Ticket #1807: garrison.patch
File garrison.patch, 24.1 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/gui/session/utility_functions.js
62 62 "teamsLocked": playerState.teamsLocked, 63 63 "state": playerState.state, 64 64 "isAlly": playerState.isAlly, 65 "isMutualAlly": playerState.isMutualAlly, 65 66 "isNeutral": playerState.isNeutral, 66 67 "isEnemy": playerState.isEnemy, 67 68 "guid": undefined, // network guid for players controlled by hosts -
binaries/data/mods/public/gui/session/input.js
206 206 var playerState = simState.players[entState.player]; 207 207 var playerOwned = (targetState.player == entState.player); 208 208 var allyOwned = playerState.isAlly[targetState.player]; 209 var mutualAllyOwned = playerState.isMutualAlly[targetState.player]; 209 210 var enemyOwned = playerState.isEnemy[targetState.player]; 210 211 var gaiaOwned = (targetState.player == 0); 211 212 … … 214 215 215 216 // default to walking there 216 217 var data = {command: "walk"}; 217 if (targetState.garrisonHolder && playerOwned)218 if (targetState.garrisonHolder && (playerOwned || mutualAllyOwned)) 218 219 { 219 220 data.command = "garrison"; 220 221 data.target = target; … … 286 287 var playerState = simState.players[entState.player]; 287 288 var playerOwned = (targetState.player == entState.player); 288 289 var allyOwned = playerState.isAlly[targetState.player]; 290 var mutualAllyOwned = playerState.isMutualAlly[targetState.player]; 289 291 var neutralOwned = playerState.isNeutral[targetState.player]; 290 292 var enemyOwned = playerState.isEnemy[targetState.player]; 291 293 var gaiaOwned = (targetState.player == 0); … … 297 299 switch (action) 298 300 { 299 301 case "garrison": 300 if (hasClass(entState, "Unit") && targetState.garrisonHolder && playerOwned)302 if (hasClass(entState, "Unit") && targetState.garrisonHolder && (playerOwned || mutualAllyOwned)) 301 303 { 302 304 var allowedClasses = targetState.garrisonHolder.allowedClasses; 303 305 for each (var unitClass in entState.identity.classes) … … 1677 1679 var unitName = getEntityName(template); 1678 1680 1679 1681 var playerID = Engine.GetPlayerID(); 1682 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 1683 1680 1684 if (entState.player == playerID || g_DevSettings.controlAll) 1681 1685 { 1682 1686 switch (commandName) … … 1725 1729 break; 1726 1730 } 1727 1731 } 1732 else if (simState.players[playerID].isMutualAlly[entState.player]) 1733 { 1734 switch (commandName) 1735 { 1736 case "garrison": 1737 inputState = INPUT_PRESELECTEDACTION; 1738 preSelectedAction = ACTION_GARRISON; 1739 break; 1740 //case "unload-all": 1741 // unloadAll(); 1742 // break; 1743 default: 1744 break; 1745 } 1746 } 1728 1747 } 1729 1748 } 1730 1749 -
binaries/data/mods/public/gui/session/unit_commands.js
670 670 button.tooltip += "\n" + GetTechnologyData(entType).requirementsTooltip; 671 671 grayscale = "grayscale:"; 672 672 } 673 674 if (guiName == GARRISON) 675 { 676 var ents = garrisonGroups.getEntsByName(item); 677 var entplayer = GetEntityState(ents[0]).player; 678 button.sprite = "colour: " + g_Players[entplayer].color.r + " " + g_Players[entplayer].color.g + " " + g_Players[entplayer].color.b; 679 680 var player = Engine.GetPlayerID(); 681 if(player != unitEntState.player && !g_DevSettings.controlAll) 682 { 683 if (entplayer != player) 684 { 685 button.enabled = false; 686 grayscale = "grayscale:"; 687 } 688 } 689 } 673 690 674 691 icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 675 692 … … 964 981 965 982 // If the selection is friendly units, add the command panels 966 983 var player = Engine.GetPlayerID(); 967 if (entState.player == player || g_DevSettings.controlAll) 968 { 969 // Get player state to check some constraints 970 // e.g. presence of a hero or build limits 971 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 972 var playerState = simState.players[player]; 984 // Get player state to check some constraints 985 // e.g. presence of a hero or build limits 986 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 987 var playerState = simState.players[player]; 973 988 989 if (entState.player == player || g_DevSettings.controlAll) 990 { 991 974 992 if (selection.length > 1) 975 993 setupUnitPanel(SELECTION, usedPanels, entState, playerState, g_Selection.groups.getTemplateNames(), 976 994 function (entType) { changePrimarySelectionGroup(entType); } ); … … 985 1003 var groups = new EntityGroups(); 986 1004 for (var i in selection) 987 1005 { 988 state = GetEntityState(selection[i]);1006 var state = GetEntityState(selection[i]); 989 1007 if (state.garrisonHolder) 990 1008 groups.add(state.garrisonHolder.entities) 991 1009 } … … 1152 1170 supplementalDetailsPanel.hidden = false; 1153 1171 commandsPanel.hidden = false; 1154 1172 } 1173 else if (playerState.isMutualAlly[entState.player]) // owned by allied player 1174 { 1175 1176 if (entState.garrisonHolder) 1177 { 1178 var groups = new EntityGroups(); 1179 for (var i in selection) 1180 { 1181 var state = GetEntityState(selection[i]); 1182 if (state.garrisonHolder) 1183 groups.add(state.garrisonHolder.entities) 1184 } 1185 1186 setupUnitPanel(GARRISON, usedPanels, entState, playerState, groups.getTemplateNames(), 1187 function (item) { unloadTemplate(item); } ); 1188 1189 supplementalDetailsPanel.hidden = false; 1190 } 1191 else 1192 { 1193 supplementalDetailsPanel.hidden = true; 1194 } 1195 1196 commandsPanel.hidden = true; 1197 } 1155 1198 else // owned by another player 1156 1199 { 1157 1200 supplementalDetailsPanel.hidden = true; -
binaries/data/mods/public/simulation/helpers/Player.js
207 207 if (cmpOwnership) 208 208 owner = cmpOwnership.GetOwner(); 209 209 210 // Figure out which player controls the foundation being built210 // Figure out which player controls the target entity 211 211 var targetOwner = 0; 212 212 var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership); 213 213 if (cmpOwnershipTarget) … … 224 224 } 225 225 226 226 /** 227 * Returns true if the entity 'target' is owned by a mutual ally of 228 * the owner of 'entity'. 229 */ 230 function IsOwnedByMutualAllyOfEntity(entity, target) 231 { 232 // Figure out which player controls us 233 var owner = 0; 234 var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership); 235 if (cmpOwnership) 236 owner = cmpOwnership.GetOwner(); 237 238 // Figure out which player controls the target entity 239 var targetOwner = 0; 240 var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership); 241 if (cmpOwnershipTarget) 242 targetOwner = cmpOwnershipTarget.GetOwner(); 243 244 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 245 var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(owner), IID_Player); 246 247 // Check for allied diplomacy status 248 if (cmpPlayer.IsMutualAlly(targetOwner)) 249 return true; 250 251 return false; 252 } 253 254 /** 227 255 * Returns true if the entity 'target' is owned by player 228 256 */ 229 257 function IsOwnedByPlayer(player, target) … … 262 290 } 263 291 264 292 /** 293 * Returns true if the entity 'target' is owned by a mutual ally of player 294 */ 295 function IsOwnedByMutualAllyOfPlayer(player, target) 296 { 297 var targetOwner = 0; 298 var cmpOwnershipTarget = Engine.QueryInterface(target, IID_Ownership); 299 if (cmpOwnershipTarget) 300 targetOwner = cmpOwnershipTarget.GetOwner(); 301 302 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 303 var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(player), IID_Player); 304 305 // Check for allied diplomacy status 306 if (cmpPlayer.IsMutualAlly(targetOwner)) 307 return true; 308 309 return false; 310 } 311 312 /** 265 313 * Returns true if the entity 'target' is owned by someone neutral to player 266 314 */ 267 315 function IsOwnedByNeutralOfPlayer(player,target) … … 305 353 Engine.RegisterGlobal("QueryOwnerInterface", QueryOwnerInterface); 306 354 Engine.RegisterGlobal("QueryPlayerIDInterface", QueryPlayerIDInterface); 307 355 Engine.RegisterGlobal("IsOwnedByAllyOfEntity", IsOwnedByAllyOfEntity); 356 Engine.RegisterGlobal("IsOwnedByMutualAllyOfEntity", IsOwnedByMutualAllyOfEntity); 308 357 Engine.RegisterGlobal("IsOwnedByPlayer", IsOwnedByPlayer); 309 358 Engine.RegisterGlobal("IsOwnedByGaia", IsOwnedByGaia); 310 359 Engine.RegisterGlobal("IsOwnedByAllyOfPlayer", IsOwnedByAllyOfPlayer); 360 Engine.RegisterGlobal("IsOwnedByMutualAllyOfPlayer", IsOwnedByMutualAllyOfPlayer); 311 361 Engine.RegisterGlobal("IsOwnedByNeutralOfPlayer", IsOwnedByNeutralOfPlayer); 312 362 Engine.RegisterGlobal("IsOwnedByEnemyOfPlayer", IsOwnedByEnemyOfPlayer); -
binaries/data/mods/public/simulation/helpers/Commands.js
82 82 break; 83 83 84 84 case "walk": 85 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);85 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 86 86 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 87 87 cmpUnitAI.Walk(cmd.x, cmd.z, cmd.queued); 88 88 }); … … 96 96 } 97 97 98 98 // See UnitAI.CanAttack for target checks 99 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);99 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 100 100 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 101 101 cmpUnitAI.Attack(cmd.target, cmd.queued); 102 102 }); … … 109 109 warn("Invalid command: heal target is not owned by player "+player+" or their ally: "+uneval(cmd)); 110 110 } 111 111 112 // See UnitAI.CanHeal for target checks 113 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);112 // See UnitAI.CanHeal for target checks TODO may-be the includeMutualAllies should be set to true in FilterEntityList 113 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 114 114 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 115 115 cmpUnitAI.Heal(cmd.target, cmd.queued); 116 116 }); … … 124 124 warn("Invalid command: repair target is not owned by ally of player "+player+": "+uneval(cmd)); 125 125 } 126 126 127 // See UnitAI.CanRepair for target checks 128 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);127 // See UnitAI.CanRepair for target checks TODO may-be the includeMutualAllies should be set to true in FilterEntityList 128 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 129 129 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 130 130 cmpUnitAI.Repair(cmd.target, cmd.autocontinue, cmd.queued); 131 131 }); … … 139 139 } 140 140 141 141 // See UnitAI.CanGather for target checks 142 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);142 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 143 143 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 144 144 cmpUnitAI.Gather(cmd.target, cmd.queued); 145 145 }); 146 146 break; 147 147 148 148 case "gather-near-position": 149 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);149 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 150 150 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 151 151 cmpUnitAI.GatherNearPosition(cmd.x, cmd.z, cmd.resourceType, cmd.resourceTemplate, cmd.queued); 152 152 }); … … 161 161 } 162 162 163 163 // See UnitAI.CanReturnResource for target checks 164 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);164 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 165 165 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 166 166 cmpUnitAI.ReturnResource(cmd.target, cmd.queued); 167 167 }); 168 168 break; 169 169 170 170 case "train": 171 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);171 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 172 172 173 173 // Check entity limits 174 174 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); … … 216 216 217 217 case "research": 218 218 // Verify that the building can be controlled by the player 219 if (CanControlUnit(cmd.entity, player, controlAllUnits))219 if (CanControlUnit(cmd.entity, player, false, controlAllUnits)) 220 220 { 221 221 var cmpTechnologyManager = QueryOwnerInterface(cmd.entity, IID_TechnologyManager); 222 222 // TODO: Enable this check once the AI gets technology support … … 239 239 240 240 case "stop-production": 241 241 // Verify that the building can be controlled by the player 242 if (CanControlUnit(cmd.entity, player, controlAllUnits))242 if (CanControlUnit(cmd.entity, player, false, controlAllUnits)) 243 243 { 244 244 var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue); 245 245 if (queue) … … 260 260 break; 261 261 262 262 case "delete-entities": 263 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);263 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 264 264 for each (var ent in entities) 265 265 { 266 266 var cmpHealth = Engine.QueryInterface(ent, IID_Health); … … 276 276 break; 277 277 278 278 case "set-rallypoint": 279 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);279 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 280 280 for each (var ent in entities) 281 281 { 282 282 var cmpRallyPoint = Engine.QueryInterface(ent, IID_RallyPoint); … … 292 292 break; 293 293 294 294 case "unset-rallypoint": 295 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);295 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 296 296 for each (var ent in entities) 297 297 { 298 298 var cmpRallyPoint = Engine.QueryInterface(ent, IID_RallyPoint); … … 308 308 309 309 case "garrison": 310 310 // Verify that the building can be controlled by the player 311 if (CanControlUnit(cmd.target, player, controlAllUnits))311 if (CanControlUnit(cmd.target, player, true, controlAllUnits)) 312 312 { 313 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);313 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 314 314 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 315 315 cmpUnitAI.Garrison(cmd.target, cmd.queued); 316 316 }); … … 322 322 break; 323 323 324 324 case "stop": 325 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);325 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 326 326 GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) { 327 327 cmpUnitAI.Stop(cmd.queued); 328 328 }); … … 330 330 331 331 case "unload": 332 332 // Verify that the building can be controlled by the player 333 if (CanControlUnit(cmd.garrisonHolder, player, controlAllUnits))333 if (CanControlUnit(cmd.garrisonHolder, player, true, controlAllUnits)) 334 334 { 335 335 var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder); 336 336 var notUngarrisoned = 0; 337 for each (ent in cmd.entities) 337 var entities = FilterEntityList(cmd.entities, player, IsOwnedByPlayer(player, cmd.garrisonHolder), controlAllUnits); 338 for each (var ent in entities) 338 339 if (!cmpGarrisonHolder || !cmpGarrisonHolder.Unload(ent)) 339 340 notUngarrisoned++; 340 341 … … 348 349 break; 349 350 350 351 case "unload-template": 351 var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits); 352 var selected = FilterEntityList(cmd.garrisonHolders, player, true, controlAllUnits); 353 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 352 354 for each (var garrisonHolder in selected) 353 355 { 354 356 var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder); 355 if (!cmpGarrisonHolder || !cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all)) 356 notifyUnloadFailure(player, garrisonHolder) 357 if (cmpGarrisonHolder) 358 { 359 // check that we are allowed to unload entities corresponding to this template 360 var entities = FilterEntityList(cmpGarrisonHolder.entities, player, IsOwnedByPlayer(player, garrisonHolder), controlAllUnits); 361 for each (var ent in entities) 362 { 363 // Units with multiple ranks are grouped together. 364 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 365 var name = cmpIdentity.GetSelectionGroupName(); 366 if (!name) 367 name = cmpTemplateManager.GetCurrentTemplateName(ent); 368 if (name == cmd.template) 369 { 370 if (!cmpGarrisonHolder.UnloadTemplate(cmd.template, cmd.all)) 371 notifyUnloadFailure(player, garrisonHolder); 372 break; 373 } 374 } 375 } 357 376 } 358 377 break; 359 378 360 379 case "unload-all": 361 var selected = FilterEntityList(cmd.garrisonHolders, player, controlAllUnits);380 var selected = FilterEntityList(cmd.garrisonHolders, player, false, controlAllUnits); 362 381 for each (var garrisonHolder in selected) 363 382 { 364 383 var cmpGarrisonHolder = Engine.QueryInterface(garrisonHolder, IID_GarrisonHolder); … … 368 387 break; 369 388 370 389 case "formation": 371 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);390 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 372 391 GetFormationUnitAIs(entities, player, cmd.name).forEach(function(cmpUnitAI) { 373 392 cmpUnitAI.MoveIntoFormation(cmd); 374 393 }); … … 388 407 break; 389 408 390 409 case "stance": 391 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);410 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 392 411 for each (var ent in entities) 393 412 { 394 413 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); … … 398 417 break; 399 418 400 419 case "wall-to-gate": 401 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);420 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 402 421 for each (var ent in entities) 403 422 { 404 423 TryTransformWallToGate(ent, cmpPlayer, cmd.template); … … 406 425 break; 407 426 408 427 case "lock-gate": 409 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);428 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 410 429 for each (var ent in entities) 411 430 { 412 431 var cmpGate = Engine.QueryInterface(ent, IID_Gate); … … 454 473 break; 455 474 456 475 case "pack": 457 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);476 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 458 477 for each (var ent in entities) 459 478 { 460 479 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); … … 469 488 break; 470 489 471 490 case "cancel-pack": 472 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);491 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 473 492 for each (var ent in entities) 474 493 { 475 494 var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); … … 558 577 */ 559 578 560 579 // Check whether we can control these units 561 var entities = FilterEntityList(cmd.entities, player, controlAllUnits);580 var entities = FilterEntityList(cmd.entities, player, false, controlAllUnits); 562 581 if (!entities.length) 563 582 return false; 564 583 … … 1181 1200 1182 1201 /** 1183 1202 * Check if player can control this entity 1184 * returns: true if the entity is valid and owned by the player if 1203 * returns: true if the entity is valid and owned by the player 1204 * or includeMutualAllies is true and the entity is owned by an ally 1185 1205 * or control all units is activated for the player, else false 1186 1206 */ 1187 function CanControlUnit(entity, player, controlAll)1207 function CanControlUnit(entity, player, includeMutualAllies, controlAll) 1188 1208 { 1189 return (IsOwnedByPlayer(player, entity) || controlAll);1209 return (IsOwnedByPlayer(player, entity) || (includeMutualAllies && IsOwnedByMutualAllyOfPlayer(player, entity)) || controlAll); 1190 1210 } 1191 1211 1192 1212 /** 1193 1213 * Filter entities which the player can control 1194 1214 */ 1195 function FilterEntityList(entities, player, controlAll)1215 function FilterEntityList(entities, player, includeMutualAllies, controlAll) 1196 1216 { 1197 return entities.filter(function(ent) { return CanControlUnit(ent, player, controlAll);} );1217 return entities.filter(function(ent) { return CanControlUnit(ent, player, includeMutualAllies, controlAll);} ); 1198 1218 } 1199 1219 1200 1220 /** -
binaries/data/mods/public/simulation/components/GuiInterface.js
64 64 65 65 // store player ally/neutral/enemy data as arrays 66 66 var allies = []; 67 var mutualAllies = []; 67 68 var neutrals = []; 68 69 var enemies = []; 69 70 for (var j = 0; j < n; ++j) 70 71 { 71 72 allies[j] = cmpPlayer.IsAlly(j); 73 mutualAllies[j] = cmpPlayer.IsMutualAlly(j); 72 74 neutrals[j] = cmpPlayer.IsNeutral(j); 73 75 enemies[j] = cmpPlayer.IsEnemy(j); 74 76 } … … 86 88 "teamsLocked": cmpPlayer.GetLockTeams(), 87 89 "phase": phase, 88 90 "isAlly": allies, 91 "isMutualAlly": mutualAllies, 89 92 "isNeutral": neutrals, 90 93 "isEnemy": enemies, 91 94 "entityLimits": cmpPlayerEntityLimits.GetLimits(), -
binaries/data/mods/public/simulation/components/GarrisonHolder.js
477 477 } 478 478 }; 479 479 480 481 /** 482 * Eject all foreign garrisoned entities which are no more allied 483 */ 484 GarrisonHolder.prototype.OnDiplomacyChanged = function() 485 { 486 for (var i = this.entities.length; i > 0; --i) 487 { 488 if (!IsOwnedByMutualAllyOfEntity(this.entity, this.entities[i-1])) 489 this.Eject(this.entities[i-1], true); 490 } 491 this.UpdateGarrisonFlag(); 492 }; 493 480 494 Engine.RegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder); 481 495 -
binaries/data/mods/public/simulation/components/UnitAI.js
3956 3956 if (!cmpGarrisonHolder) 3957 3957 return false; 3958 3958 3959 // Verify that the target is owned by this entity's player 3959 // Verify that the target is owned by this entity's player or is mutual allied 3960 3960 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 3961 if (!cmpOwnership || ! IsOwnedByPlayer(cmpOwnership.GetOwner(), target))3961 if (!cmpOwnership || !(IsOwnedByPlayer(cmpOwnership.GetOwner(), target) || IsOwnedByMutualAllyOfPlayer(cmpOwnership.GetOwner(), target))) 3962 3962 return false; 3963 3963 3964 3964 // Don't let animals garrison for now -
binaries/data/mods/public/simulation/components/Player.js
337 337 338 338 var sharedLos = []; 339 339 for (var i = 0; i < cmpPlayerManager.GetNumPlayers(); ++i) 340 if (this.IsAlly(i)) 341 { 342 var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(i), IID_Player); 343 if (cmpPlayer && cmpPlayer.IsAlly(this.playerID)) 344 sharedLos.push(i); 345 } 340 if (this.IsMutualAlly(i)) 341 sharedLos.push(i); 346 342 347 343 cmpRangeManager.SetSharedLos(this.playerID, sharedLos); 348 344 }; … … 410 406 return this.diplomacy[id] > 0; 411 407 }; 412 408 409 /** 410 * Check if given player is our ally, and we are its ally 411 */ 412 Player.prototype.IsMutualAlly = function(id) 413 { 414 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 415 if (!cmpPlayerManager) 416 return false; 417 var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(id), IID_Player); 418 return this.IsAlly(id) && cmpPlayer && cmpPlayer.IsAlly(this.playerID); 419 }; 420 413 421 Player.prototype.SetEnemy = function(id) 414 422 { 415 423 this.SetDiplomacyIndex(id, -1);