Ticket #3488: 3488.12.diff
File 3488.12.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 (msg.visible[ent] || !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 (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 "<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": [entity], 268 "removed": [], 269 "visible": { entity: this.IsVisiblyGarrisoned(entity) } 270 }); 244 271 return true; 245 272 }; 246 273 274 /** 275 * Garrison units inside the entity 276 * @return true if successful, false if not 277 */ 247 278 GarrisonHolder.prototype.PerformGarrison = function(entity) 248 279 { 249 280 if (!this.HasEnoughHealth()) … … 250 281 return false; 251 282 252 283 // Check if the unit is allowed to be garrisoned inside the building 253 if (!this.AllowedToGarrison(entity))284 if (!this.AllowedToGarrison(entity)) 254 285 return false; 255 286 256 // check the capacity287 // Check the capacity 257 288 var extraCount = 0; 258 289 var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder); 259 290 if (cmpGarrisonHolder) … … 278 309 if (cmpAura && cmpAura.HasGarrisonAura()) 279 310 cmpAura.ApplyGarrisonBonus(this.entity); 280 311 281 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });282 283 312 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 284 313 if (cmpUnitAI && cmpUnitAI.IsUnderAlert()) 285 314 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity}); … … 326 355 327 356 var cmpNewPosition = Engine.QueryInterface(entity, IID_Position); 328 357 this.entities.splice(entityIndex, 1); 329 358 // Should only be called before the ejection has been performed else the visible Garrison Points will be empty. 359 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 360 "added": [], 361 "removed": [entity], 362 "visible": { entity: this.IsVisiblyGarrisoned(entity) } 363 }); 330 364 for (var vgp of this.visibleGarrisonPoints) 331 365 { 332 366 if (vgp.entity != entity) … … 356 390 cmpNewPosition.SetHeightOffset(0); 357 391 // TODO: what direction should they face in? 358 392 359 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });360 393 361 394 return true; 362 395 }; … … 620 653 if (cmpHealth && cmpHealth.GetHitpoints() == 0) 621 654 { 622 655 this.entities.splice(entityIndex, 1); 623 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] }); 656 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 657 "added": [], 658 "removed": [msg.entity], 659 "visible": { msg.entity: this.IsVisiblyGarrisoned(msg.entity) } 660 }); 624 661 this.UpdateGarrisonFlag(); 625 662 626 663 for (var pt of this.visibleGarrisonPoints) … … 634 671 635 672 /** 636 673 * Update list of garrisoned entities if one gets renamed (e.g. by promotion) 674 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint, 675 * in case of promotion for example, and thus should always be allowed. 637 676 */ 638 677 GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) 639 678 { … … 670 709 } 671 710 }; 672 711 673 674 712 /** 675 713 * Eject all foreign garrisoned entities which are no more allied 676 714 */ … … 687 725 GarrisonHolder.prototype.EjectOrKill = function(entities) 688 726 { 689 727 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 690 // Eject the units which can be ejected (if not in world, it generallymeans this holder728 // Eject the units which can be ejected (if not in world, it often means this holder 691 729 // is inside a holder which kills its entities, so do not eject) 692 730 if (cmpPosition.IsInWorld()) 693 731 { … … 710 748 this.entities.splice(entityIndex, 1); 711 749 killedEntities.push(entity); 712 750 } 713 714 751 if (killedEntities.length > 0) 715 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities }); 752 { 753 let visibleEntitiesIds = {}; 754 for (let ent of killedEntities) 755 visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent); 756 757 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 758 "added": [], 759 "removed": killedEntities, 760 "visible": visibleEntitiesIds 761 }); 762 } 716 763 this.UpdateGarrisonFlag(); 717 764 }; 718 765 719 766 /** 767 * Gives insight about the unit type of garrisoning. 768 * @return{bool} returns true if the unit is visible on the structure 769 * @param {int} the entity's id 770 */ 771 GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) 772 { 773 return this.visibleGarrisonPoints.some(point => point.entity == entity); 774 }; 775 776 /** 720 777 * Checks if an entity is ejectable on destroy if possible 721 778 */ 722 779 GarrisonHolder.prototype.IsEjectable = function(entity)