Item* Creature::dropCorpse() { Item* splash = NULL; if(getRace() == RACE_VENOM) splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_SLIME); else if(getRace() == RACE_BLOOD) splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD); Tile* tile = getParentTile(); if(splash){ if(g_game.internalAddItem(NULL, tile, splash, INDEX_WHEREEVER, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE) == RET_NOERROR){ g_game.startDecay(splash); } else{ g_game.FreeThing(splash); } } Item* corpse = createCorpse(); if(corpse){ if(g_game.internalAddItem(NULL, tile, corpse, INDEX_WHEREEVER, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE) == RET_NOERROR){ dropLoot(corpse->getContainer()); g_game.startDecay(corpse); return corpse; } else{ g_game.FreeThing(corpse); } } return NULL; }
void House::resetTransferItem() { if(transferItem){ Item* tmpItem = transferItem; transferItem = NULL; transfer_container.setParent(NULL); transfer_container.__removeThing(tmpItem, tmpItem->getItemCount()); g_game.FreeThing(tmpItem); } }
void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link /*= LINK_OWNER*/) { const Position& cylinderMapPos = getPosition(); SpectatorVec list; g_game.getSpectators(list, cylinderMapPos, true, true); for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) { (*it)->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR); } //add a reference to this item, it may be deleted after being added (mailbox for example) thing->useThing2(); if (link == LINK_OWNER) { //calling movement scripts Creature* creature = thing->getCreature(); if (creature) { g_moveEvents->onCreatureMove(creature, this, true); } else { Item* item = thing->getItem(); if (item) { g_moveEvents->onItemMove(item, this, true); } } if (hasFlag(TILESTATE_TELEPORT)) { Teleport* teleport = getTeleportItem(); if (teleport) { teleport->__addThing(thing); } } else if (hasFlag(TILESTATE_TRASHHOLDER)) { TrashHolder* trashholder = getTrashHolder(); if (trashholder) { trashholder->__addThing(thing); } } else if (hasFlag(TILESTATE_MAILBOX)) { Mailbox* mailbox = getMailbox(); if (mailbox) { mailbox->__addThing(thing); } } } //release the reference to this item onces we are finished g_game.FreeThing(thing); }
Spawn::~Spawn() { stopEvent(); Monster* monster = NULL; for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end(); ++it) { if(!(monster = it->second)) continue; monster->setSpawn(NULL); if(!monster->isRemoved()) g_game.FreeThing(monster); } spawnedMap.clear(); spawnMap.clear(); }
void Tile::__addThing(int32_t index, Thing* thing) { Creature* creature = thing->getCreature(); if (creature) { g_game.clearSpectatorCache(); creature->setParent(this); CreatureVector* creatures = makeCreatures(); creatures->insert(creatures->begin(), creature); ++thingCount; } else { Item* item = thing->getItem(); if (!item) { #ifdef __DEBUG__MOVESYS__ std::cout << "Failure: [Tile::__addThing] item == NULL" << std::endl; DEBUG_REPORT #endif return /*RET_NOTPOSSIBLE*/; } TileItemVector* items = getItemList(); if (items && items->size() > 0xFFFF) { return /*RET_NOTPOSSIBLE*/; } item->setParent(this); if (item->isGroundTile()) { if (!ground) { ground = item; ++thingCount; onAddTileItem(item); } else { const ItemType& oldType = Item::items[ground->getID()]; const ItemType& newType = Item::items[item->getID()]; int32_t oldGroundIndex = __getIndexOfThing(ground); Item* oldGround = ground; ground->setParent(NULL); g_game.FreeThing(ground); ground = item; updateTileFlags(oldGround, true); updateTileFlags(item, false); onUpdateTileItem(oldGround, oldType, item, newType); postRemoveNotification(oldGround, NULL, oldGroundIndex, true); } } else if (item->isAlwaysOnTop()) { if (item->isSplash()) { //remove old splash if exists if (items) { for (ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { if ((*it)->isSplash()) { int32_t oldSplashIndex = __getIndexOfThing(*it); Item* oldSplash = *it; __removeThing(oldSplash, 1); oldSplash->setParent(NULL); g_game.FreeThing(oldSplash); postRemoveNotification(oldSplash, NULL, oldSplashIndex, true); break; } } } } bool isInserted = false; if (items) { for (ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it) { //Note: this is different from internalAddThing if (Item::items[item->getID()].alwaysOnTopOrder <= Item::items[(*it)->getID()].alwaysOnTopOrder) { items->insert(it, item); ++thingCount; isInserted = true; break; } } } else { items = makeItemList(); } if (!isInserted) { items->push_back(item); ++thingCount; } onAddTileItem(item); } else { if (item->isMagicField()) { //remove old field item if exists if (items) { MagicField* oldField = NULL; for (ItemVector::iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it) { if ((oldField = (*it)->getMagicField())) { if (oldField->isReplaceable()) { int32_t oldFieldIndex = __getIndexOfThing(*it); __removeThing(oldField, 1); oldField->setParent(NULL); g_game.FreeThing(oldField); postRemoveNotification(oldField, NULL, oldFieldIndex, true); break; } else { //This magic field cannot be replaced. item->setParent(NULL); g_game.FreeThing(item); return; } } } } } items = makeItemList(); items->insert(items->getBeginDownItem(), item); ++items->downItemCount; ++thingCount; onAddTileItem(item); } }
void Tile::__addThing(int32_t index, Thing* thing) { Creature* creature = thing->getCreature(); if(creature){ creature->setParent(this); creatures.insert(creatures.begin(), creature); } else{ Item* item = thing->getItem(); if(item == NULL){ #ifdef __DEBUG__MOVESYS__ std::cout << "Failure: [Tile::__addThing] item == NULL" << std::endl; int *a = NULL; *a = 1; #endif return /*RET_NOTPOSSIBLE*/; } item->setParent(this); if(item->isGroundTile()){ if(ground == NULL){ onAddTileItem(item); } else{ uint32_t index = __getIndexOfThing(ground); onUpdateTileItem(index, ground, item); ground->setParent(NULL); g_game.FreeThing(ground); ground = NULL; } ground = item; } else if(item->isAlwaysOnTop()){ if(item->isSplash()){ //remove old splash if exists ItemVector::iterator iit; for(iit = topItems.begin(); iit != topItems.end(); ++iit){ if((*iit)->isSplash()){ Item* oldSplash = *iit; __removeThing(oldSplash, 1); oldSplash->setParent(NULL); g_game.FreeThing(oldSplash); break; } } } bool isInserted = false; ItemVector::iterator iit; for(iit = topItems.begin(); iit != topItems.end(); ++iit){ //Note: this is different from internalAddThing if(Item::items[item->getID()].alwaysOnTopOrder <= Item::items[(*iit)->getID()].alwaysOnTopOrder){ topItems.insert(iit, item); isInserted = true; break; } } if(!isInserted){ topItems.push_back(item); } onAddTileItem(item); } else{ if(item->isMagicField()){ //remove old field item if exists ItemVector::iterator iit; for(iit = downItems.begin(); iit != downItems.end(); ++iit){ if((*iit)->isMagicField()){ Item* oldField = *iit; __removeThing(oldField, 1); oldField->setParent(NULL); g_game.FreeThing(oldField); break; } } } downItems.insert(downItems.begin(), item); onAddTileItem(item); } } }