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; }
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; }
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); }
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 MediumPlane::updateExplotionAnimation() { m_explotionRemainingTime -= GameTimeHelper::Instance()->deltaTime(); int step = m_explotionAnimationTime / m_numFrames; int lastFrame = m_currentFrame; int lastRow = m_currentRow; m_currentFrame = ((m_explotionAnimationTime - m_explotionRemainingTime) / step) % 4; m_currentRow = ((m_explotionAnimationTime - m_explotionRemainingTime) / step) / 4; if (m_explotionRemainingTime <= 0) { m_dying = false; m_dead = true; m_exploting = false; dropLoot(); } if ((lastFrame != m_currentFrame) || (lastRow != m_currentRow)) { m_dirty = true; } }
void NounShip::destroyShip( Noun * pKiller, bool bZeroVelocity ) { // make sure the damage is enough m_Damage = maxDamage(); // clear the current order & command, so if they respawn the ship doesn't try to keep doing it's last command setCommand( NOCOMMAND, NULL ); setOrder( NOORDER, NULL, NULL ); // inform the context user first if ( pKiller != this ) { gameContext()->gameUser()->onDestroyed( this, pKiller ); if ( pKiller != NULL ) gameContext()->gameUser()->onKill( pKiller, this ); } else gameContext()->gameUser()->onSelfDestruct( this ); if ( WidgetCast<NounPlanet>( pKiller ) ) gameContext()->gameUser()->onCollidePlanet( this ); // create the primary explosion if ( context()->isClient() ) { Scene * pScene = destroyEffect(); if ( pScene != NULL ) { // TODO: no need to add this explosion of this player is nowhere near the explosion // ship destroyed, create the explosion effect SceneryDebris * pEffect = new SceneryDebris; pEffect->setNounContext( new NounContext( pScene ) ); pEffect->setContext( context() ); pEffect->setPosition( worldPosition() ); pEffect->setDelay( 0.0f ); pEffect->setFrame( frame() ); if (! bZeroVelocity ) pEffect->setVelocity( Vector3( sin( m_fHeading ) * m_fVelocity, 0.0f, cos( m_fHeading) * m_fVelocity ) ); if (! pEffect->setSegment( "Effect" ) ) pEffect->setLife( 15.0f ); context()->attachNoun( pEffect ); } NounTrail::CopyTrailsIntoZone( this ); } // list of destroyed items to remove from ship.. std::list< Noun * > destroyed; // damage enhancements, once they reach their maxDamage() they are destroyed.. for(int i=0;i<childCount();++i) { NounEnhancement * pEnh = WidgetCast<NounEnhancement>( child(i) ); if ( pEnh != NULL ) { if ( pEnh->incrementDamage() ) { LOG_STATUS( "NounShip", "[ENHANCEMENT]:Destroyed:%s:%s:%u", pEnh->getName(), name(), userId() ); message( CharString().format( "<color;ffffff>Comms: Enhancement '%s' destroyed!", pEnh->getName() ) ); destroyed.push_back( pEnh ); } continue; } // remove any beacons on death.. NounBeacon * pBeacon = WidgetCast<NounBeacon>( child(i) ); if ( pBeacon != NULL ) { destroyed.push_back( pBeacon ); continue; } } // server-side only logic if ( isServer() ) { // check for area damage Array< GameContext::NounCollision > collide; if ( context()->proximityCheck( worldPosition(), explodeArea(), collide ) ) { for(int i=0;i<collide.size();i++) { NounGame * pCollide = WidgetCast<NounGame>( collide[i].pNoun ); if ( !pCollide || pCollide == this ) continue; if ( pCollide->canDamage( DAMAGE_ENERGY | DAMAGE_KINETIC ) && collide[i].fDistance < explodeArea() ) { float damageRatio = 1.0f - (collide[i].fDistance / explodeArea()); int damage = damageRatio * explodeDamage(); if ( damage > 0 ) { pCollide->inflictDamage( tick(), this, damage, DAMAGE_ENERGY | DAMAGE_KINETIC, pCollide->worldFrame() * (worldPosition() - pCollide->worldPosition()) ); } } } } // drop enhancements after we do area damage, otherwise we'll destroy the dropped loot.. dropLoot(); // space-monsters do not leave behind devices if ( ! isMonster() ) { // eject some of the resources used to build the ship into space int nAmount = DESTROYED_SHIP_RESOURCE * buildCost( this ); while( nAmount > 0 ) { CargoResource::Ref pCargo = new CargoResource( nAmount ); nAmount -= pCargo->quantity(); Vector3 vPosition( worldPosition() + RandomVector( -radius(), radius() ) ); vPosition.y = 0.0f; pCargo->setPosition( vPosition ); context()->attachNoun( pCargo ); } //// check for any cargo items... if found put them into space //for(int i=0;i<childCount();i++) //{ // BaseNode * pChild = child(i); // NounCargo::Ref pCargo; // if ( WidgetCast<NounCargo>( pChild ) ) // { // int roll = rand() % 100; // if ( roll < ((NounCargo *)pChild)->durability() ) // pCargo = (NounCargo *)pChild->copy(); // } // if ( pCargo.valid() ) // { // Vector3 vPosition( worldPosition() + RandomVector( -5.0f, 5.0f ) ); // vPosition.y = 0.0f; // pCargo->setPosition( vPosition ); // context()->attachNoun( pCargo ); // } //} } // last before detach so that players dont dupe thier enhancements // that were dropped // save off storage with this "active" ship if(userId() != 0) context()->user()->saveStorage(this); } // remove desrtroyed items from ship.. while( destroyed.size() > 0 ) { Noun * pDestroyed = destroyed.front(); destroyed.pop_front(); if ( pDestroyed ) pDestroyed->detachSelf(); } // lastly, detach the ship from the universe setDetach(); }
void Enemy::onRemove() { Game::playSound("dead",shared_from_this()); spawnGrave(); dropLoot(); light->remove(); }