Ticket #3488: 3488.10.diff
File 3488.10.diff, 7.6 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/simulation/components/BuildingAI.js
36 36 37 37 for (let ent of msg.added) 38 38 { 39 let cmpIdentity = Engine.QueryInterface(ent , IID_Identity);40 if ( !cmpIdentity)39 let cmpIdentity = Engine.QueryInterface(ent.id, IID_Identity); 40 if (ent.visible || !cmpIdentity) 41 41 continue; 42 42 if (MatchesClassList(cmpIdentity.GetClassesList(), classes)) 43 43 ++this.archersGarrisoned; … … 45 45 46 46 for (let ent of msg.removed) 47 47 { 48 let cmpIdentity = Engine.QueryInterface(ent , IID_Identity);49 if ( !cmpIdentity)48 let cmpIdentity = Engine.QueryInterface(ent.id, IID_Identity); 49 if (ent.visible || !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 "<optional>" + 52 "<element name='VisibleGarrisonAllowedClasses'>" + 53 "<attribute name='datatype'>" + 54 "<value>tokens</value>" + 55 "</attribute>" + 56 "<text/>" + 57 "</element>" + 58 "</optional>" + 48 59 "</interleave>" + 49 60 "</element>" + 50 61 "</zeroOrMore>" + … … 72 83 o.x = +offset.X; 73 84 o.y = +offset.Y; 74 85 o.z = +offset.Z; 75 this.visibleGarrisonPoints.push({ "offset":o, "entity": null});86 this.visibleGarrisonPoints.push({ "offset": o, "entity": null, "allowedClass": offset.VisibleGarrisonAllowedClasses }); 76 87 } 77 88 } 78 89 }; … … 100 111 return IsOwnedByPlayer(player, ent); 101 112 }; 102 113 103 104 114 /** 105 115 * Return the list of entities garrisoned inside 106 116 */ … … 204 214 }; 205 215 206 216 /** 217 * Returns true if the unit is allowed be visible on that garrison point, false otherwise. 218 */ 219 GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(visibleGarrisonPoint, entity) 220 { 221 let allowedClassesList = visibleGarrisonPoint.allowedClass._string; 222 // If classlist is empty, everybody can garrison. 223 if (!allowedClassesList) 224 return true; 225 226 return MatchesClassList(Engine.QueryInterface(entity, IID_Identity).GetClassesList(), allowedClassesList); 227 }; 228 229 /** 207 230 * Garrison a unit inside. 208 231 * Returns true if successful, false if not 209 232 * The timer for AutoHeal is started here … … 229 252 break; 230 253 } 231 254 } 232 233 if (visibleGarrisonPoint) 255 if (visibleGarrisonPoint && this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity)) 234 256 { 235 257 visibleGarrisonPoint.entity = entity; 236 258 cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); … … 240 262 } 241 263 else 242 264 cmpPosition.MoveOutOfWorld(); 243 265 // Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet. 266 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 267 "added": [{ "id": entity, "visible": this.IsVisiblyGarrisoned(entity) }], 268 "removed": [] 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 // Should only be called before the ejection has been performed else the visible Garrison Points will be empty. 358 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 359 "added": [], 360 "removed": [{ "id": entity, "visible": this.IsVisiblyGarrisoned(entity) }] 361 }); 330 362 for (var vgp of this.visibleGarrisonPoints) 331 363 { 332 364 if (vgp.entity != entity) … … 356 388 cmpNewPosition.SetHeightOffset(0); 357 389 // TODO: what direction should they face in? 358 390 359 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });360 391 361 392 return true; 362 393 }; … … 620 651 if (cmpHealth && cmpHealth.GetHitpoints() == 0) 621 652 { 622 653 this.entities.splice(entityIndex, 1); 623 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] }); 654 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 655 "added": [], 656 "removed": [{ "id": msg.entity, "visible": this.IsVisiblyGarrisoned(msg.entity) }] 657 }); 624 658 this.UpdateGarrisonFlag(); 625 659 626 660 for (var pt of this.visibleGarrisonPoints) … … 634 668 635 669 /** 636 670 * Update list of garrisoned entities if one gets renamed (e.g. by promotion) 671 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint, 672 * in case of promotion for example, and thus should always be allowed. 637 673 */ 638 674 GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) 639 675 { … … 670 706 } 671 707 }; 672 708 673 674 709 /** 675 710 * Eject all foreign garrisoned entities which are no more allied 676 711 */ … … 687 722 GarrisonHolder.prototype.EjectOrKill = function(entities) 688 723 { 689 724 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 690 // Eject the units which can be ejected (if not in world, it generallymeans this holder725 // Eject the units which can be ejected (if not in world, it often means this holder 691 726 // is inside a holder which kills its entities, so do not eject) 692 727 if (cmpPosition.IsInWorld()) 693 728 { … … 710 745 this.entities.splice(entityIndex, 1); 711 746 killedEntities.push(entity); 712 747 } 713 714 748 if (killedEntities.length > 0) 715 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities }); 749 { 750 let killedEntitiesObjects = []; 751 for (let ent of killedEntities) 752 { 753 killedEntitiesObjects.push({"id": ent, "visible": this.IsVisiblyGarrisoned(ent)}); 754 } 755 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 756 "added": [], 757 "removed": killedEntitiesObjects 758 }); 759 } 716 760 this.UpdateGarrisonFlag(); 717 761 }; 718 762 719 763 /** 764 * Gives insight about the unit type of garrisoning. 765 * @return{bool} returns true if the unit is visible on the structure 766 * @param {int} the entity's id 767 */ 768 GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) 769 { 770 return this.visibleGarrisonPoints.some(point => point.entity === entity); 771 }; 772 773 /** 720 774 * Checks if an entity is ejectable on destroy if possible 721 775 */ 722 776 GarrisonHolder.prototype.IsEjectable = function(entity)