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

Lua Server crash when a monster kills a player

Friday13x

New Member
Joined
Apr 5, 2010
Messages
12
Reaction score
0
Hello, I don't understand exactly why, but this creature script does not work on TFS 0.2.14 (Mystic Spirit).
Code:
position = {x=100, y=100, z=1}
function onPrepareDeath(cid, killer)
	if isPlayer(cid) then
		doRemoveCondition(cid, CONDITION_INFIGHT)
		doTeleportThing(cid, position)
		local add = (getCreatureMaxHealth(cid)-getCreatureHealth(cid))
		doCreatureAddHealth(cid, add)
		local addmp = (getPlayerMaxMana(cid)-getPlayerMana(cid))
		doPlayerAddMana(cid, addmp)
		doCreatureSetSkullType(cid, 0)
		doSendMagicEffect(position,CONST_ME_FIREWORK_RED)
		return false
	else
		return true
	end
end
It does not matter if I run it with the check of "has-hp-less-than-0".

The problem is, when a monster kills me, I get an instant server crash. Tried a situation that when a player kill me - result was positive, worked like a charm.
After all testings and tries, I have run server in debug mode. The last messages were:

HTML:
Searching target...
Selecting target...
Selecting target...
Selecting target...
Selecting target...
Selecting target...
Selecting target...
Creature::updateTileCache out of range.
Attacked creature disappeared.
Follow creature disappeared.
Selecting target...
Selecting target...
Selecting target...
<and then crash>
So I assume, that there's a problem in monster.cpp -> Monster::searchTarget function. It's trying to select the target that got teleported to other position.
I'm not very experienced with C++, so any help would be appreciated.
Adding Monster::searchTarget in monster.cpp:
Code:
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/)
{
#ifdef __DEBUG__
	std::cout << "Searching target... " << std::endl;
#endif

	std::list<Creature*> resultList;
	const Position& myPos = getPosition();
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature != (*it) && isTarget(*it))
		{
			if(searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, *it))
				resultList.push_back(*it);
		}
	}

	switch(searchType)
	{
		case TARGETSEARCH_NEAREAST:
		{
			Creature* target = NULL;
			int32_t minRange = -1;
			for(std::list<Creature*>::iterator it = resultList.begin(); it != resultList.end(); ++it)
			{
				const Position& pos = (*it)->getPosition();
				if(minRange == -1 || std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y)) < minRange)
				{
					target = *it;
					minRange = std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y));
				}
			}

			if(target && selectTarget(target))
				return true;

			break;
		}

		case TARGETSEARCH_DEFAULT:
		case TARGETSEARCH_ATTACKRANGE:
		case TARGETSEARCH_RANDOM:
		default:
		{
			if(!resultList.empty())
			{
				uint32_t index = random_range(0, resultList.size() - 1);
				CreatureList::iterator it = resultList.begin();
				std::advance(it, index);
#ifdef __DEBUG__
				std::cout << "Selecting target " << (*it)->getName() << std::endl;
#endif
				return selectTarget(*it);
			}

			if(searchType == TARGETSEARCH_ATTACKRANGE)
				return false;

			break;
		}
	}

	//lets just pick the first target in the list
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature != (*it) && selectTarget(*it))
		{
#ifdef __DEBUG__
			std::cout << "Selecting target " << (*it)->getName() << std::endl;
#endif
			return true;
		}
	}
	return false;
}

Best regards,
Friday13x.​
 
Did it crash before you added that script? If not, then try to do this with the script:

Lua:
local position = {x=100, y=100, z=1}
function onPrepareDeath(cid, killer)
	if isPlayer(cid) and isCreature(killer) then
		local add = (getCreatureMaxHealth(cid)-getCreatureHealth(cid))
		local addmp = (getPlayerMaxMana(cid)-getPlayerMana(cid))
		doRemoveCondition(cid, CONDITION_INFIGHT)
		doTeleportThing(cid, position)
		doCreatureAddHealth(cid, add)
		doPlayerAddMana(cid, addmp)
		doCreatureSetSkullType(cid, 0)
		doSendMagicEffect(position,CONST_ME_FIREWORK_RED)
	end
	return false
end
 
Last edited:
What happens if you "return true" instead of false?
0.2 does not deny the following steps anyway if you return false. It will just go on.
 
Back
Top