Ticket #3488: 3488.15.diff
File 3488.15.diff, 12.8 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/simulation/components/BuildingAI.js
37 37 for (let ent of msg.added) 38 38 { 39 39 let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 40 if ( !cmpIdentity)40 if (msg.visible[ent] || !cmpIdentity) 41 41 continue; 42 42 if (MatchesClassList(cmpIdentity.GetClassesList(), classes)) 43 43 ++this.archersGarrisoned; … … 46 46 for (let ent of msg.removed) 47 47 { 48 48 let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 49 if ( !cmpIdentity)49 if (msg.visible[ent] || !cmpIdentity) 50 50 continue; 51 51 if (MatchesClassList(cmpIdentity.GetClassesList(), classes)) 52 52 --this.archersGarrisoned; -
binaries/data/mods/public/simulation/components/GarrisonHolder.js
1 /** 2 * @class Defines an entity's ability to garrison units. 3 */ 1 4 function GarrisonHolder() {} 2 5 3 6 GarrisonHolder.prototype.Schema = … … 45 48 "<element name='Z'>" + 46 49 "<data type='decimal'/>" + 47 50 "</element>" + 51 "<element name='VisibleGarrisonAllowedClasses'>" + 52 "<attribute name='datatype'>" + 53 "<value>tokens</value>" + 54 "</attribute>" + 55 "<text/>" + 56 "</element>" + 48 57 "</interleave>" + 49 58 "</element>" + 50 59 "</zeroOrMore>" + … … 72 81 o.x = +offset.X; 73 82 o.y = +offset.Y; 74 83 o.z = +offset.Z; 75 this.visibleGarrisonPoints.push({ "offset":o, "entity": null});84 this.visibleGarrisonPoints.push({ "offset": o, "entity": null, "allowedClass": offset.VisibleGarrisonAllowedClasses }); 76 85 } 77 86 } 78 87 }; … … 100 109 return IsOwnedByPlayer(player, ent); 101 110 }; 102 111 103 104 112 /** 105 113 * Return the list of entities garrisoned inside 106 114 */ … … 204 212 }; 205 213 206 214 /** 215 * Returns true if the unit is allowed be visible on that garrison point, false otherwise. 216 */ 217 GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(visibleGarrisonPoint, entity) 218 { 219 return MatchesClassList(Engine.QueryInterface(entity, IID_Identity).GetClassesList(), visibleGarrisonPoint.allowedClass._string); 220 }; 221 222 /** 207 223 * Garrison a unit inside. 208 224 * Returns true if successful, false if not 209 225 * The timer for AutoHeal is started here … … 225 241 { 226 242 if (vgp.entity) 227 243 continue; 228 visibleGarrisonPoint = vgp; 229 break; 244 if (this.AllowedToVisibleGarrisoning(vgp, entity)) 245 { 246 visibleGarrisonPoint = vgp; 247 break; 248 } 230 249 } 231 250 } 232 233 if (visibleGarrisonPoint) 251 if (visibleGarrisonPoint && this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity)) 234 252 { 235 253 visibleGarrisonPoint.entity = entity; 236 254 cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); … … 241 259 else 242 260 cmpPosition.MoveOutOfWorld(); 243 261 262 let visible = {}; 263 visible[entity] = this.IsVisiblyGarrisoned(entity); 264 // Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet. 265 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 266 "added": [entity], 267 "removed": [], 268 "visible": visible 269 }); 244 270 return true; 245 271 }; 246 272 273 /** 274 * Garrison units inside the entity 275 * @return true if successful, false if not 276 */ 247 277 GarrisonHolder.prototype.PerformGarrison = function(entity) 248 278 { 249 279 if (!this.HasEnoughHealth()) … … 250 280 return false; 251 281 252 282 // Check if the unit is allowed to be garrisoned inside the building 253 if (!this.AllowedToGarrison(entity))283 if (!this.AllowedToGarrison(entity)) 254 284 return false; 255 285 256 // check the capacity286 // Check the capacity 257 287 var extraCount = 0; 258 288 var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder); 259 289 if (cmpGarrisonHolder) … … 278 308 if (cmpAura && cmpAura.HasGarrisonAura()) 279 309 cmpAura.ApplyGarrisonBonus(this.entity); 280 310 281 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });282 283 311 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 284 312 if (cmpUnitAI && cmpUnitAI.IsUnderAlert()) 285 313 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity}); … … 326 354 327 355 var cmpNewPosition = Engine.QueryInterface(entity, IID_Position); 328 356 this.entities.splice(entityIndex, 1); 329 357 358 let visible = {}; 359 visible[entity] = this.IsVisiblyGarrisoned(entity); 360 // Should only be called before the ejection has been performed else the visible Garrison Points will be empty. 361 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 362 "added": [], 363 "removed": [entity], 364 "visible": visible 365 }); 330 366 for (var vgp of this.visibleGarrisonPoints) 331 367 { 332 368 if (vgp.entity != entity) … … 356 392 cmpNewPosition.SetHeightOffset(0); 357 393 // TODO: what direction should they face in? 358 394 359 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });360 395 361 396 return true; 362 397 }; … … 454 489 */ 455 490 GarrisonHolder.prototype.UnloadTemplate = function(extendedTemplate, all, forced) 456 491 { 457 varindex = extendedTemplate.indexOf("&");492 let index = extendedTemplate.indexOf("&"); 458 493 if (index == -1) 459 494 return false; 460 495 461 var owner = +extendedTemplate.slice(1,index); 462 var template = extendedTemplate.slice(index+1); 496 let entities = []; 497 let visibleEntities = []; 498 let entitiesMatching = []; 499 let entitiesNotOwned = []; 500 let entitiesNotMatchingName = []; 501 let owner = +extendedTemplate.slice(1, index); 502 let template = extendedTemplate.slice(index + 1); 503 let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 463 504 464 var entities = []; 465 var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 466 for each (var entity in this.entities) 467 { 468 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 505 entitiesNotOwned= this.entities.filter(e => Engine.QueryInterface(e, IID_Ownership).GetOwner() != owner); 506 entitiesNotMatchingName = this.entities.filter(e => (Engine.QueryInterface(e, IID_Identity).GetSelectionGroupName() || cmpTemplateManager.GetCurrentTemplateName(e)) != template); 469 507 470 // Units with multiple ranks are grouped together.471 var name = cmpIdentity.GetSelectionGroupName()472 || cmpTemplateManager.GetCurrentTemplateName(entity);508 for (let entity of this.entities) 509 if(!entitiesNotOwned.some(e=> e == entity) && ! entitiesNotMatchingName.some(e=> e == entity)) 510 entitiesMatching.push(entity); 473 511 474 if (name != template) 475 continue; 476 if (owner != Engine.QueryInterface(entity, IID_Ownership).GetOwner()) 477 continue; 512 for (let entity of entitiesMatching) 513 { 514 if (this.IsVisiblyGarrisoned(entity)) 515 visibleEntities.push(entity); 516 else 517 entities.push(entity); 478 518 479 entities.push(entity); 519 // If 'all' is false, only ungarrison the first matched unit and if possible, one that 's not visible. 520 if (!all) 521 { 522 if (!entities.length) 523 { 524 if (entitiesMatching.length !== visibleEntities.length) 525 continue; 480 526 481 // If 'all' is false, only ungarrison the first matched unit. 482 if (!all) 527 if (visibleEntities.length) 528 entities.push(visibleEntities[0]); 529 } 483 530 break; 531 } 484 532 } 485 533 if (all) 534 entities.push.apply(entities,visibleEntities); 486 535 return this.PerformEject(entities, forced); 487 536 }; 488 537 … … 612 661 } 613 662 614 663 // or on some of its garrisoned units 615 varentityIndex = this.entities.indexOf(msg.entity);664 let entityIndex = this.entities.indexOf(msg.entity); 616 665 if (entityIndex != -1) 617 666 { 618 667 // If the entity is dead, remove it directly instead of ejecting the corpse 619 varcmpHealth = Engine.QueryInterface(msg.entity, IID_Health);668 let cmpHealth = Engine.QueryInterface(msg.entity, IID_Health); 620 669 if (cmpHealth && cmpHealth.GetHitpoints() == 0) 621 670 { 622 671 this.entities.splice(entityIndex, 1); 623 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] }); 672 let visible = {}; 673 visible[msg.entity] = this.IsVisiblyGarrisoned(msg.entity); 674 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 675 "added": [], 676 "removed": [msg.entity], 677 "visible": visible 678 }); 624 679 this.UpdateGarrisonFlag(); 625 680 626 681 for (var pt of this.visibleGarrisonPoints) … … 634 689 635 690 /** 636 691 * Update list of garrisoned entities if one gets renamed (e.g. by promotion) 692 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint, 693 * in case of promotion for example, and thus should always be allowed. 637 694 */ 638 695 GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) 639 696 { … … 670 727 } 671 728 }; 672 729 673 674 730 /** 675 731 * Eject all foreign garrisoned entities which are no more allied 676 732 */ … … 687 743 GarrisonHolder.prototype.EjectOrKill = function(entities) 688 744 { 689 745 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 690 // Eject the units which can be ejected (if not in world, it generallymeans this holder746 // Eject the units which can be ejected (if not in world, it often means this holder 691 747 // is inside a holder which kills its entities, so do not eject) 692 748 if (cmpPosition.IsInWorld()) 693 749 { … … 710 766 this.entities.splice(entityIndex, 1); 711 767 killedEntities.push(entity); 712 768 } 713 714 769 if (killedEntities.length > 0) 715 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities }); 770 { 771 let visibleEntitiesIds = {}; 772 for (let ent of killedEntities) 773 visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent); 774 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 775 "added": [], 776 "removed": killedEntities, 777 "visible": visibleEntitiesIds 778 }); 779 } 716 780 this.UpdateGarrisonFlag(); 717 781 }; 718 782 719 783 /** 784 * Gives insight about the unit type of garrisoning. 785 * @return{bool} returns true if the unit is visible on the structure 786 * @param {int} the entity's id 787 */ 788 GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) 789 { 790 return this.visibleGarrisonPoints.some(point => point.entity == entity); 791 }; 792 793 /** 720 794 * Checks if an entity is ejectable on destroy if possible 721 795 */ 722 796 GarrisonHolder.prototype.IsEjectable = function(entity) -
binaries/data/mods/public/simulation/templates/template_structure_defense_wall_long.xml
20 20 <VisibleGarrisonPoints> 21 21 <Archer1> 22 22 <X>0</X><Y>11.5</Y><Z>0</Z> 23 <VisibleGarrisonAllowedClasses datatype="tokens"> 24 Infantry+Ranged 25 </VisibleGarrisonAllowedClasses> 23 26 </Archer1> 24 27 <Archer2> 25 28 <X>8</X><Y>11.5</Y><Z>0</Z> 29 <VisibleGarrisonAllowedClasses datatype="tokens"> 30 Infantry+Ranged 31 </VisibleGarrisonAllowedClasses> 26 32 </Archer2> 27 33 <Archer3> 28 34 <X>-8</X><Y>11.5</Y><Z>0</Z> 35 <VisibleGarrisonAllowedClasses datatype="tokens"> 36 Infantry+Ranged 37 </VisibleGarrisonAllowedClasses> 29 38 </Archer3> 30 39 <Archer4> 31 40 <X>4</X><Y>11.5</Y><Z>0</Z> 41 <VisibleGarrisonAllowedClasses datatype="tokens"> 42 Infantry+Ranged 43 </VisibleGarrisonAllowedClasses> 32 44 </Archer4> 33 45 <Archer5> 34 46 <X>-4</X><Y>11.5</Y><Z>0</Z> 47 <VisibleGarrisonAllowedClasses datatype="tokens"> 48 Infantry+Ranged 49 </VisibleGarrisonAllowedClasses> 35 50 </Archer5> 36 51 </VisibleGarrisonPoints> 37 52 </GarrisonHolder> -
binaries/data/mods/public/simulation/templates/template_structure_defense_wall_medium.xml
17 17 <VisibleGarrisonPoints> 18 18 <Archer1> 19 19 <X>0</X><Y>11.5</Y><Z>0</Z> 20 <VisibleGarrisonAllowedClasses datatype="tokens"> 21 Infantry+Ranged 22 </VisibleGarrisonAllowedClasses> 20 23 </Archer1> 21 24 <Archer2> 22 25 <X>4</X><Y>11.5</Y><Z>0</Z> 26 <VisibleGarrisonAllowedClasses datatype="tokens"> 27 Infantry+Ranged 28 </VisibleGarrisonAllowedClasses> 23 29 </Archer2> 24 30 <Archer3> 25 31 <X>-4</X><Y>11.5</Y><Z>0</Z> 32 <VisibleGarrisonAllowedClasses datatype="tokens"> 33 Infantry+Ranged 34 </VisibleGarrisonAllowedClasses> 26 35 </Archer3> 27 36 </VisibleGarrisonPoints> 28 37 </GarrisonHolder>