LCOV - code coverage report
Current view: top level - simulation/helpers - Player.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 59 136 43.4 %
Date: 2023-04-02 12:52:40 Functions: 9 19 47.4 %

          Line data    Source code
       1             : /**
       2             :  * Used to create player entities prior to reading the rest of a map,
       3             :  * all other initialization must be done after loading map (terrain/entities).
       4             :  * Be VERY careful in using other components here, as they may not be properly initialised yet.
       5             :  * settings is the object containing settings for this map.
       6             :  * newPlayers if true will remove old player entities or add new ones until
       7             :  * the new number of player entities is obtained
       8             :  * (used when loading a map or when Atlas changes the number of players).
       9             :  */
      10             : function LoadPlayerSettings(settings, newPlayers)
      11             : {
      12           0 :         const playerDefaults = Engine.ReadJSONFile("simulation/data/settings/player_defaults.json").PlayerData;
      13           0 :         const playerData = settings.PlayerData;
      14           0 :         if (!playerData)
      15           0 :                 warn("Player.js: Setup has no player data - using defaults.");
      16             : 
      17           0 :         const getPlayerSetting = (idx, property) => {
      18           0 :                 if (playerData && playerData[idx] && (property in playerData[idx]))
      19           0 :                         return playerData[idx][property];
      20             : 
      21           0 :                 if (playerDefaults && playerDefaults[idx] && (property in playerDefaults[idx]))
      22           0 :                         return playerDefaults[idx][property];
      23             : 
      24           0 :                 return undefined;
      25             :         };
      26             : 
      27             :         // Add gaia to simplify iteration
      28             :         // (if gaia is not already the first civ such as when called from Atlas' ActorViewer)
      29           0 :         if (playerData && playerData[0] && (!playerData[0].Civ || playerData[0].Civ != "gaia"))
      30           0 :                 playerData.unshift(null);
      31             : 
      32           0 :         if (playerData && !playerData.some(v => v && !!v.AI))
      33           0 :                 Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface).Disable();
      34             : 
      35           0 :         const cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
      36           0 :         let numPlayers = cmpPlayerManager.GetNumPlayers();
      37             : 
      38             :         // Remove existing players or add new ones
      39           0 :         if (newPlayers)
      40             :         {
      41           0 :                 const settingsNumPlayers = playerData?.length ?? playerDefaults.length;
      42             : 
      43           0 :                 while (numPlayers < settingsNumPlayers)
      44           0 :                         cmpPlayerManager.AddPlayer(GetPlayerTemplateName(getPlayerSetting(numPlayers++, "Civ")));
      45             : 
      46           0 :                 for (; numPlayers > settingsNumPlayers; numPlayers--)
      47           0 :                         cmpPlayerManager.RemoveLastPlayer();
      48             :         }
      49             : 
      50             :         // Even when no new player, we must check the template compatibility as player templates are civ dependent.
      51           0 :         const cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
      52           0 :         for (let i = 0; i < numPlayers; ++i)
      53             :         {
      54           0 :                 const template = GetPlayerTemplateName(getPlayerSetting(i, "Civ"));
      55           0 :                 const entID = cmpPlayerManager.GetPlayerByID(i);
      56           0 :                 if (cmpTemplateManager.GetCurrentTemplateName(entID) !== template)
      57           0 :                         cmpPlayerManager.ReplacePlayerTemplate(i, template);
      58             :         }
      59             : 
      60           0 :         for (let i = 0; i < numPlayers; ++i)
      61             :         {
      62           0 :                 QueryPlayerIDInterface(i, IID_Identity).SetName(getPlayerSetting(i, "Name"));
      63             : 
      64           0 :                 const color = getPlayerSetting(i, "Color");
      65           0 :                 const cmpPlayer = QueryPlayerIDInterface(i);
      66           0 :                 cmpPlayer.SetColor(color.r, color.g, color.b);
      67             : 
      68             :                 // Special case for gaia
      69           0 :                 if (i == 0)
      70           0 :                         continue;
      71             : 
      72             :                 // PopulationLimit
      73             :                 {
      74             :                         const maxPopulation =
      75           0 :                                 settings.PlayerData[i].PopulationLimit !== undefined ?
      76             :                                         settings.PlayerData[i].PopulationLimit :
      77             :                                 settings.PopulationCap !== undefined ?
      78             :                                         settings.PopulationCap :
      79             :                                 playerDefaults[i].PopulationLimit !== undefined ?
      80             :                                         playerDefaults[i].PopulationLimit :
      81             :                                         undefined;
      82             : 
      83           0 :                         if (maxPopulation !== undefined)
      84           0 :                                 cmpPlayer.SetMaxPopulation(maxPopulation);
      85             :                 }
      86             : 
      87             :                 // StartingResources
      88           0 :                 if (settings.PlayerData[i].Resources !== undefined)
      89           0 :                         cmpPlayer.SetResourceCounts(settings.PlayerData[i].Resources);
      90           0 :                 else if (settings.StartingResources)
      91             :                 {
      92           0 :                         let resourceCounts = cmpPlayer.GetResourceCounts();
      93           0 :                         let newResourceCounts = {};
      94           0 :                         for (let resouces in resourceCounts)
      95           0 :                                 newResourceCounts[resouces] = settings.StartingResources;
      96           0 :                         cmpPlayer.SetResourceCounts(newResourceCounts);
      97             :                 }
      98           0 :                 else if (playerDefaults[i].Resources !== undefined)
      99           0 :                         cmpPlayer.SetResourceCounts(playerDefaults[i].Resources);
     100             : 
     101           0 :                 if (settings.DisableSpies)
     102             :                 {
     103           0 :                         cmpPlayer.AddDisabledTechnology("unlock_spies");
     104           0 :                         cmpPlayer.AddDisabledTemplate("special/spy");
     105             :                 }
     106             : 
     107             :                 // If diplomacy explicitly defined, use that; otherwise use teams.
     108           0 :                 const diplomacy = getPlayerSetting(i, "Diplomacy");
     109           0 :                 if (diplomacy !== undefined)
     110           0 :                         cmpPlayer.SetDiplomacy(diplomacy);
     111             :                 else
     112           0 :                         cmpPlayer.SetTeam(getPlayerSetting(i, "Team") ?? -1);
     113             : 
     114           0 :                 const formations = getPlayerSetting(i, "Formations");
     115           0 :                 if (formations)
     116           0 :                         cmpPlayer.SetFormations(formations);
     117             : 
     118           0 :                 const startCam = getPlayerSetting(i, "StartingCamera");
     119           0 :                 if (startCam)
     120           0 :                         cmpPlayer.SetStartingCamera(startCam.Position, startCam.Rotation);
     121             :         }
     122             : 
     123             :         // NOTE: We need to do the team locking here, as otherwise
     124             :         // SetTeam can't ally the players.
     125           0 :         if (settings.LockTeams)
     126           0 :                 for (let i = 0; i < numPlayers; ++i)
     127           0 :                         QueryPlayerIDInterface(i).SetLockTeams(true);
     128             : }
     129             : 
     130             : function GetPlayerTemplateName(civ)
     131             : {
     132           0 :         return "special/players/" + civ;
     133             : }
     134             : 
     135             : /**
     136             :  * @param id An entity's ID
     137             :  * @returns The entity ID of the owner player (not his player ID) or ent if ent is a player entity.
     138             :  */
     139             : function QueryOwnerEntityID(ent)
     140             : {
     141          37 :         let cmpPlayer = Engine.QueryInterface(ent, IID_Player);
     142          37 :         if (cmpPlayer)
     143           3 :                 return ent;
     144             : 
     145          34 :         let cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
     146          34 :         if (!cmpOwnership)
     147           6 :                 return null;
     148             : 
     149          28 :         let owner = cmpOwnership.GetOwner();
     150          28 :         if (owner == INVALID_PLAYER)
     151           0 :                 return null;
     152             : 
     153          28 :         let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     154          28 :         if (!cmpPlayerManager)
     155           0 :                 return null;
     156             : 
     157          28 :         return cmpPlayerManager.GetPlayerByID(owner);
     158             : }
     159             : 
     160             : /**
     161             :  * Similar to Engine.QueryInterface but applies to the player entity
     162             :  * that owns the given entity.
     163             :  * iid is typically IID_Player.
     164             :  */
     165             : function QueryOwnerInterface(ent, iid = IID_Player)
     166             : {
     167         372 :         var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
     168         372 :         if (!cmpOwnership)
     169           2 :                 return null;
     170             : 
     171         370 :         var owner = cmpOwnership.GetOwner();
     172         370 :         if (owner == INVALID_PLAYER)
     173           1 :                 return null;
     174             : 
     175         369 :         return QueryPlayerIDInterface(owner, iid);
     176             : }
     177             : 
     178             : /**
     179             :  * Similar to Engine.QueryInterface but applies to the player entity
     180             :  * with the given ID number.
     181             :  * iid is typically IID_Player.
     182             :  */
     183             : function QueryPlayerIDInterface(id, iid = IID_Player)
     184             : {
     185         630 :         var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     186             : 
     187         630 :         var playerEnt = cmpPlayerManager.GetPlayerByID(id);
     188         630 :         if (!playerEnt)
     189           0 :                 return null;
     190             : 
     191         630 :         return Engine.QueryInterface(playerEnt, iid);
     192             : }
     193             : 
     194             : /**
     195             :  * Similar to Engine.QueryInterface but first checks if the entity
     196             :  * mirages the interface.
     197             :  */
     198             : function QueryMiragedInterface(ent, iid)
     199             : {
     200         612 :         let cmpMirage = Engine.QueryInterface(ent, IID_Mirage);
     201         612 :         if (cmpMirage && !cmpMirage.Mirages(iid))
     202           0 :                 return null;
     203         612 :         else if (!cmpMirage)
     204         612 :                 return Engine.QueryInterface(ent, iid);
     205             : 
     206           0 :         return cmpMirage.Get(iid);
     207             : }
     208             : 
     209             : /**
     210             :  * Similar to Engine.QueryInterface, but checks for all interfaces
     211             :  * implementing a builder list (currently Foundation and Repairable)
     212             :  * TODO Foundation and Repairable could both implement a BuilderList component
     213             :  */
     214             : function QueryBuilderListInterface(ent)
     215             : {
     216           4 :         return Engine.QueryInterface(ent, IID_Foundation) || Engine.QueryInterface(ent, IID_Repairable);
     217             : }
     218             : 
     219             : /**
     220             :  * Returns true if the entity 'target' is owned by an ally of
     221             :  * the owner of 'entity'.
     222             :  */
     223             : function IsOwnedByAllyOfEntity(entity, target)
     224             : {
     225           0 :         return IsOwnedByEntityHelper(entity, target, "IsAlly");
     226             : }
     227             : 
     228             : function IsOwnedByMutualAllyOfEntity(entity, target)
     229             : {
     230          78 :         return IsOwnedByEntityHelper(entity, target, "IsMutualAlly");
     231             : }
     232             : 
     233             : function IsOwnedByEntityHelper(entity, target, check)
     234             : {
     235             :         // Figure out which player controls us
     236          78 :         let owner = 0;
     237          78 :         let cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
     238          78 :         if (cmpOwnership)
     239          78 :                 owner = cmpOwnership.GetOwner();
     240             : 
     241             :         // Figure out which player controls the target entity
     242          78 :         let targetOwner = 0;
     243          78 :         let cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
     244          78 :         if (cmpOwnershipTarget)
     245          78 :                 targetOwner = cmpOwnershipTarget.GetOwner();
     246             : 
     247          78 :         let cmpPlayer = QueryPlayerIDInterface(owner);
     248             : 
     249          78 :         return cmpPlayer && cmpPlayer[check](targetOwner);
     250             : }
     251             : 
     252             : /**
     253             :  * Returns true if the entity 'target' is owned by player
     254             :  */
     255             : function IsOwnedByPlayer(player, target)
     256             : {
     257           0 :         var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
     258           0 :         return cmpOwnershipTarget && player == cmpOwnershipTarget.GetOwner();
     259             : }
     260             : 
     261             : function IsOwnedByGaia(target)
     262             : {
     263           0 :         return IsOwnedByPlayer(0, target);
     264             : }
     265             : 
     266             : /**
     267             :  * Returns true if the entity 'target' is owned by an ally of player
     268             :  */
     269             : function IsOwnedByAllyOfPlayer(player, target)
     270             : {
     271          23 :         return IsOwnedByHelper(player, target, "IsAlly");
     272             : }
     273             : 
     274             : function IsOwnedByMutualAllyOfPlayer(player, target)
     275             : {
     276           0 :         return IsOwnedByHelper(player, target, "IsMutualAlly");
     277             : }
     278             : 
     279             : function IsOwnedByNeutralOfPlayer(player, target)
     280             : {
     281           0 :         return IsOwnedByHelper(player, target, "IsNeutral");
     282             : }
     283             : 
     284             : function IsOwnedByEnemyOfPlayer(player, target)
     285             : {
     286           0 :         return IsOwnedByHelper(player, target, "IsEnemy");
     287             : }
     288             : 
     289             : function IsOwnedByHelper(player, target, check)
     290             : {
     291          23 :         let targetOwner = 0;
     292          23 :         let cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership);
     293          23 :         if (cmpOwnershipTarget)
     294          23 :                 targetOwner = cmpOwnershipTarget.GetOwner();
     295             : 
     296          23 :         let cmpPlayer = QueryPlayerIDInterface(player);
     297             : 
     298          23 :         return cmpPlayer && cmpPlayer[check](targetOwner);
     299             : }
     300             : 
     301          36 : Engine.RegisterGlobal("LoadPlayerSettings", LoadPlayerSettings);
     302          36 : Engine.RegisterGlobal("QueryOwnerEntityID", QueryOwnerEntityID);
     303          36 : Engine.RegisterGlobal("QueryOwnerInterface", QueryOwnerInterface);
     304          36 : Engine.RegisterGlobal("QueryPlayerIDInterface", QueryPlayerIDInterface);
     305          36 : Engine.RegisterGlobal("QueryMiragedInterface", QueryMiragedInterface);
     306          36 : Engine.RegisterGlobal("QueryBuilderListInterface", QueryBuilderListInterface);
     307          36 : Engine.RegisterGlobal("IsOwnedByAllyOfEntity", IsOwnedByAllyOfEntity);
     308          36 : Engine.RegisterGlobal("IsOwnedByMutualAllyOfEntity", IsOwnedByMutualAllyOfEntity);
     309          36 : Engine.RegisterGlobal("IsOwnedByPlayer", IsOwnedByPlayer);
     310          36 : Engine.RegisterGlobal("IsOwnedByGaia", IsOwnedByGaia);
     311          36 : Engine.RegisterGlobal("IsOwnedByAllyOfPlayer", IsOwnedByAllyOfPlayer);
     312          36 : Engine.RegisterGlobal("IsOwnedByMutualAllyOfPlayer", IsOwnedByMutualAllyOfPlayer);
     313          36 : Engine.RegisterGlobal("IsOwnedByNeutralOfPlayer", IsOwnedByNeutralOfPlayer);
     314          36 : Engine.RegisterGlobal("IsOwnedByEnemyOfPlayer", IsOwnedByEnemyOfPlayer);

Generated by: LCOV version 1.14