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; }
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; }
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); }
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; }
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; }
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); }
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; }
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); } }
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); } }
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; }
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)); }
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; }
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); }
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; }