Beispiel #1
0
bool Creature::dropCorpse()
{
	if (!lootDrop && getMonster() && !(master && master->getPlayer())) {
		if (master) {
			//scripting event - onDeath
			CreatureEventList deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);

			for (CreatureEventList::const_iterator it = deathEvents.begin(); it != deathEvents.end(); ++it) {
				(*it)->executeOnDeath(this, NULL, _lastHitCreature, _mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
			}
		}

		g_game.addMagicEffect(getPosition(), NM_ME_POFF);
	} else {
		Item* splash = NULL;

		switch (getRace()) {
			case RACE_VENOM:
				splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_GREEN);
				break;

			case RACE_BLOOD:
				splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
				break;

			default:
				break;
		}

		Tile* tile = getTile();

		if (splash) {
			g_game.internalAddItem(tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
			g_game.startDecay(splash);
		}

		Item* corpse = getCorpse();

		if (corpse) {
			g_game.internalAddItem(tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
			g_game.startDecay(corpse);
		}

		//scripting event - onDeath
		CreatureEventList deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);

		for (CreatureEventList::const_iterator it = deathEvents.begin(); it != deathEvents.end(); ++it) {
			(*it)->executeOnDeath(this, corpse, _lastHitCreature, _mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
		}

		if (corpse) {
			dropLoot(corpse->getContainer());
		}
	}

	return true;
}
Beispiel #2
0
bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
	if (!lootDrop && getMonster()) {
		if (master) {
			//scripting event - onDeath
			const CreatureEventList& deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);
			for (CreatureEvent* deathEvent : deathEvents) {
				deathEvent->executeOnDeath(this, nullptr, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
			}
		}

		g_game.addMagicEffect(getPosition(), CONST_ME_POFF);
	} else {
		Item* splash;
		switch (getRace()) {
			case RACE_VENOM:
				splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_GREEN);
				break;

			case RACE_BLOOD:
				splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
				break;

			default:
				splash = nullptr;
				break;
		}

		Tile* tile = getTile();

		if (splash) {
			g_game.internalAddItem(tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
			g_game.startDecay(splash);
		}

		Item* corpse = getCorpse(lastHitCreature, mostDamageCreature);
		if (corpse) {
			g_game.internalAddItem(tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
			g_game.startDecay(corpse);
		}

		//scripting event - onDeath
		for (CreatureEvent* deathEvent : getCreatureEvents(CREATURE_EVENT_DEATH)) {
			deathEvent->executeOnDeath(this, corpse, lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
		}

		if (corpse) {
			dropLoot(corpse->getContainer(), lastHitCreature);
		}
	}

	return true;
}
Beispiel #3
0
void Creature::dropCorpse(DeathList deathList)
{
	if(master && !g_config.getBool(ConfigManager::SUMMONS_DROP_CORPSE))
	{
		g_game.addMagicEffect(getPosition(), MAGIC_EFFECT_POFF);
		return;
	}

	Item* corpse = createCorpse(deathList);
	if(corpse)
		corpse->setParent(VirtualCylinder::virtualCylinder);

	bool deny = false;
	CreatureEventList deathEvents = getCreatureEvents(CREATURE_EVENT_DEATH);
	for(CreatureEventList::iterator it = deathEvents.begin(); it != deathEvents.end(); ++it)
	{
		if(!(*it)->executeDeath(this, corpse, deathList) && !deny)
			deny = true;
	}

	if(!corpse)
		return;

	corpse->setParent(NULL);
	if(deny)
		return;

	Tile* tile = getTile();
	if(!tile)
		return;

	Item* splash = NULL;
	switch(getRace())
	{
		case RACE_VENOM:
			splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_GREEN);
			break;

		case RACE_BLOOD:
			splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);
			break;

		default:
			break;
	}

	if(splash)
	{
		g_game.internalAddItem(NULL, tile, splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
		g_game.startDecay(splash);
	}

	g_game.internalAddItem(NULL, tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
	dropLoot(corpse->getContainer());
	g_game.startDecay(corpse);
}
Beispiel #4
0
void Creature::onCreatureDisappear(const Creature* creature, bool isLogout)
{
	internalCreatureDisappear(creature, true);
	if(creature != this && isMapLoaded && creature->getPosition().z == getPosition().z)
	{
		updateTileCache(creature->getTile(), creature->getPosition());
        CreatureEventList disappearEvents = getCreatureEvents(CREATURE_EVENT_DISAPPEAR);
        for(CreatureEventList::iterator it = disappearEvents.begin(); it != disappearEvents.end(); ++it)
        	(*it)->executeDisappear(this, creature);
    }
}
bool Creature::onKilledCreature(Creature* target, bool lastHit/* = true*/)
{
	if (getMaster()) {
		getMaster()->onKilledCreature(target);
	}

	//scripting event - onKill
	const CreatureEventList& killEvents = getCreatureEvents(CREATURE_EVENT_KILL);
	for (CreatureEvent* killEvent : killEvents) {
		killEvent->executeOnKill(this, target);
	}
	return false;
}
Beispiel #6
0
bool Creature::onKilledCreature(Creature* target, bool)
{
	if (master) {
		master->onKilledCreature(target);
	}

	//scripting event - onKill
	const CreatureEventList& killEvents = getCreatureEvents(CREATURE_EVENT_KILL);
	for (CreatureEvent* killEvent : killEvents) {
		killEvent->executeOnKill(this, target);
	}
	return false;
}
Beispiel #7
0
void Creature::onThink(uint32_t interval)
{
	if(!isMapLoaded && useCacheMap())
	{
		isMapLoaded = true;
		updateMapCache();
	}

	if(followCreature && master != followCreature && !canSeeCreature(followCreature))
		internalCreatureDisappear(followCreature, false);

	if(attackedCreature && master != attackedCreature && !canSeeCreature(attackedCreature))
		internalCreatureDisappear(attackedCreature, false);

	blockTicks += interval;
	if(blockTicks >= 1000)
	{
		blockCount = std::min((uint32_t)blockCount + 1, (uint32_t)2);
		blockTicks = 0;
	}

	if(followCreature)
	{
		walkUpdateTicks += interval;
		if(forceUpdateFollowPath || walkUpdateTicks >= 2000)
		{
			walkUpdateTicks = 0;
			forceUpdateFollowPath = false;
			isUpdatingPath = true;
		}
	}

	if(isUpdatingPath)
	{
		isUpdatingPath = false;
		goToFollowCreature();
	}

#ifndef __GROUPED_ATTACKS__
	onAttacking(interval / EVENT_CREATURECOUNT);
#else
	onAttacking(interval);
#endif
	executeConditions(interval);

	CreatureEventList thinkEvents = getCreatureEvents(CREATURE_EVENT_THINK);
	for(CreatureEventList::iterator it = thinkEvents.begin(); it != thinkEvents.end(); ++it)
		(*it)->executeThink(this, interval);
}
Beispiel #8
0
bool Creature::onKilledCreature(Creature* target, bool lastHit/* = true*/)
{
	if (getMaster()) {
		getMaster()->onKilledCreature(target);
	}

	//scripting event - onKill
	CreatureEventList killEvents = getCreatureEvents(CREATURE_EVENT_KILL);

	for (CreatureEventList::const_iterator it = killEvents.begin(), end = killEvents.end(); it != end; ++it) {
		(*it)->executeOnKill(this, target);
	}

	return false;
}
Beispiel #9
0
void Creature::onCreatureAppear(const Creature* creature)
{
	if(creature == this)
	{
		if(useCacheMap())
		{
			isMapLoaded = true;
			updateMapCache();
		}
	}
	else if(isMapLoaded && creature->getPosition().z == getPosition().z)
    {
		updateTileCache(creature->getTile(), creature->getPosition());
        CreatureEventList disappearEvents = getCreatureEvents(CREATURE_EVENT_APPEAR);
        for(CreatureEventList::iterator it = disappearEvents.begin(); it != disappearEvents.end(); ++it)
        	(*it)->executeDisappear(this, creature);
    }
}
Beispiel #10
0
void Creature::onThink(uint32_t interval)
{
	if (!isMapLoaded && useCacheMap()) {
		isMapLoaded = true;
		updateMapCache();
	}

	if (followCreature && getMaster() != followCreature && !canSeeCreature(followCreature)) {
		onCreatureDisappear(followCreature, false);
	}

	if (attackedCreature && getMaster() != attackedCreature && !canSeeCreature(attackedCreature)) {
		onCreatureDisappear(attackedCreature, false);
	}

	blockTicks += interval;

	if (blockTicks >= 1000) {
		blockCount = std::min<uint32_t>(blockCount + 1, 2);
		blockTicks = 0;
	}

	if (followCreature) {
		walkUpdateTicks += interval;

		if (forceUpdateFollowPath || walkUpdateTicks >= 2000) {
			walkUpdateTicks = 0;
			forceUpdateFollowPath = false;
			isUpdatingPath = true;
		}
	}

	if (isUpdatingPath) {
		isUpdatingPath = false;
		goToFollowCreature();
	}

	//scripting event - onThink
	CreatureEventList thinkEvents = getCreatureEvents(CREATURE_EVENT_THINK);

	for (CreatureEventList::const_iterator it = thinkEvents.begin(), end = thinkEvents.end(); it != end; ++it) {
		(*it)->executeOnThink(this, interval);
	}
}
Beispiel #11
0
bool Creature::onKilledCreature(Creature* target, DeathEntry& entry)
{
	bool ret = true;
	if(master)
		ret = master->onKilledCreature(target, entry);

	CreatureEventList killEvents = getCreatureEvents(CREATURE_EVENT_KILL);
	if(!entry.isLast())
	{
		for(CreatureEventList::iterator it = killEvents.begin(); it != killEvents.end(); ++it)
			(*it)->executeKill(this, target, entry);

		return true;
	}

	for(CreatureEventList::iterator it = killEvents.begin(); it != killEvents.end(); ++it)
	{
		if(!(*it)->executeKill(this, target, entry) && ret)
			ret = false;
	}

	return ret;
}
Beispiel #12
0
void Monster::onCreatureAppear(const Creature* creature)
{
	Creature::onCreatureAppear(creature);
	if(creature == this)
	{
		//We just spawned lets look around to see who is there.
		if(isSummon())
			isMasterInRange = canSee(getMaster()->getPosition());
			
			 setStorage(510, mType->realName); // sistema de shiny nomes 2.0
			
			CreatureEventList spawn = getCreatureEvents(CREATURE_EVENT_SPAWN);
			for(CreatureEventList::iterator it = spawn.begin(); it != spawn.end(); ++it)

			(*it)->executeOnSpawn(this);
			

		updateTargetList();
		updateIdleStatus();
	}
	else
		onCreatureEnter(const_cast<Creature*>(creature));
}
Beispiel #13
0
bool Creature::onKilledCreature(Creature* target, uint32_t& flags, DeathEntry& entry)
{
	bool ret = true;
	if(master)
		ret = master->onKilledCreature(target, flags, entry);

	CreatureEventList killEvents = getCreatureEvents(CREATURE_EVENT_KILL);
	if(!hasBitSet((uint32_t)KILLFLAG_LASTHIT, flags))
	{
		for(CreatureEventList::iterator it = killEvents.begin(); it != killEvents.end(); ++it)
			(*it)->executeKill(this, target, false);

		return true;
	}

	for(CreatureEventList::iterator it = killEvents.begin(); it != killEvents.end(); ++it)
	{
		if(!(*it)->executeKill(this, target, true) && ret)
			ret = false;
	}

	return ret;
}
Beispiel #14
0
void Creature::onAttacking(uint32_t interval)
{
	if(!attackedCreature || attackedCreature->getHealth() < 1 || interval < 100)
		return;

	bool deny = false;
	CreatureEventList attackEvents = getCreatureEvents(CREATURE_EVENT_ATTACK);
	for(CreatureEventList::iterator it = attackEvents.begin(); it != attackEvents.end(); ++it)
	{
		if(!(*it)->executeAction(this, attackedCreature) && !deny)
			deny = true;
	}

	if(deny)
		setAttackedCreature(NULL);

	if(!attackedCreature)
		return;

	onAttacked();
	attackedCreature->onAttacked();
	if(g_game.isSightClear(getPosition(), attackedCreature->getPosition(), true))
		doAttacking(interval);
}
Beispiel #15
0
bool Creature::onDeath()
{
	DeathList deathList = getKillers();
	bool deny = false;

	CreatureEventList prepareDeathEvents = getCreatureEvents(CREATURE_EVENT_PREPAREDEATH);
	for(CreatureEventList::iterator it = prepareDeathEvents.begin(); it != prepareDeathEvents.end(); ++it)
	{
		if(!(*it)->executePrepareDeath(this, deathList) && !deny)
			deny = true;
	}

	if(deny)
		return false;

	int32_t i = 0, size = deathList.size(), limit = g_config.getNumber(ConfigManager::DEATH_ASSISTS) + 1;
	if(limit > 0 && size > limit)
		size = limit;

	Creature* tmp = NULL;
	CreatureVector justifyVec;
	for(DeathList::iterator it = deathList.begin(); it != deathList.end(); ++it, ++i)
	{
		if(it->isNameKill())
			continue;

		if(it == deathList.begin())
			it->setLast();

		if(i < size)
		{
			if(it->getKillerCreature()->getPlayer())
				tmp = it->getKillerCreature();
			else if(it->getKillerCreature()->getPlayerMaster())
				tmp = it->getKillerCreature()->getMaster();
		}

		if(tmp)
		{
			if(std::find(justifyVec.begin(), justifyVec.end(), tmp) == justifyVec.end())
			{
				it->setJustify();
				justifyVec.push_back(tmp);
			}

			tmp = NULL;
		}

		if(!it->getKillerCreature()->onKilledCreature(this, (*it)) && it->isLast())
			return false;
	}

	for(CountMap::iterator it = damageMap.begin(); it != damageMap.end(); ++it)
	{
		if((tmp = g_game.getCreatureByID(it->first)))
			tmp->onTargetKilled(this);
	}

	dropCorpse(deathList);
	if(master)
		master->removeSummon(this);

	return true;
}