• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Monster ViewRange configured in monster.xml files

Flatlander

Species Developer
Joined
Feb 17, 2009
Messages
2,461
Solutions
3
Reaction score
1,355
Location
Texas
Here is my tutorial adding monster ViewRange.

This is how far a Monster can "see" you and start chasing you. (Not to be confused with Target Range, which is the distance a monster stands to attack you)

I HIGHLY suggest following my Pathfinding tutorial if you plan to have monsters follow players over 15 tiles away. You can locate this tutorial here:
Optimizing TFS Pathfinding

Now onto the ViewRange Source Edits:

In monsters.h add the following line:
Code:
       LightInfo light = {};
       uint16_t lookcorpse = 0;

       uint64_t experience = 0;
       
       int32_t viewRange = 11; // Add this line, 11 is the Default viewRange for monsters in this case
       uint32_t manaCost = 0;

in monsters.cpp add the following 2 lines:
Code:
           } else if (strcasecmp(attrName, "runonhealth") == 0) {
               mType->info.runAwayHealth = pugi::cast<int32_t>(attr.value());
           } else if (strcasecmp(attrName, "viewRange") == 0) { //Add this line to find the flag viewRange
               mType->info.viewRange = pugi::cast<int32_t>(attr.value()); //This line sets the value

Now that we have the value, we have to basically update the ViewRange in certain areas of TFS (Hope 1.X isn't much different than 0.X here)

In creature.cpp you will need to edit canSee: (I do this using Storage Values on 0.X, but i'm going to use mType here since I do not know if monsters can have storage values in 1.X)

Creature.cpp add:
Code:
extern Game g_game;
extern Monsters g_monsters; //Add this so we can get the mType
Creature.cpp change:
Code:
bool Creature::canSee(const Position& pos) const
{
   return canSee(getPosition(), pos, Map::maxViewportX, Map::maxViewportY);
}
We must change creatures to use the new viewRange (but not break other creaturetypes)
Code:
bool Creature::canSee(const Position& pos) const
{
   int viewX = Map::maxViewportX
   int viewY = Map::maxViewportY
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mtype) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return canSee(getPosition(), pos, viewX, viewY);
}


I THINK that is all the changes that are required. If it doesn't work, let me know.

Disclaimer:
I am self-taught, the way I do things most likely is terrible an inefficient and I also do not use TFS 1.X.

Feel free to give pointers, and provide optimizations and I'll gladly update the tutorial so everyone has a better time.
 
Hello,

Have you tested the code ? I see there is targetList in monster.cpp which is used for selecting target. This list is updated with onCreatureAppear function which I think is based on default view ranges.

I think your code may work only if the monster is already chasing you, it does not extend the view range for selecting new targets. But anyway its good point to start with :)
 
I have this code working on my server, which has literally thousands of edits, if you find something is missing you'll have to let me know and i'll update the tutorial.
 
After doing some testings i got this conclusions:

There are small erros for compiling:
C++:
bool Creature::canSee(const Position& pos) const
{
   int viewX = Map::maxViewportX
   int viewY = Map::maxViewportY
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mtype) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return canSee(getPosition(), pos, viewX, viewY);
}
must be like this:
C++:
bool Creature::canSee(const Position& pos) const
{
   int viewX = Map::maxViewportX;
   int viewY = Map::maxViewportY;
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mType) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return canSee(getPosition(), pos, viewX, viewY);
}

Also, after compiling with 0 errors, i've added this to random monsters:
Lua:
<flag viewRange="50"/>
Tested flag as "viewRange" and "viewrange".
Monster is not affected at all. Tested viewRange with different values.
If the monster did not have target, monsters viewRange is not affected.
If the monster had you in range and you run fast from its range, monster still not affected.

Conclusions:
-the monster cant get target from that viewRange.
-the monster loses target and doesnt follow for the viewRange.

Fixes?
 
im using OTX 3 (based in tfs 1.3) and to work i need to make more changes in

monster.cpp

this
C++:
bool Monster::canSee(const Position& pos) const
{
    return Creature::canSee(getPosition(), pos, 9, 9);
}
for
C++:
bool Monster::canSee(const Position& pos) const
{
    int viewX = Map::maxViewportX;
    int viewY = Map::maxViewportY;
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mType) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return Creature::canSee(getPosition(), pos, viewX, viewY);
}

work fine after thats changes
 
Last edited:
Here is my tutorial adding monster ViewRange.

This is how far a Monster can "see" you and start chasing you. (Not to be confused with Target Range, which is the distance a monster stands to attack you)

I HIGHLY suggest following my Pathfinding tutorial if you plan to have monsters follow players over 15 tiles away. You can locate this tutorial here:
Optimizing TFS Pathfinding

Now onto the ViewRange Source Edits:

In monsters.h add the following line:
Code:
       LightInfo light = {};
       uint16_t lookcorpse = 0;

       uint64_t experience = 0;
      
       int32_t viewRange = 11; // Add this line, 11 is the Default viewRange for monsters in this case
       uint32_t manaCost = 0;

in monsters.cpp add the following 2 lines:
Code:
           } else if (strcasecmp(attrName, "runonhealth") == 0) {
               mType->info.runAwayHealth = pugi::cast<int32_t>(attr.value());
           } else if (strcasecmp(attrName, "viewRange") == 0) { //Add this line to find the flag viewRange
               mType->info.viewRange = pugi::cast<int32_t>(attr.value()); //This line sets the value

Now that we have the value, we have to basically update the ViewRange in certain areas of TFS (Hope 1.X isn't much different than 0.X here)

In creature.cpp you will need to edit canSee: (I do this using Storage Values on 0.X, but i'm going to use mType here since I do not know if monsters can have storage values in 1.X)

Creature.cpp add:
Code:
extern Game g_game;
extern Monsters g_monsters; //Add this so we can get the mType
Creature.cpp change:
Code:
bool Creature::canSee(const Position& pos) const
{
   return canSee(getPosition(), pos, Map::maxViewportX, Map::maxViewportY);
}
We must change creatures to use the new viewRange (but not break other creaturetypes)
Code:
bool Creature::canSee(const Position& pos) const
{
   int viewX = Map::maxViewportX
   int viewY = Map::maxViewportY
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mtype) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return canSee(getPosition(), pos, viewX, viewY);
}


I THINK that is all the changes that are required. If it doesn't work, let me know.

Disclaimer:
I am self-taught, the way I do things most likely is terrible an inefficient and I also do not use TFS 1.X.

Feel free to give pointers, and provide optimizations and I'll gladly update the tutorial so everyone has a better time.
could you make a code to make monster gain skills?
 
If you do not like monsters staying and doing nothing in your viewrange, then You can adopt my changes: canSee and canTarget as separate functions:
 

Attachments

TFS 1.3, monsters get stuck if you increase their viewRange above 11, do you guys know why and how to fix it?
 
Really neat idea, I was not able to get it working on TFS 1.4 though.. kind of a bummer, maybe something to dig into later :)

Edit: Did get it working in TFS 1.4 by editing monster.cpp as well

C++:
bool Monster::canSee(const Position& pos) const
{
    int viewX = Map::maxViewportX;
    int viewY = Map::maxViewportY;
   MonsterType* mType = g_monsters.getMonsterType(this->getName());
   if(mType) {
       viewX = mType->info.viewRange;
       viewY = mType->info.viewRange;
   }
   return Creature::canSee(getPosition(), pos, viewX, viewY);
}
 
Last edited:
Back
Top