2010-01-22 21:03:14 +01:00
function Player ( ) { }
2010-04-23 18:09:03 +02:00
Player . prototype . Schema =
"<a:component type='system'/><empty/>" ;
2010-01-22 21:03:14 +01:00
Player . prototype . Init = function ( )
{
this . playerID = undefined ;
2010-10-30 06:02:42 +02:00
this . name = undefined ; // define defaults elsewhere (supporting other languages)
this . civ = undefined ;
2010-06-30 23:41:04 +02:00
this . colour = { "r" : 0.0 , "g" : 0.0 , "b" : 0.0 , "a" : 1.0 } ;
2011-06-25 02:47:46 +02:00
this . popUsed = 0 ; // population of units owned or trained by this player
this . popBonuses = 0 ; // sum of population bonuses of player's entities
2011-07-18 02:31:42 +02:00
this . maxPop = 300 ; // maximum population
2012-04-20 19:21:04 +02:00
this . trainingBlocked = false ; // indicates whether any training queue is currently blocked
2010-02-12 23:46:53 +01:00
this . resourceCount = {
2012-05-12 23:31:00 +02:00
"food" : 300 ,
"wood" : 300 ,
"metal" : 300 ,
"stone" : 300
2010-02-12 23:46:53 +01:00
} ;
2010-10-30 06:02:42 +02:00
this . team = - 1 ; // team number of the player, players on the same team will always have ally diplomatic status - also this is useful for team emblems, scoring, etc.
2012-10-23 18:31:07 +02:00
this . teamsLocked = false ;
2010-10-01 22:51:21 +02:00
this . state = "active" ; // game state - one of "active", "defeated", "won"
2011-08-15 02:25:22 +02:00
this . diplomacy = [ ] ; // array of diplomatic stances for this player with respect to other players (including gaia and self)
2010-10-01 22:51:21 +02:00
this . conquestCriticalEntitiesCount = 0 ; // number of owned units with ConquestCritical class
2010-10-30 06:02:42 +02:00
this . phase = "village" ;
2012-05-04 01:32:10 +02:00
this . formations = [ ] ;
2011-06-14 01:32:41 +02:00
this . startCam = undefined ;
2011-07-02 02:06:39 +02:00
this . controlAllUnits = false ;
2011-08-15 02:25:22 +02:00
this . isAI = false ;
2012-08-05 16:01:05 +02:00
this . cheatsEnabled = true ;
this . cheatTimeMultiplier = 1 ;
2010-01-22 21:03:14 +01:00
} ;
2010-06-30 23:41:04 +02:00
Player . prototype . SetPlayerID = function ( id )
2010-04-23 20:36:48 +02:00
{
2010-06-30 23:41:04 +02:00
this . playerID = id ;
2010-04-23 20:36:48 +02:00
} ;
2010-08-21 22:43:55 +02:00
Player . prototype . GetPlayerID = function ( )
{
return this . playerID ;
} ;
2010-06-30 23:41:04 +02:00
Player . prototype . SetName = function ( name )
2010-01-22 21:03:14 +01:00
{
2010-06-30 23:41:04 +02:00
this . name = name ;
} ;
2010-07-02 04:44:25 +02:00
Player . prototype . GetName = function ( )
{
return this . name ;
} ;
2010-06-30 23:41:04 +02:00
Player . prototype . SetCiv = function ( civcode )
{
this . civ = civcode ;
2010-01-22 21:03:14 +01:00
} ;
2010-07-02 04:44:25 +02:00
Player . prototype . GetCiv = function ( )
{
return this . civ ;
} ;
2010-06-30 23:41:04 +02:00
Player . prototype . SetColour = function ( r , g , b )
{
this . colour = { "r" : r / 255.0 , "g" : g / 255.0 , "b" : b / 255.0 , "a" : 1.0 } ;
} ;
Player . prototype . GetColour = function ( )
{
return this . colour ;
} ;
2010-08-21 22:43:55 +02:00
Player . prototype . TryReservePopulationSlots = function ( num )
{
2012-08-18 20:44:20 +02:00
if ( num != 0 && num > ( this . GetPopulationLimit ( ) - this . GetPopulationCount ( ) ) )
2010-08-21 22:43:55 +02:00
return false ;
2011-06-25 02:47:46 +02:00
this . popUsed += num ;
2010-08-21 22:43:55 +02:00
return true ;
} ;
Player . prototype . UnReservePopulationSlots = function ( num )
{
2011-06-25 02:47:46 +02:00
this . popUsed -= num ;
2010-08-21 22:43:55 +02:00
} ;
2010-01-22 21:03:14 +01:00
Player . prototype . GetPopulationCount = function ( )
{
2011-06-25 02:47:46 +02:00
return this . popUsed ;
2010-01-22 21:03:14 +01:00
} ;
2011-06-25 02:47:46 +02:00
Player . prototype . GetPopulationLimit = function ( )
2010-10-30 06:02:42 +02:00
{
2012-10-08 00:19:03 +02:00
return Math . min ( this . GetMaxPopulation ( ) , this . popBonuses ) ;
2010-10-30 06:02:42 +02:00
} ;
2011-06-25 02:47:46 +02:00
Player . prototype . SetMaxPopulation = function ( max )
{
this . maxPop = max ;
} ;
Player . prototype . GetMaxPopulation = function ( )
2010-01-22 21:03:14 +01:00
{
2012-10-08 00:19:03 +02:00
var cmpTechMan = Engine . QueryInterface ( this . entity , IID _TechnologyManager ) ;
if ( cmpTechMan )
return cmpTechMan . ApplyModifications ( "Player/MaxPopulation" , this . maxPop , this . entity ) ;
else
return this . maxPop ;
2010-01-22 21:03:14 +01:00
} ;
2012-04-20 19:21:04 +02:00
Player . prototype . IsTrainingBlocked = function ( )
2010-09-04 15:24:52 +02:00
{
2012-04-20 19:21:04 +02:00
return this . trainingBlocked ;
2010-09-04 15:24:52 +02:00
} ;
2012-04-20 19:21:04 +02:00
Player . prototype . BlockTraining = function ( )
2010-09-04 15:24:52 +02:00
{
2012-04-20 19:21:04 +02:00
this . trainingBlocked = true ;
2010-09-04 15:24:52 +02:00
} ;
2012-04-20 19:21:04 +02:00
Player . prototype . UnBlockTraining = function ( )
2010-09-04 15:24:52 +02:00
{
2012-04-20 19:21:04 +02:00
this . trainingBlocked = false ;
2010-09-04 15:24:52 +02:00
} ;
2010-10-30 06:02:42 +02:00
Player . prototype . SetResourceCounts = function ( resources )
{
2010-11-19 06:05:45 +01:00
if ( resources . food !== undefined )
this . resourceCount . food = resources . food ;
if ( resources . wood !== undefined )
this . resourceCount . wood = resources . wood ;
if ( resources . stone !== undefined )
this . resourceCount . stone = resources . stone ;
if ( resources . metal !== undefined )
this . resourceCount . metal = resources . metal ;
2010-10-30 06:02:42 +02:00
} ;
2010-02-12 23:46:53 +01:00
Player . prototype . GetResourceCounts = function ( )
{
return this . resourceCount ;
} ;
2010-11-12 23:24:49 +01:00
/ * *
2010-11-13 20:15:29 +01:00
* Add resource of specified type to player
2010-11-12 23:24:49 +01:00
* @ param type Generic type of resource ( string )
* @ param amount Amount of resource , whick should be added ( integer )
* /
2010-11-13 20:15:29 +01:00
Player . prototype . AddResource = function ( type , amount )
2010-02-12 23:46:53 +01:00
{
this . resourceCount [ type ] += ( + amount ) ;
} ;
2010-11-12 23:24:49 +01:00
/ * *
2010-11-13 20:15:29 +01:00
* Add resources to player
2010-11-12 23:24:49 +01:00
* /
2010-04-19 21:47:23 +02:00
Player . prototype . AddResources = function ( amounts )
{
for ( var type in amounts )
2010-11-12 23:24:49 +01:00
{
2010-04-19 21:47:23 +02:00
this . resourceCount [ type ] += ( + amounts [ type ] ) ;
2010-11-12 23:24:49 +01:00
}
2010-04-19 21:47:23 +02:00
} ;
2012-08-13 18:47:10 +02:00
Player . prototype . GetNeededResources = function ( amounts )
2010-03-12 22:41:40 +01:00
{
2010-08-14 00:02:27 +02:00
// Check if we can afford it all
var amountsNeeded = { } ;
2010-03-12 22:41:40 +01:00
for ( var type in amounts )
2012-08-13 18:47:10 +02:00
if ( this . resourceCount [ type ] != undefined && amounts [ type ] > this . resourceCount [ type ] )
2010-08-14 00:02:27 +02:00
amountsNeeded [ type ] = amounts [ type ] - this . resourceCount [ type ] ;
2012-08-13 18:47:10 +02:00
if ( Object . keys ( amountsNeeded ) . length == 0 )
return undefined ;
return amountsNeeded ;
} ;
Player . prototype . TrySubtractResources = function ( amounts )
{
var amountsNeeded = this . GetNeededResources ( amounts ) ;
2012-10-23 18:31:07 +02:00
2010-08-14 00:02:27 +02:00
// If we don't have enough resources, send a notification to the player
2012-08-13 18:47:10 +02:00
if ( amountsNeeded )
2010-08-14 00:02:27 +02:00
{
2012-08-13 18:47:10 +02:00
var formatted = [ ] ;
for ( var type in amountsNeeded )
formatted . push ( amountsNeeded [ type ] + " " + type [ 0 ] . toUpperCase ( ) + type . substr ( 1 ) ) ;
var notification = { "player" : this . playerID , "message" : "Insufficient resources - " + formatted . join ( ", " ) } ;
2010-08-14 00:02:27 +02:00
var cmpGUIInterface = Engine . QueryInterface ( SYSTEM _ENTITY , IID _GuiInterface ) ;
2010-08-14 06:34:49 +02:00
cmpGUIInterface . PushNotification ( notification ) ;
2010-08-14 00:02:27 +02:00
return false ;
}
else
{
// Subtract the resources
2012-08-29 07:13:45 +02:00
var cmpStatisticsTracker = QueryPlayerIDInterface ( this . playerID , IID _StatisticsTracker ) ;
2010-08-14 00:02:27 +02:00
for ( var type in amounts )
2012-08-29 07:13:45 +02:00
{
2010-08-14 17:34:36 +02:00
this . resourceCount [ type ] -= amounts [ type ] ;
2012-08-29 07:13:45 +02:00
if ( cmpStatisticsTracker )
cmpStatisticsTracker . IncreaseResourceUsedCounter ( type , amounts [ type ] ) ;
}
2010-08-14 00:02:27 +02:00
}
2010-03-12 22:41:40 +01:00
return true ;
} ;
2010-10-01 22:51:21 +02:00
Player . prototype . GetState = function ( )
{
return this . state ;
} ;
Player . prototype . SetState = function ( newState )
{
this . state = newState ;
} ;
Player . prototype . GetConquestCriticalEntitiesCount = function ( )
{
return this . conquestCriticalEntitiesCount ;
} ;
2010-10-30 06:02:42 +02:00
Player . prototype . GetTeam = function ( )
{
return this . team ;
} ;
Player . prototype . SetTeam = function ( team )
{
2012-10-23 18:31:07 +02:00
if ( ! this . teamsLocked )
{
this . team = team ;
var cmpPlayerManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _PlayerManager ) ;
if ( cmpPlayerManager && this . team != - 1 )
{
// Set all team members as allies
for ( var i = 0 ; i < this . diplomacy . length ; ++ i )
{
var cmpPlayer = Engine . QueryInterface ( cmpPlayerManager . GetPlayerByID ( i ) , IID _Player ) ;
if ( this . team == cmpPlayer . GetTeam ( ) )
{
this . SetAlly ( i ) ;
cmpPlayer . SetAlly ( this . playerID ) ;
}
}
}
Engine . BroadcastMessage ( MT _DiplomacyChanged , { "player" : this . playerID } ) ;
}
} ;
Player . prototype . SetLockTeams = function ( value )
{
this . teamsLocked = value ;
} ;
Player . prototype . GetLockTeams = function ( )
{
return this . teamsLocked ;
2010-10-30 06:02:42 +02:00
} ;
Player . prototype . GetDiplomacy = function ( )
{
return this . diplomacy ;
} ;
Player . prototype . SetDiplomacy = function ( dipl )
{
2012-10-23 18:31:07 +02:00
// Should we check for teamsLocked here?
2010-10-30 06:02:42 +02:00
this . diplomacy = dipl ;
2012-10-23 18:31:07 +02:00
Engine . BroadcastMessage ( MT _DiplomacyChanged , { "player" : this . playerID } ) ;
2012-06-08 06:41:39 +02:00
} ;
Player . prototype . SetDiplomacyIndex = function ( idx , value )
{
2012-10-23 18:31:07 +02:00
// You can have alliances with other players,
if ( this . teamsLocked )
{
var cmpPlayerManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _PlayerManager ) ;
if ( cmpPlayerManager )
{
var cmpPlayer = Engine . QueryInterface ( cmpPlayerManager . GetPlayerByID ( idx ) , IID _Player ) ;
// but can't stab your team members in the back
if ( this . team == - 1 || cmpPlayer && this . team != cmpPlayer . GetTeam ( ) )
{
this . diplomacy [ idx ] = value ;
Engine . BroadcastMessage ( MT _DiplomacyChanged , { "player" : this . playerID } ) ;
}
}
}
else
{
this . diplomacy [ idx ] = value ;
Engine . BroadcastMessage ( MT _DiplomacyChanged , { "player" : this . playerID } ) ;
}
2012-06-08 06:41:39 +02:00
} ;
Player . prototype . UpdateSharedLos = function ( )
{
var cmpRangeManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _RangeManager ) ;
if ( ! cmpRangeManager )
return ;
2012-10-23 18:31:07 +02:00
var cmpPlayerManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _PlayerManager ) ;
if ( ! cmpPlayerManager )
return ;
2012-06-08 06:41:39 +02:00
var sharedLos = [ ] ;
for ( var i = 0 ; i < this . diplomacy . length ; ++ i )
if ( this . IsAlly ( i ) )
2012-10-23 18:31:07 +02:00
{
var cmpPlayer = Engine . QueryInterface ( cmpPlayerManager . GetPlayerByID ( i ) , IID _Player ) ;
if ( cmpPlayer && cmpPlayer . IsAlly ( this . playerID ) )
sharedLos . push ( i ) ;
}
2012-06-08 06:41:39 +02:00
cmpRangeManager . SetSharedLos ( this . playerID , sharedLos ) ;
2010-10-30 06:02:42 +02:00
} ;
2012-05-04 01:32:10 +02:00
Player . prototype . GetFormations = function ( )
{
return this . formations ;
} ;
Player . prototype . SetFormations = function ( formations )
{
this . formations = formations ;
} ;
2011-06-16 23:21:33 +02:00
Player . prototype . GetStartingCameraPos = function ( )
2011-06-14 01:32:41 +02:00
{
2011-06-16 23:21:33 +02:00
return this . startCam . position ;
2011-08-15 02:25:22 +02:00
} ;
2011-06-14 01:32:41 +02:00
2011-06-16 23:21:33 +02:00
Player . prototype . GetStartingCameraRot = function ( )
2011-06-14 01:32:41 +02:00
{
2011-06-16 23:21:33 +02:00
return this . startCam . rotation ;
2011-08-15 02:25:22 +02:00
} ;
2011-06-16 23:21:33 +02:00
Player . prototype . SetStartingCamera = function ( pos , rot )
{
this . startCam = { "position" : pos , "rotation" : rot } ;
2011-08-15 02:25:22 +02:00
} ;
2011-06-14 01:32:41 +02:00
Player . prototype . HasStartingCamera = function ( )
{
return ( this . startCam !== undefined ) ;
2011-08-15 02:25:22 +02:00
} ;
2011-06-14 01:32:41 +02:00
2011-07-02 02:06:39 +02:00
Player . prototype . SetControlAllUnits = function ( c )
{
this . controlAllUnits = c ;
2011-08-15 02:25:22 +02:00
} ;
2011-07-02 02:06:39 +02:00
Player . prototype . CanControlAllUnits = function ( )
{
return this . controlAllUnits ;
2011-08-15 02:25:22 +02:00
} ;
Player . prototype . SetAI = function ( flag )
{
this . isAI = flag ;
} ;
Player . prototype . IsAI = function ( )
{
return this . isAI ;
} ;
Player . prototype . SetAlly = function ( id )
{
2012-06-08 06:41:39 +02:00
this . SetDiplomacyIndex ( id , 1 ) ;
2011-08-15 02:25:22 +02:00
} ;
2011-07-02 02:06:39 +02:00
/ * *
* Check if given player is our ally
* /
Player . prototype . IsAlly = function ( id )
{
2012-06-04 02:24:08 +02:00
return this . diplomacy [ id ] > 0 ;
2011-08-15 02:25:22 +02:00
} ;
Player . prototype . SetEnemy = function ( id )
{
2012-06-08 06:41:39 +02:00
this . SetDiplomacyIndex ( id , - 1 ) ;
2011-08-15 02:25:22 +02:00
} ;
2011-07-02 02:06:39 +02:00
/ * *
* Check if given player is our enemy
* /
Player . prototype . IsEnemy = function ( id )
{
2012-06-04 02:24:08 +02:00
return this . diplomacy [ id ] < 0 ;
2011-08-15 02:25:22 +02:00
} ;
Player . prototype . SetNeutral = function ( id )
{
2012-06-08 06:41:39 +02:00
this . SetDiplomacyIndex ( id , 0 ) ;
2011-08-15 02:25:22 +02:00
} ;
2011-07-02 02:06:39 +02:00
/ * *
* Check if given player is neutral
* /
Player . prototype . IsNeutral = function ( id )
{
2012-06-04 02:24:08 +02:00
return this . diplomacy [ id ] == 0 ;
2011-08-15 02:25:22 +02:00
} ;
2011-07-02 02:06:39 +02:00
2010-11-12 23:24:49 +01:00
/ * *
* Keep track of population effects of all entities that
* become owned or unowned by this player
* /
2010-01-22 21:03:14 +01:00
Player . prototype . OnGlobalOwnershipChanged = function ( msg )
{
2010-11-12 23:24:49 +01:00
var isConquestCritical = false ;
2010-10-01 22:51:21 +02:00
// Load class list only if we're going to need it
if ( msg . from == this . playerID || msg . to == this . playerID )
{
var cmpIdentity = Engine . QueryInterface ( msg . entity , IID _Identity ) ;
if ( cmpIdentity )
2010-11-12 23:24:49 +01:00
{
var classes = cmpIdentity . GetClassesList ( ) ;
isConquestCritical = classes . indexOf ( "ConquestCritical" ) != - 1 ;
}
2010-10-01 22:51:21 +02:00
}
2010-11-12 23:24:49 +01:00
2010-01-22 21:03:14 +01:00
if ( msg . from == this . playerID )
{
2010-11-12 23:24:49 +01:00
if ( isConquestCritical )
2012-10-23 18:31:07 +02:00
this . conquestCriticalEntitiesCount -- ;
2010-10-01 22:51:21 +02:00
2010-01-22 21:03:14 +01:00
var cost = Engine . QueryInterface ( msg . entity , IID _Cost ) ;
if ( cost )
2010-01-24 18:24:35 +01:00
{
2010-08-21 22:43:55 +02:00
this . popUsed -= cost . GetPopCost ( ) ;
2011-06-25 02:47:46 +02:00
this . popBonuses -= cost . GetPopBonus ( ) ;
2010-01-24 18:24:35 +01:00
}
2010-01-22 21:03:14 +01:00
}
if ( msg . to == this . playerID )
{
2010-11-12 23:24:49 +01:00
if ( isConquestCritical )
2010-10-01 22:51:21 +02:00
this . conquestCriticalEntitiesCount ++ ;
2010-11-12 23:24:49 +01:00
2010-01-22 21:03:14 +01:00
var cost = Engine . QueryInterface ( msg . entity , IID _Cost ) ;
if ( cost )
2010-01-24 18:24:35 +01:00
{
2010-08-21 22:43:55 +02:00
this . popUsed += cost . GetPopCost ( ) ;
2011-06-25 02:47:46 +02:00
this . popBonuses += cost . GetPopBonus ( ) ;
2010-01-24 18:24:35 +01:00
}
2010-01-22 21:03:14 +01:00
}
} ;
2012-08-05 20:07:56 +02:00
Player . prototype . OnPlayerDefeated = function ( msg )
2010-10-01 22:51:21 +02:00
{
this . state = "defeated" ;
2012-10-23 18:31:07 +02:00
// TODO: Tribute all resources to this player's active allies (if any)
2012-08-08 07:27:59 +02:00
// Reassign all player's entities to Gaia
2010-10-01 22:51:21 +02:00
var cmpRangeManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _RangeManager ) ;
var entities = cmpRangeManager . GetEntitiesByPlayer ( this . playerID ) ;
2012-08-08 07:27:59 +02:00
// The ownership change is done in two steps so that entities don't hit idle
// (and thus possibly look for "enemies" to attack) before nearby allies get
// converted to Gaia as well.
for each ( var entity in entities )
2012-08-05 20:07:56 +02:00
{
2012-08-08 07:27:59 +02:00
var cmpOwnership = Engine . QueryInterface ( entity , IID _Ownership ) ;
cmpOwnership . SetOwnerQuiet ( 0 ) ;
2010-10-01 22:51:21 +02:00
}
2012-08-05 07:34:17 +02:00
2012-08-08 07:27:59 +02:00
// With the real ownership change complete, send OwnershipChanged messages.
for each ( var entity in entities )
Engine . PostMessage ( entity , MT _OwnershipChanged , { "entity" : entity ,
"from" : this . playerID , "to" : 0 } ) ;
2012-08-05 07:34:17 +02:00
// Reveal the map for this player.
cmpRangeManager . SetLosRevealAll ( this . playerID , true ) ;
2012-08-05 07:41:19 +02:00
// Send a chat message notifying of the player's defeat.
var notification = { "type" : "defeat" , "player" : this . playerID } ;
var cmpGUIInterface = Engine . QueryInterface ( SYSTEM _ENTITY , IID _GuiInterface ) ;
cmpGUIInterface . PushNotification ( notification ) ;
2011-08-15 02:25:22 +02:00
} ;
2010-10-01 22:51:21 +02:00
2012-10-23 18:31:07 +02:00
Player . prototype . OnDiplomacyChanged = function ( )
{
this . UpdateSharedLos ( ) ;
} ;
2012-08-05 16:01:05 +02:00
Player . prototype . SetCheatEnabled = function ( flag )
{
this . cheatsEnabled = flag ;
2012-10-23 18:31:07 +02:00
} ;
2012-08-05 16:01:05 +02:00
Player . prototype . GetCheatEnabled = function ( flag )
{
return this . cheatsEnabled ;
2012-10-23 18:31:07 +02:00
} ;
Player . prototype . TributeResource = function ( player , amounts )
{
var cmpPlayerManager = Engine . QueryInterface ( SYSTEM _ENTITY , IID _PlayerManager ) ;
if ( ! cmpPlayerManager )
return ;
var cmpPlayer = Engine . QueryInterface ( cmpPlayerManager . GetPlayerByID ( player ) , IID _Player ) ;
if ( cmpPlayer && ! this . GetNeededResources ( amounts ) )
{
for ( var type in amounts )
this . resourceCount [ type ] -= amounts [ type ] ;
cmpPlayer . AddResources ( amounts ) ;
// TODO: notify the receiver
}
// else not enough resources... TODO: send gui notification
} ;
2012-08-05 16:01:05 +02:00
2010-01-22 21:03:14 +01:00
Engine . RegisterComponentType ( IID _Player , "Player" , Player ) ;