Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 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);
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
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;
	}
}
Exemplo n.º 6
0
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();
}
Exemplo n.º 7
0
void Enemy::onRemove() {
	Game::playSound("dead",shared_from_this());
	spawnGrave();
	dropLoot();
	light->remove();
}