• 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!

TFS 1.X+ Bug with respaw (appears 2, 3 demons if player lure)

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,188
Solutions
34
Reaction score
200
Hi, I'm using tfs 1.3 for 8.6 and found a bug.
Monsters can walk up to 25 sqm (deSpawnRadius) before being teleported back to their spawn.
If a player lures the behemoth for about 20 sqm (number 1 to 2) what happens is that another behemoth is born in the respawn position (number 1).
And if the player finishes lurking for another 25 sqm, the behemoth will be teleported to the respaw position (numer 1), and now here are 2 behemoth in stacks on the start spawn, how can i solve it?
I see up to 3 behemoth stack is possible
obs: happens with all monsters, I used behemoth just for example

1570038124429.png

Here a link of a spawn.cpp in github
spawn.cpp
 
Last edited:
It looks like programmed behaviour.

I'll quote here some code from spawn.cpp (https://github.com/otland/forgottenserver/blob/master/src/spawn.cpp):

loadFromXml() tries to load radius for each spawn, if not defined then -1 is set.
otland/forgottenserver (https://github.com/otland/forgottenserver/blob/master/src/spawn.cpp#L59)
C++:
int32_t radius;
pugi::xml_attribute radiusAttribute = spawnNode.attribute("radius");
if (radiusAttribute) {
    radius = pugi::cast<int32_t>(radiusAttribute.value());
} else {
    radius = -1;
}

During spawnCheck(), cleanup() method is executed and if monster is alive
and went out of its spawn (spawn radius matters, not antiLureRadius) then in spawnedMap
the monster is detached from its spawn (now it is attached to spawn of id = 0) and
server thinks that there is no monster spawned yet in this spawn (so it is going to be respawn soon).
C++:
void Spawn::checkSpawn()
{
    checkSpawnEvent = 0;

    cleanup();
    // the rest of checkSpawn method [ ... ]
}

void Spawn::cleanup()
{
    // [...]
        } else if (!isInSpawnZone(monster->getPosition()) && spawnId != 0) {
            spawnedMap.insert(spawned_pair(0, monster));
            it = spawnedMap.erase(it);
        }
    // [...]
}

One important thing is that isInZone() method think that the monster is in spawn
if spawnRadius is set to -1.
C++:
bool Spawn::isInSpawnZone(const Position& pos)
{
    return Spawns::isInZone(centerPos, radius, pos);
}

bool Spawns::isInZone(const Position& centerPos, int32_t radius, const Position& pos)
{
    if (radius == -1) {
        return true;
    }

    return ((pos.getX() >= centerPos.getX() - radius) && (pos.getX() <= centerPos.getX() + radius) &&
            (pos.getY() >= centerPos.getY() - radius) && (pos.getY() <= centerPos.getY() + radius));
}

I am not sure what is the idea behind this feature, but probably removing following lines in void Spawn::cleanup() method
(see otland/forgottenserver (https://github.com/otland/forgottenserver/blob/master/src/spawn.cpp#L278)) should help:
C++:
        } else if (!isInSpawnZone(monster->getPosition()) && spawnId != 0) {
            spawnedMap.insert(spawned_pair(0, monster));
            it = spawnedMap.erase(it);
        }


Be aware that if antilure is off for some reason and monster will go far away from its spawn then it will not respawn until someone kills it.
 
if you dont want to compile you can just set spawn point larger in RME (like radius 15~)

if monster leaves it's spawn for atleast 60sec it will respawn again and this allows to respawn even 1000 demons instead of just 1 if you will lure them one by one from thier little 3x3 spawns

1575299953327.png
 
Back
Top