void MouseUp()
    {
        if( g_app->m_location )
        {
            int myTeamId = g_app->m_globalWorld->m_myTeamId;
            for( int t = 0; t < NUM_TEAMS; ++t )
            {
                if( !g_app->m_location->IsFriend( myTeamId, t ) )
                {
                    Team *team = g_app->m_location->m_teams[t];
                    
                    // Kill all UNITS
                    for( int u = 0; u < team->m_units.Size(); ++u )
                    {
                        if( team->m_units.ValidIndex(u) )
                        {
                            Unit *unit = team->m_units[u];
                            for( int e = 0; e < unit->m_entities.Size(); ++e )
                            {
                                if( unit->m_entities.ValidIndex(e) )
                                {
                                    Entity *entity = unit->m_entities[e];
                                    entity->ChangeHealth( entity->m_stats[Entity::StatHealth] * -2.0 );
                                }
                            }
                        }
                    }

                    // Kill all ENTITIES
                    for( int o = 0; o < team->m_others.Size(); ++o )
                    {
                        if( team->m_others.ValidIndex(o) )
                        {
                            Entity *entity = team->m_others[o];
                            entity->ChangeHealth( entity->m_stats[Entity::StatHealth] * -2.0 );
                        }
                    }
                }
            }

            for( int i = 0; i < g_app->m_location->m_buildings.Size(); ++i )
            {
                if( g_app->m_location->m_buildings.ValidIndex(i) )
                {
                    Building *building = g_app->m_location->m_buildings[i];
                    if( building->m_type == Building::TypeAntHill ||
                        building->m_type == Building::TypeTriffid )
                    {
                        building->Damage( -999 );
                    }
                }
            }
        }
    }
void SoulDestroyer::Attack( Vector3 const &_pos )
{
    int numFound;
    g_app->m_location->m_entityGrid->GetEnemies( s_neighbours, _pos.x, _pos.z, SOULDESTROYER_DAMAGERANGE, &numFound, m_id.GetTeamId() );

    for( int i = 0; i < numFound; ++i )
    {
        WorldObjectId id = s_neighbours[i];
        Entity *entity = (Entity *) g_app->m_location->GetEntity( id );        
        bool killed = false;

        Vector3 pushVector = ( entity->m_pos - _pos );
        double distance = pushVector.Mag();       
        if( distance < SOULDESTROYER_DAMAGERANGE )
        {
            g_app->m_soundSystem->TriggerEntityEvent( this, "Attack" );

            pushVector.SetLength( SOULDESTROYER_DAMAGERANGE - distance );
                                        
            g_app->m_location->m_entityGrid->RemoveObject( id, entity->m_pos.x, entity->m_pos.z, entity->m_radius );
            entity->m_pos += pushVector;
            g_app->m_location->m_entityGrid->AddObject( id, entity->m_pos.x, entity->m_pos.z, entity->m_radius );
            
            bool dead = entity->m_dead;
            entity->ChangeHealth( (SOULDESTROYER_DAMAGERANGE - distance) * -50.0 );            
            if( !dead && entity->m_dead ) killed = true;
        }

        if( killed )
        {
            // Eat the spirit
            int spiritIndex = g_app->m_location->GetSpirit( id );
            if( spiritIndex != -1 )
            {
                g_app->m_location->m_spirits.RemoveData( spiritIndex );
                if( m_spirits.NumUsed() < SOULDESTROYER_MAXSPIRITS )
                {
                    m_spirits.PutData( (double) GetHighResTime() );
                }
                else
                {
                    // Doesnt need to be sync safe
                    int index = AppRandom() % SOULDESTROYER_MAXSPIRITS;
                    m_spirits.PutData( (double) GetHighResTime(), index );
                }
            }
            
			if(entity->m_type == TypeDarwinian )
            {
				// Create a zombie
				Zombie *zombie = new Zombie();
				zombie->m_pos = entity->m_pos;
				zombie->m_front = entity->m_front;
				zombie->m_up = g_upVector;
				zombie->m_up.RotateAround( zombie->m_front * syncsfrand(1) );
				zombie->m_vel = m_vel * 0.5;
				zombie->m_vel.y = 20.0 + syncfrand(25.0);
				int index = g_app->m_location->m_effects.PutData( zombie );
				zombie->m_id.Set( id.GetTeamId(), UNIT_EFFECTS, index, -1 );
				zombie->m_id.GenerateUniqueId();
			}
        }
    } 
}
bool Officer::Advance( Unit *_unit )
{
    if( !m_onGround ) AdvanceInAir(_unit);
    bool amIDead = Entity::Advance(_unit);
    if( m_inWater != -1.0f ) AdvanceInWater(_unit);

    if( m_onGround && !m_dead ) m_pos.y = g_app->m_location->m_landscape.m_heightMap->GetValue( m_pos.x, m_pos.z );


    //
    // Advance in whatever state we are in

    if( !amIDead && m_onGround && m_inWater == -1.0f )
    {
        switch( m_state )
        {
            case StateIdle :                amIDead = AdvanceIdle();            break;
            case StateToWaypoint :          amIDead = AdvanceToWaypoint();      break;
            case StateGivingOrders :        amIDead = AdvanceGivingOrders();    break;
        }
    }

    if( m_dead )
    {
        m_vel.y -= 20.0f;
        m_pos.y += m_vel.y * SERVER_ADVANCE_PERIOD;
    }


    //
    // If we are giving orders, render them

    if( m_orders == OrderGoto )
    {
        if( syncfrand() < 0.05f )
        {
            OfficerOrders *orders = new OfficerOrders();
            orders->m_pos = m_pos + Vector3(0,2,0);
            orders->m_wayPoint = m_orderPosition;
            int index = g_app->m_location->m_effects.PutData( orders );
            orders->m_id.Set( m_id.GetTeamId(), UNIT_EFFECTS, index, -1 );
            orders->m_id.GenerateUniqueId();
        }
    }

    //
    // If we are absorbing, look around for Darwinians

    if( m_absorb ) Absorb();


    //
    // Attack anything nearby with our "shield"

    if( m_shield > 0 )
    {
        WorldObjectId id = g_app->m_location->m_entityGrid->GetBestEnemy( m_pos.x, m_pos.z, 0.0f, OFFICER_ATTACKRANGE, m_id.GetTeamId() );
        if( id.IsValid() )
        {
            Entity *entity = g_app->m_location->GetEntity( id );
            entity->ChangeHealth( -10 );
            m_shield --;

            Vector3 themToUs = m_pos - entity->m_pos;
            g_app->m_location->SpawnSpirit( m_pos, themToUs, 0, WorldObjectId() );
        }
    }


    //
    // Use teleports.  Remember which teleport we entered,
    // As there may be people following us

    if( m_wayPointTeleportId != -1 )
    {
        int teleportId = EnterTeleports(m_wayPointTeleportId);
        if( teleportId != -1 )
        {
            m_ordersBuildingId = teleportId;
            Teleport *teleport = (Teleport *) g_app->m_location->GetBuilding( teleportId );
            Vector3 exitPos, exitFront;
            bool exitFound = teleport->GetExit( exitPos, exitFront );
            if( exitFound ) m_wayPoint = exitPos + exitFront * 30.0f;
            if( m_orders == OrderGoto ) m_orders = OrderNone;
            m_wayPointTeleportId = -1;
        }
    }

    return amIDead || m_demoted;
}