Ticket #3488: 3488.14.diff
File 3488.14.diff, 8.7 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 "<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 … … 225 248 { 226 249 if (vgp.entity) 227 250 continue; 228 visibleGarrisonPoint = vgp; 229 break; 251 if (this.AllowedToVisibleGarrisoning(vgp, entity)) 252 { 253 visibleGarrisonPoint = vgp; 254 break; 255 } 230 256 } 231 257 } 232 233 if (visibleGarrisonPoint) 258 if (visibleGarrisonPoint && this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity)) 234 259 { 235 260 visibleGarrisonPoint.entity = entity; 236 261 cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset); … … 241 266 else 242 267 cmpPosition.MoveOutOfWorld(); 243 268 269 let visible = {}; 270 visible[entity] = this.IsVisiblyGarrisoned(entity); 271 // Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet. 272 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 273 "added": [entity], 274 "removed": [], 275 "visible": visible 276 }); 244 277 return true; 245 278 }; 246 279 280 /** 281 * Garrison units inside the entity 282 * @return true if successful, false if not 283 */ 247 284 GarrisonHolder.prototype.PerformGarrison = function(entity) 248 285 { 249 286 if (!this.HasEnoughHealth()) … … 250 287 return false; 251 288 252 289 // Check if the unit is allowed to be garrisoned inside the building 253 if (!this.AllowedToGarrison(entity))290 if (!this.AllowedToGarrison(entity)) 254 291 return false; 255 292 256 // check the capacity293 // Check the capacity 257 294 var extraCount = 0; 258 295 var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder); 259 296 if (cmpGarrisonHolder) … … 278 315 if (cmpAura && cmpAura.HasGarrisonAura()) 279 316 cmpAura.ApplyGarrisonBonus(this.entity); 280 317 281 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });282 283 318 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI); 284 319 if (cmpUnitAI && cmpUnitAI.IsUnderAlert()) 285 320 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity}); … … 326 361 327 362 var cmpNewPosition = Engine.QueryInterface(entity, IID_Position); 328 363 this.entities.splice(entityIndex, 1); 329 364 365 let visible = {}; 366 visible[entity] = this.IsVisiblyGarrisoned(entity); 367 // Should only be called before the ejection has been performed else the visible Garrison Points will be empty. 368 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 369 "added": [], 370 "removed": [entity], 371 "visible": visible 372 }); 330 373 for (var vgp of this.visibleGarrisonPoints) 331 374 { 332 375 if (vgp.entity != entity) … … 356 399 cmpNewPosition.SetHeightOffset(0); 357 400 // TODO: what direction should they face in? 358 401 359 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });360 402 361 403 return true; 362 404 }; … … 597 639 */ 598 640 GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg) 599 641 { 642 let msgEntity = msg.entity; 600 643 // the ownership change may be on the garrisonholder 601 if (this.entity == msg .entity)644 if (this.entity == msgEntity) 602 645 { 603 646 var entities = []; 604 647 for each (var entity in this.entities) … … 612 655 } 613 656 614 657 // or on some of its garrisoned units 615 var entityIndex = this.entities.indexOf(msg.entity);658 let entityIndex = this.entities.indexOf(msgEntity); 616 659 if (entityIndex != -1) 617 660 { 618 661 // If the entity is dead, remove it directly instead of ejecting the corpse 619 var cmpHealth = Engine.QueryInterface(msg.entity, IID_Health);662 let cmpHealth = Engine.QueryInterface(msgEntity, IID_Health); 620 663 if (cmpHealth && cmpHealth.GetHitpoints() == 0) 621 664 { 622 665 this.entities.splice(entityIndex, 1); 623 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] }); 666 let visible = {}; 667 visible[msgEntity] = this.IsVisiblyGarrisoned(msgEntity); 668 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 669 "added": [], 670 "removed": [msgEntity], 671 "visible": visible 672 }); 624 673 this.UpdateGarrisonFlag(); 625 674 626 675 for (var pt of this.visibleGarrisonPoints) 627 if (pt.entity == msg .entity)676 if (pt.entity == msgEntity) 628 677 pt.entity = null; 629 678 } 630 else if (msg.to == -1 || !IsOwnedByMutualAllyOfEntity(this.entity, msg .entity))631 this.EjectOrKill([msg .entity]);679 else if (msg.to == -1 || !IsOwnedByMutualAllyOfEntity(this.entity, msgEntity)) 680 this.EjectOrKill([msgEntity]); 632 681 } 633 682 }; 634 683 635 684 /** 636 685 * Update list of garrisoned entities if one gets renamed (e.g. by promotion) 686 * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint, 687 * in case of promotion for example, and thus should always be allowed. 637 688 */ 638 689 GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg) 639 690 { … … 670 721 } 671 722 }; 672 723 673 674 724 /** 675 725 * Eject all foreign garrisoned entities which are no more allied 676 726 */ … … 687 737 GarrisonHolder.prototype.EjectOrKill = function(entities) 688 738 { 689 739 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 690 // Eject the units which can be ejected (if not in world, it generallymeans this holder740 // Eject the units which can be ejected (if not in world, it often means this holder 691 741 // is inside a holder which kills its entities, so do not eject) 692 742 if (cmpPosition.IsInWorld()) 693 743 { … … 710 760 this.entities.splice(entityIndex, 1); 711 761 killedEntities.push(entity); 712 762 } 713 714 763 if (killedEntities.length > 0) 715 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities }); 764 { 765 let visibleEntitiesIds = {}; 766 for (let ent of killedEntities) 767 visibleEntitiesIds[ent] = this.IsVisiblyGarrisoned(ent); 768 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { 769 "added": [], 770 "removed": killedEntities, 771 "visible": visibleEntitiesIds 772 }); 773 } 716 774 this.UpdateGarrisonFlag(); 717 775 }; 718 776 719 777 /** 778 * Gives insight about the unit type of garrisoning. 779 * @return{bool} returns true if the unit is visible on the structure 780 * @param {int} the entity's id 781 */ 782 GarrisonHolder.prototype.IsVisiblyGarrisoned = function(entity) 783 { 784 return this.visibleGarrisonPoints.some(point => point.entity == entity); 785 }; 786 787 /** 720 788 * Checks if an entity is ejectable on destroy if possible 721 789 */ 722 790 GarrisonHolder.prototype.IsEjectable = function(entity)