gBaseZoneHack Class Reference

base zone: belongs to a team, enemy players who manage to stay inside win the round (will be replaced More...

#include <gWinZone.h>

Inheritance diagram for gBaseZoneHack:

Inheritance graph
[legend]
Collaboration diagram for gBaseZoneHack:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 gBaseZoneHack (eGrid *grid, const eCoord &pos)
 local constructor
 gBaseZoneHack (nMessage &m)
 network constructor
 ~gBaseZoneHack ()
 destructor

Private Types

enum  State { State_Safe, State_Conquering, State_Conquered }
 possible states More...
typedef std::vector
< tJUST_CONTROLLED_PTR< eTeam > > 
TeamArray

Private Member Functions

virtual bool Timestep (REAL currentTime)
 simulates behaviour up to currentTime
virtual void OnEnter (gCycle *target, REAL time)
 reacts on objects inside the zone
virtual void OnVanish ()
 called when the zone vanishes
virtual void OnConquest ()
 called when the zone gets conquered
virtual void CheckSurvivor ()
 checks for the only surviving zone

Static Private Member Functions

static void CountZonesOfTeam (eGrid const *grid, eTeam *otherTeam, int &count, gBaseZoneHack *&farthest)
 counts the zones belonging to the given team.

Private Attributes

REAL conquered_
 conquest status; zero if it is free, 1 if it has been completely conquered by the enemy
int enemiesInside_
 count of enemies currently inside the zone
int ownersInside_
 count of owners currently inside the zone
bool onlySurvivor_
 flag set if this zone is the only survivor
TeamArray enemies_
 list of teams that currently have a player in the zone
REAL lastEnemyContact_
 last time an enemy player was in the zone
REAL teamDistance_
 distance to the closest member of the owning team
bool touchy_
 flag set when the zone is "touchy", which makes it get conquered on the slightest enemy touch
State currentState_
 the current state
REAL lastSync_
 time of the last sync request


Detailed Description

base zone: belongs to a team, enemy players who manage to stay inside win the round (will be replaced

Definition at line 146 of file gWinZone.h.


Member Typedef Documentation

typedef std::vector< tJUST_CONTROLLED_PTR< eTeam > > gBaseZoneHack::TeamArray [private]

Definition at line 169 of file gWinZone.h.


Member Enumeration Documentation

enum gBaseZoneHack::State [private]

possible states

Enumerator:
State_Safe  not yet conquered
State_Conquering  conquering in this frame
State_Conquered  conquered

Definition at line 178 of file gWinZone.h.

00179     {
00180         State_Safe,        
00181         State_Conquering,  
00182         State_Conquered    
00183     };


Constructor & Destructor Documentation

gBaseZoneHack::gBaseZoneHack ( eGrid grid,
const eCoord &  pos 
)

local constructor

Parameters:
grid Grid to put the zone into
pos Position to spawn the zone at

Definition at line 729 of file gWinZone.cpp.

References conquered_, enemiesInside_, lastEnemyContact_, lastSync_, ownersInside_, se_GameTime(), and teamDistance_.

00730         :gZone( grid, pos), onlySurvivor_( false ), currentState_( State_Safe )
00731 {
00732     enemiesInside_ = ownersInside_ = 0;
00733     conquered_ = 0;
00734     lastSync_ = -10;
00735     teamDistance_ = 0;
00736     lastEnemyContact_ = se_GameTime();
00737 }

Here is the call graph for this function:

gBaseZoneHack::gBaseZoneHack ( nMessage m  ) 

network constructor

Parameters:
m Message to read creation data from

Definition at line 749 of file gWinZone.cpp.

References conquered_, enemiesInside_, lastEnemyContact_, lastSync_, ownersInside_, se_GameTime(), and teamDistance_.

00750         : gZone( m ), onlySurvivor_( false ), currentState_( State_Safe )
00751 {
00752     enemiesInside_ = ownersInside_ = 0;
00753     conquered_ = 0;
00754     lastSync_ = -10;
00755     teamDistance_ = 0;
00756     lastEnemyContact_ = se_GameTime();
00757 }

Here is the call graph for this function:

gBaseZoneHack::~gBaseZoneHack ( void   ) 

destructor

Definition at line 768 of file gWinZone.cpp.

00769 {
00770 }


Member Function Documentation

bool gBaseZoneHack::Timestep ( REAL  time  )  [private, virtual]

simulates behaviour up to currentTime

Parameters:
time the current time

Reimplemented from gZone.

Definition at line 837 of file gWinZone.cpp.

References tColor::b_, gZone::color_, conquered_, CountZonesOfTeam(), currentState_, ePlayerNetID::CurrentTeam(), gCycleMovement::distance, dt, eCoord, enemies_, enemiesInside_, tColor::g_, eGrid::GameObjects(), gZone::GetRadius(), gZone::GetRotationAcceleration(), gZone::GetRotationSpeed(), eGameObject::Grid(), lastEnemyContact_, lastSync_, eGameObject::lastTime, GrowingArrayBase::Len(), nCLIENT, nSERVER, NULL, OnConquest(), onlySurvivor_, ownersInside_, eNetGameObject::Player(), eGameObject::pos, eGameObject::Position(), tColor::r_, REAL, nNetObject::RequestSync(), gZone::SetExpansionSpeed(), gZone::SetReferenceTime(), gZone::SetRotationAcceleration(), gZone::SetRotationSpeed(), sg_baseZonesPerTeam, sg_conquestDecayRate, sg_conquestRate, sg_conquestTimeout, sg_DeclareWinner(), sg_defendRate, sg_onConquestScore, sg_segments, sn_ConsoleOut(), sn_GetNetState(), State_Conquered, State_Conquering, State_Safe, eGameObject::team, teamDistance_, eTeam::teams, and gZone::Timestep().

00838 {
00839     if ( currentState_ == State_Conquering )
00840     {
00841         // let zone vanish
00842         SetReferenceTime();
00843         SetExpansionSpeed( -GetRadius()*.5 );
00844         SetRotationAcceleration( -GetRotationSpeed()*.4 );
00845         RequestSync();
00846 
00847         currentState_ = State_Conquered;
00848     }
00849 
00850     REAL dt = time - lastTime;
00851 
00852     // conquest going on
00853     REAL conquest = sg_conquestRate * enemiesInside_ - sg_defendRate * ownersInside_ - sg_conquestDecayRate;
00854     conquered_ += dt * conquest;
00855 
00856     // clamp
00857     if ( conquered_ < 0 )
00858     {
00859         conquered_ = 0;
00860         conquest = 0;
00861     }
00862     if ( conquered_ > 1.01 )
00863     {
00864         conquered_ = 1.01;
00865         conquest = 0;
00866     }
00867 
00868     // set speed according to conquest status
00869     if ( currentState_ == State_Safe )
00870     {
00871         REAL maxSpeed = 10 * ( 2 * 3.141 ) / sg_segments;
00872         REAL omega = .3 + conquered_ * conquered_ * maxSpeed;
00873         REAL omegaDot = 2 * conquered_ * conquest * maxSpeed;
00874 
00875         // determine the time since the last sync (exaggerate for smoother motion in local games)
00876         REAL timeStep = lastTime - lastSync_;
00877         if ( sn_GetNetState() != nSERVER )
00878             timeStep *= 100;
00879 
00880         if ( sn_GetNetState() != nCLIENT &&
00881                 ( ( fabs( omega - GetRotationSpeed() ) + fabs( omegaDot - GetRotationAcceleration() ) ) * timeStep > .5 ) )
00882         {
00883             SetRotationSpeed( omega );
00884             SetRotationAcceleration( omegaDot );
00885             SetReferenceTime();
00886             RequestSync();
00887             lastSync_ = lastTime;
00888         }
00889 
00890 
00891         // check for enemy contact timeout
00892         if ( sg_conquestTimeout > 0 && lastEnemyContact_ + sg_conquestTimeout < time )
00893         {
00894             enemies_.clear();
00895 
00896             // if the zone would collapse without defenders, let it collapse now. A smart defender would
00897             // have left the zone to let it collapse anyway.
00898             if ( sg_conquestDecayRate < 0 )
00899             {
00900                 if ( team )
00901                     sn_ConsoleOut( tOutput( "$zone_collapse_harmless", team->Name()  ) );
00902                 conquered_ = 1.0;
00903             }
00904         }
00905 
00906         // check whether the zone got conquered
00907         if ( conquered_ >= 1 )
00908         {
00909             currentState_ = State_Conquering;
00910             OnConquest();
00911         }
00912     }
00913 
00914 
00915     // reset counts
00916     enemiesInside_ = ownersInside_ = 0;
00917 
00918     // determine the owning team: the one that has a player spawned closest
00919 
00920     // find the closest player
00921     if ( !team )
00922     {
00923         teamDistance_ = 0;
00924         const tList<eGameObject>& gameObjects = Grid()->GameObjects();
00925         gCycle * closest = NULL;
00926         REAL closestDistance = 0;
00927         for (int i=gameObjects.Len()-1;i>=0;i--)
00928         {
00929             gCycle *other=dynamic_cast<gCycle *>(gameObjects(i));
00930 
00931             if (other )
00932             {
00933                 eTeam * otherTeam = other->Player()->CurrentTeam();
00934                 eCoord otherpos = other->Position() - pos;
00935                 REAL distance = otherpos.NormSquared();
00936                 if ( !closest || distance < closestDistance )
00937                 {
00938                     // check whether other zones are already registered to that team
00939                     gBaseZoneHack * farthest = NULL;
00940                     int count = 0;
00941                     if ( sg_baseZonesPerTeam > 0 )
00942                         CountZonesOfTeam( Grid(), otherTeam, count, farthest );
00943 
00944                     // only set team if not too many closer other zones are registered
00945                     if ( sg_baseZonesPerTeam == 0 || count < sg_baseZonesPerTeam || farthest->teamDistance_ > distance )
00946                     {
00947                         closest = other;
00948                         closestDistance = distance;
00949                     }
00950                 }
00951             }
00952         }
00953 
00954         if ( closest )
00955         {
00956             // take over team and color
00957             team = closest->Player()->CurrentTeam();
00958             color_.r_ = team->R()/15.0;
00959             color_.g_ = team->G()/15.0;
00960             color_.b_ = team->B()/15.0;
00961             teamDistance_ = closestDistance;
00962 
00963             RequestSync();
00964         }
00965 
00966         // if this zone does not belong to a team, discard it.
00967         if ( !team )
00968         {
00969             return true;
00970         }
00971 
00972         // check other zones owned by the same team. Discard the one farthest away
00973         // if the max count is exceeded
00974         if ( team && sg_baseZonesPerTeam > 0 )
00975         {
00976             gBaseZoneHack * farthest = 0;
00977             int count = 0;
00978             CountZonesOfTeam( Grid(), team, count, farthest );
00979 
00980             // discard team of farthest zone
00981             if ( count > sg_baseZonesPerTeam )
00982                 farthest->team = NULL;
00983         }
00984     }
00985 
00986 
00987     // delegate
00988     bool ret = gZone::Timestep( time );
00989 
00990     // reward survival
00991     if ( !ret && onlySurvivor_ )
00992     {
00993         const char* message= ( eTeam::teams.Len() > 2 || sg_onConquestScore ) ? "$player_win_survive" : "$player_win_conquest";
00994         sg_DeclareWinner( team, message );
00995     }
00996 
00997     return ret;
00998 }

Here is the call graph for this function:

void gBaseZoneHack::OnEnter ( gCycle target,
REAL  time 
) [private, virtual]

reacts on objects inside the zone

Parameters:
target the cycle that has been found inside the zone
time the current time

Reimplemented from gZone.

Definition at line 1167 of file gWinZone.cpp.

References currentState_, ePlayerNetID::CurrentTeam(), enemies_, enemiesInside_, lastEnemyContact_, ownersInside_, eNetGameObject::Player(), State_Safe, tASSERT, and eGameObject::team.

01168 {
01169     // determine the team of the player
01170     tASSERT( target );
01171     if ( !target->Player() )
01172         return;
01173     tJUST_CONTROLLED_PTR< eTeam > otherTeam = target->Player()->CurrentTeam();
01174     if (!otherTeam)
01175         return;
01176     if ( currentState_ != State_Safe )
01177         return;
01178 
01179     // remember who is inside
01180     if ( team == otherTeam )
01181     {
01182         ++ ownersInside_;
01183     }
01184     else if ( team )
01185     {
01186         if ( enemiesInside_ == 0 )
01187             enemies_.clear();
01188 
01189         ++ enemiesInside_;
01190         if ( std::find( enemies_.begin(), enemies_.end(), otherTeam ) == enemies_.end() )
01191             enemies_.push_back( otherTeam );
01192 
01193         lastEnemyContact_ = time;
01194     }
01195 }

Here is the call graph for this function:

void gBaseZoneHack::OnVanish ( void   )  [private, virtual]

called when the zone vanishes

Reimplemented from gZone.

Definition at line 1009 of file gWinZone.cpp.

References eGameObject::Alive(), CheckSurvivor(), currentState_, gCycleMovement::distance, eCoord, enemies_, ePlayerNetID::GetName(), eGameObject::Kill(), NULL, ePlayerNetID::Object(), eGameObject::pos, REAL, sg_defendRate, sg_onConquestKillMin, sg_onConquestKillRatio, sn_ConsoleOut(), State_Safe, and eGameObject::team.

01010 {
01011     if (!team)
01012         return;
01013 
01014     CheckSurvivor();
01015 
01016     // kill the closest owners of the zone
01017     if ( currentState_ != State_Safe && ( enemies_.size() > 0 || sg_defendRate < 0 ) )
01018     {
01019         int kills = int( sg_onConquestKillRatio * team->NumPlayers() );
01020         kills = kills > sg_onConquestKillMin ? kills : sg_onConquestKillMin;
01021 
01022         while ( kills > 0 )
01023         {
01024             -- kills;
01025 
01026             ePlayerNetID * closest = NULL;
01027             REAL closestDistance = 0;
01028 
01029             // find the closest living owner
01030             for ( int i = team->NumPlayers()-1; i >= 0; --i )
01031             {
01032                 ePlayerNetID * player = team->Player(i);
01033                 eNetGameObject * object = player->Object();
01034                 if ( object && object->Alive() )
01035                 {
01036                     eCoord otherpos = object->Position() - pos;
01037                     REAL distance = otherpos.NormSquared();
01038                     if ( !closest || distance < closestDistance )
01039                     {
01040                         closest = player;
01041                         closestDistance = distance;
01042                     }
01043                 }
01044             }
01045 
01046             if ( closest )
01047             {
01048                 sn_ConsoleOut( tOutput("$player_kill_collapse", closest->GetName() ) );
01049                 closest->Object()->Kill();
01050             }
01051         }
01052     }
01053 }

Here is the call graph for this function:

void gBaseZoneHack::OnConquest ( void   )  [private, virtual]

called when the zone gets conquered

Definition at line 1064 of file gWinZone.cpp.

References eTeam::Alive(), CheckSurvivor(), enemies_, enemiesInside_, score, tOutput::SetTemplateParameter(), sg_DeclareWinner(), sg_onConquestScore, sg_onConquestWin, and eGameObject::team.

Referenced by Timestep().

01065 {
01066     // calculate score. If nobody really was inside the zone any more, half it.
01067     int totalScore = sg_onConquestScore;
01068     if ( 0 == enemiesInside_ )
01069         totalScore /= 2;
01070 
01071     // eliminate dead enemies
01072     TeamArray enemiesAlive;
01073     for ( TeamArray::iterator iter = enemies_.begin(); iter != enemies_.end(); ++iter )
01074     {
01075         eTeam* team = *iter;
01076         if ( team->Alive() )
01077             enemiesAlive.push_back( team );
01078     }
01079     enemies_ = enemiesAlive;
01080 
01081     // add score for successful conquest, divided equally between the teams that are
01082     // inside the zone
01083     if ( totalScore && enemies_.size() > 0 )
01084     {
01085         tOutput win;
01086         if ( team )
01087         {
01088             win.SetTemplateParameter( 3, team->Name() );
01089             win << "$player_win_conquest_specific";
01090         }
01091         else
01092         {
01093             win << "$player_win_conquest";
01094         }
01095 
01096         int score = totalScore / enemies_.size();
01097         for ( TeamArray::iterator iter = enemies_.begin(); iter != enemies_.end(); ++iter )
01098         {
01099             (*iter)->AddScore( score, win, tOutput() );
01100         }
01101     }
01102 
01103     // trigger immediate win
01104     if ( sg_onConquestWin && enemies_.size() > 0 )
01105     {
01106         static const char* message="$player_win_conquest";
01107         sg_DeclareWinner( enemies_[0], message );
01108     }
01109 
01110     CheckSurvivor();
01111 }

Here is the call graph for this function:

Here is the caller graph for this function:

void gBaseZoneHack::CheckSurvivor ( void   )  [private, virtual]

checks for the only surviving zone

Definition at line 1126 of file gWinZone.cpp.

References currentState_, eGrid::GameObjects(), eGameObject::Grid(), GrowingArrayBase::Len(), onlySurvivor_, sg_onSurviveWin, State_Safe, and eGameObject::team.

Referenced by OnConquest(), and OnVanish().

01127 {
01128     // test if there is only one team with non-conquered zones left
01129     if ( sg_onSurviveWin )
01130     {
01131         // find surviving team and test whether it is the only one
01132         gBaseZoneHack * survivor = 0;
01133         bool onlySurvivor = true;
01134 
01135         const tList<eGameObject>& gameObjects = Grid()->GameObjects();
01136         for (int i=gameObjects.Len()-1;i>=0 && onlySurvivor;i--){
01137             gBaseZoneHack *other=dynamic_cast<gBaseZoneHack *>(gameObjects(i));
01138 
01139             if ( other && other->currentState_ == State_Safe && other->team )
01140             {
01141                 if ( survivor && survivor->team != other->team )
01142                     onlySurvivor = false;
01143                 else
01144                     survivor = other;
01145             }
01146         }
01147 
01148         // reward it later
01149         if ( onlySurvivor && survivor )
01150         {
01151             survivor->onlySurvivor_ = true;
01152         }
01153     }
01154 }

Here is the call graph for this function:

Here is the caller graph for this function:

void gBaseZoneHack::CountZonesOfTeam ( eGrid const *  grid,
eTeam otherTeam,
int &  count,
gBaseZoneHack *&  farthest 
) [static, private]

counts the zones belonging to the given team.

Definition at line 806 of file gWinZone.cpp.

References eGrid::GameObjects(), GrowingArrayBase::Len(), NULL, eGameObject::Team(), and teamDistance_.

Referenced by Timestep().

00807 {
00808     count = 0;
00809     farthest = NULL;
00810 
00811     // check whether other zones are already registered to that team
00812     const tList<eGameObject>& gameObjects = grid->GameObjects();
00813     for (int j=gameObjects.Len()-1;j>=0;j--)
00814     {
00815         gBaseZoneHack *otherZone=dynamic_cast<gBaseZoneHack *>(gameObjects(j));
00816 
00817         if ( otherZone && otherTeam == otherZone->Team() )
00818         {
00819             count++;
00820             if ( !farthest || otherZone->teamDistance_ > farthest->teamDistance_ )
00821                 farthest = otherZone;
00822         }
00823     }
00824 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

REAL gBaseZoneHack::conquered_ [private]

conquest status; zero if it is free, 1 if it has been completely conquered by the enemy

Definition at line 163 of file gWinZone.h.

Referenced by gBaseZoneHack(), and Timestep().

int gBaseZoneHack::enemiesInside_ [private]

count of enemies currently inside the zone

Definition at line 164 of file gWinZone.h.

Referenced by gBaseZoneHack(), OnConquest(), OnEnter(), and Timestep().

int gBaseZoneHack::ownersInside_ [private]

count of owners currently inside the zone

Definition at line 165 of file gWinZone.h.

Referenced by gBaseZoneHack(), OnEnter(), and Timestep().

bool gBaseZoneHack::onlySurvivor_ [private]

flag set if this zone is the only survivor

Definition at line 167 of file gWinZone.h.

Referenced by CheckSurvivor(), and Timestep().

TeamArray gBaseZoneHack::enemies_ [private]

list of teams that currently have a player in the zone

Definition at line 170 of file gWinZone.h.

Referenced by OnConquest(), OnEnter(), OnVanish(), and Timestep().

REAL gBaseZoneHack::lastEnemyContact_ [private]

last time an enemy player was in the zone

Definition at line 171 of file gWinZone.h.

Referenced by gBaseZoneHack(), OnEnter(), and Timestep().

REAL gBaseZoneHack::teamDistance_ [private]

distance to the closest member of the owning team

Definition at line 173 of file gWinZone.h.

Referenced by CountZonesOfTeam(), gBaseZoneHack(), and Timestep().

bool gBaseZoneHack::touchy_ [private]

flag set when the zone is "touchy", which makes it get conquered on the slightest enemy touch

Definition at line 175 of file gWinZone.h.

State gBaseZoneHack::currentState_ [private]

the current state

Definition at line 184 of file gWinZone.h.

Referenced by CheckSurvivor(), OnEnter(), OnVanish(), and Timestep().

REAL gBaseZoneHack::lastSync_ [private]

time of the last sync request

Definition at line 186 of file gWinZone.h.

Referenced by gBaseZoneHack(), and Timestep().


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:33:58 2008 for Armagetron Advanced by  doxygen 1.5.4