Ticket #52: Triggers.3.patch
File Triggers.3.patch, 30.5 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/simulation/components/BuildingAI.js
146 146 */ 147 147 BuildingAI.prototype.OnRangeUpdate = function(msg) 148 148 { 149 150 149 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 151 150 if (!cmpAttack) 152 151 return; -
binaries/data/mods/public/simulation/components/Foundation.js
202 202 // (via CCmpTemplateManager). Now we need to remove that temporary 203 203 // blocker-disabling, so that we'll perform standard unit blocking instead. 204 204 cmpObstruction.SetDisableBlockMovementPathfinding(false, false, -1); 205 206 // Call the related trigger event 207 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 208 cmpTrigger.CallEvent("OnConstructionStarted", {"foundation": this.entity, "template": this.finalTemplateName}); 205 209 } 206 210 207 211 // Switch foundation to scaffold variant -
binaries/data/mods/public/simulation/components/PlayerManager.js
31 31 return INVALID_ENTITY; 32 32 }; 33 33 34 /** 35 * Get the number of players (including gaia) 36 */ 34 37 PlayerManager.prototype.GetNumPlayers = function() 35 38 { 36 39 return this.playerEntities.length; -
binaries/data/mods/public/simulation/components/ProductionQueue.js
288 288 "timeTotal": time*1000, 289 289 "timeRemaining": time*1000, 290 290 }); 291 292 // Call the related trigger event 293 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 294 cmpTrigger.CallEvent("OnTrainingQueued", {"playerid": cmpPlayer.GetPlayerID(), "unitTemplate": templateName, "count": count, "metadata": metadata, "trainerEntity": this.entity}); 291 295 } 292 296 else if (type == "technology") 293 297 { … … 324 328 "timeTotal": time*1000, 325 329 "timeRemaining": time*1000, 326 330 }); 331 332 // Call the related trigger event 333 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 334 cmpTrigger.CallEvent("OnResearchQueued", {"playerid": cmpPlayer.GetPlayerID(), "technologyTemplate": templateName, "researcherEntity": this.entity}); 327 335 } 328 336 else 329 337 { -
binaries/data/mods/public/simulation/components/ResourceTrickle.js
57 57 if (cmpPlayer) 58 58 for (var resource in rates) 59 59 cmpPlayer.AddResource(resource, rates[resource]); 60 61 60 }; 62 61 63 62 Engine.RegisterComponentType(IID_ResourceTrickle, "ResourceTrickle", ResourceTrickle); -
binaries/data/mods/public/simulation/components/TechnologyManager.js
286 286 return; 287 287 } 288 288 289 // Call the related trigger event 290 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 291 cmpTrigger.CallEvent("OnResearchFinished", {"researcher": this.entity, "tech": tech}); 292 289 293 var modifiedComponents = {}; 290 294 this.researchedTechs[tech] = template; 291 295 // store the modifications in an easy to access structure -
binaries/data/mods/public/simulation/components/Trigger.js
1 function Trigger() {} 2 3 Trigger.prototype.Schema = 4 "<a:component type='system'/><empty/>"; 5 6 Trigger.prototype.Init = function() 7 { 8 // Each event has its own set of actions determined by the map maker. 9 var eventNames = [ 10 "OnEntityTookDamage", 11 "OnEntityKilled", 12 "OnStructureBuilt", 13 "OnConstructionStarted", 14 "OnTrainingFinished", 15 "OnTrainingQueued", 16 "OnResearchFinished", 17 "OnResearchQueued", 18 "OnTimer", 19 "OnUnitIssuedOrder"]; 20 for each (var eventName in eventNames) 21 this["event" + eventName + "Actions"] = []; 22 23 this.eventOnUnitRangeFromEntityData = {}; 24 }; 25 26 /** 27 * Start the update timer, will cause the "Always" events to be triggered every timer tick 28 */ 29 Trigger.prototype.StartUpdateTimer = function(delay, interval) 30 { 31 // Stop the last timer before starting a new one 32 if (this.timer) 33 this.StopUpdateTimer(); 34 35 // Start the update timer 36 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 37 this.timer = cmpTimer.SetInterval(this.entity, IID_Trigger, "TimerUpdate", delay, interval, null); 38 } 39 40 /** 41 * Stop the update timer, will cause the "Always" events to never be triggered again 42 */ 43 Trigger.prototype.StopUpdateTimer = function() 44 { 45 // Call the update timer 46 if (!this.timer) 47 return; 48 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 49 cmpTimer.CancelTimer(this.timer); 50 this.timer = undefined; 51 } 52 53 /** 54 * Binds the "action" function to one of the implemented events. 55 * 56 * @param eventName Name of the event (see the list in init) 57 * @param action Functionname of a function available under the g_Triggers global object 58 */ 59 Trigger.prototype.RegisterTrigger = function(eventName, action) 60 { 61 var eventString = "event" + eventName + "Actions"; 62 if (this[eventString]) 63 this[eventString].push(action); 64 else 65 error("event " + eventName + " not found as an existing trigger event."); 66 }; 67 68 /* 69 * This is an event with more than just the key argument, 70 * so we should have a special register function for it. 71 * 72 * @param entity Entity id around which the range is checked 73 * @param radius Radius of the range 74 * @param action Functionname to execute on a range change (entities entered or left) 75 * @param players Array of player ids (0 to 8). Or null if you want to check for all players 76 * @param componentID Only entities with this component id will be noticed. 0 for all entities 77 */ 78 Trigger.prototype.RegisterOnUnitRangeFromEntityTrigger = function(entity, radius, action, players, componentID) 79 { 80 // If the players parameter is not specified use all players. 81 if (!players) 82 { 83 var numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers; 84 players = []; 85 for (var i = 0; i < numPlayers; i++) 86 players.push(i); 87 } 88 89 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 90 91 var rangeQueryID = cmpRangeManager.CreateActiveQuery(entity, 0, radius, players, componentID || 0, cmpRangeManager.GetEntityFlagMask("normal")); 92 93 cmpRangeManager.EnableActiveQuery(rangeQueryID); 94 95 this.eventOnUnitRangeFromEntityData[action] = { 96 "action": action, 97 "entity": entity, 98 "radius": radius, 99 "currentCollection": [], 100 "rangeQuery": rangeQueryID, 101 "players": players}; 102 } 103 104 Trigger.prototype.DisableRangeTrigger = function(action) 105 { 106 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 107 cmpRangeManager.DisableActiveQuery(this.eventOnUnitRangeFromEntityData[action].rangeQuery); 108 } 109 110 Trigger.prototype.EnableRangeTrigger = function(action) 111 { 112 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 113 cmpRangeManager.EnableActiveQuery(this.eventOnUnitRangeFromEntityData[action].rangeQuery); 114 } 115 116 Trigger.prototype.RemoveTrigger = function(eventName, action) 117 { 118 var eventString = "event" + eventName + "Actions"; 119 if (this[eventString]) 120 { 121 var index = this[eventString].indexOf(action); 122 if (index > -1) 123 this[eventString].splice(index, 1); 124 } 125 else 126 error("event " + eventName + " not found as an existing trigger event."); 127 } 128 129 /** 130 * This function executes the actions bound to the events 131 * It's either called directlty from other simulation scripts, 132 * or from message listeners in this file 133 * 134 * @param eventName Name of the event (see the list in init) 135 * @param data Data object that will be passed to the actions 136 */ 137 Trigger.prototype.CallEvent = function(eventName, data) 138 { 139 var eventString = "event" + eventName + "Actions"; 140 if (!this[eventString]) 141 error("Unknown trigger event "+eventName); 142 else 143 this[eventString].forEach(function(action){this.DoAction({"action": action, "data": data});}, this); 144 } 145 146 Trigger.prototype.OnGlobalConstructionFinished = function(msg) 147 { 148 this.CallEvent("OnStructureBuilt", {"building": msg.newentity}); 149 } 150 151 Trigger.prototype.OnGlobalTrainingFinished = function(msg) 152 { 153 this.CallEvent("OnTrainingFinished", msg); 154 // The data for this one is {"entities": createdEnts, 155 // "owner": cmpOwnership.GetOwner(), 156 // "metadata": metadata} 157 // See function "SpawnUnits" in ProductionQueue for more details 158 } 159 160 Trigger.prototype.TimerUpdate = function(data, lateness) 161 { 162 this.CallEvent("OnTimer", lateness); 163 } 164 165 Trigger.prototype.OnGlobalRangeUpdate = function(msg) 166 { 167 // search the right query 168 for (var action in this.eventOnUnitRangeFromEntityData) 169 { 170 if (msg.tag == this.eventOnUnitRangeFromEntityData[action].rangeQuery) 171 { 172 var updatedQuery = this.eventOnUnitRangeFromEntityData[action]; 173 break; 174 } 175 } 176 177 if (!updatedQuery) 178 return; 179 180 for each (var entity in msg.removed) 181 { 182 var index = updatedQuery.currentCollection.indexOf(entity); 183 if (index > -1) 184 updatedQuery.currentCollection.splice(index, 1); 185 } 186 187 updatedQuery.currentCollection.concat(msg.added); 188 189 var data = { 190 "currentCollection": updatedQuery.currentCollection.slice(), 191 "added": msg.added, 192 "removed": msg.removed}; 193 194 this.DoAction({"action": updatedQuery.action, "data": data}); 195 } 196 197 /** 198 * Execute a function after a certain delay 199 * @param time The delay expressed in milleseconds 200 * @param action Name of the action function 201 * @param data Data object that will be passed to the action function 202 */ 203 Trigger.prototype.DoAfterDelay = function(time, action, data) 204 { 205 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 206 return cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger, "DoAction", time, {"action": action, "data": data}); 207 } 208 209 /** 210 * Called by the trigger listeners to exucute the actual action. Including sanity checks. 211 */ 212 Trigger.prototype.DoAction = function(msg) 213 { 214 if (g_Triggers[msg.action]) 215 g_Triggers[msg.action](msg.data); 216 else 217 error("called a trigger action '" + msg.action + "' that wasn't added to the g_Triggers global"); 218 } 219 220 Engine.RegisterComponentType(IID_Trigger, "Trigger", Trigger); -
binaries/data/mods/public/simulation/components/UnitAI.js
199 199 cmpUnitMotion.MoveToFormationOffset(msg.data.target, msg.data.x, msg.data.z); 200 200 201 201 this.SetNextStateAlwaysEntering("FORMATIONMEMBER.WALKING"); 202 203 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 204 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.FormationWalk", "metadata": msg}); 202 205 }, 203 206 204 207 // Special orders: … … 225 228 // We are already at the target, or can't move at all 226 229 this.FinishOrder(); 227 230 } 231 232 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 233 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.LeaveFoundation", "metadata": msg}); 228 234 }, 229 235 230 236 // Individual orders: … … 247 253 this.SetNextState("ANIMAL.IDLE"); 248 254 else 249 255 this.SetNextState("INDIVIDUAL.IDLE"); 250 256 257 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 258 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Stop", "metadata": msg}); 251 259 }, 252 260 253 261 "Order.Walk": function(msg) { … … 258 266 return; 259 267 } 260 268 269 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 270 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Walk", "metadata": msg}); 271 261 272 // For packable units: 262 273 // 1. If packed, we can move. 263 274 // 2. If unpacked, we first need to pack, then follow case 1. … … 284 295 return; 285 296 } 286 297 298 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 299 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.WalkAndFight", "metadata": msg}); 300 287 301 // For packable units: 288 302 // 1. If packed, we can move. 289 303 // 2. If unpacked, we first need to pack, then follow case 1. … … 310 324 this.FinishOrder(); 311 325 return; 312 326 } 313 327 328 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 329 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.WalkToTarget", "metadata": msg, "target": this.order.data.target}); 330 314 331 // For packable units: 315 332 // 1. If packed, we can move. 316 333 // 2. If unpacked, we first need to pack, then follow case 1. … … 369 386 this.StopMoving(); 370 387 this.SetNextState("INDIVIDUAL.PICKUP.LOADING"); 371 388 } 389 390 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 391 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.PickupUnit", "metadata": msg, "target": this.order.data.target}); 372 392 }, 373 393 374 394 "Order.Guard": function(msg) { … … 382 402 this.SetNextState("INDIVIDUAL.GUARD.ESCORTING"); 383 403 else 384 404 this.SetNextState("INDIVIDUAL.GUARD.GUARDING"); 405 406 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 407 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Guard", "metadata": msg, "target": this.order.data.target}); 385 408 }, 386 409 387 410 "Order.Flee": function(msg) { … … 390 413 var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); 391 414 if (cmpUnitMotion.MoveToTargetRange(this.order.data.target, distance, -1)) 392 415 { 416 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 417 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Flee", "metadata": msg, "target": this.order.data.target}); 418 393 419 // We've started fleeing from the given target 394 420 if (this.IsAnimal()) 395 421 this.SetNextState("ANIMAL.FLEEING"); … … 402 428 this.StopMoving(); 403 429 this.FinishOrder(); 404 430 } 431 432 405 433 }, 406 434 407 435 "Order.Attack": function(msg) { … … 422 450 } 423 451 this.order.data.attackType = type; 424 452 453 // Call "OnUnitIssuedOrder" event of the triggers. 454 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 455 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Attack", "metadata": msg, "target": this.order.data.target}); 456 425 457 // If we are already at the target, try attacking it from here 426 458 if (this.CheckTargetAttackRange(this.order.data.target, this.order.data.attackType)) 427 459 { … … 506 538 // We can't reach the target, and can't move towards it, 507 539 // so abandon this attack order 508 540 this.FinishOrder(); 541 509 542 }, 510 543 511 544 "Order.Heal": function(msg) { … … 526 559 // Check if the target is in range 527 560 if (this.CheckTargetRange(this.order.data.target, IID_Heal)) 528 561 { 562 // Call "OnUnitIssuedOrder" event of the triggers. 563 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 564 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Heal", "metadata": msg, "target": this.order.data.target}); 565 529 566 this.StopMoving(); 530 567 this.SetNextState("INDIVIDUAL.HEAL.HEALING"); 531 568 return; … … 542 579 // Try to move within heal range 543 580 if (this.MoveToTargetRange(this.order.data.target, IID_Heal)) 544 581 { 582 // Call "OnUnitIssuedOrder" event of the triggers. 583 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 584 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Heal", "metadata": msg, "target": this.order.data.target}); 585 545 586 // We've started walking to the given point 546 587 this.SetNextState("INDIVIDUAL.HEAL.APPROACHING"); 547 588 return; … … 599 640 this.StopMoving(); 600 641 this.SetNextStateAlwaysEntering("INDIVIDUAL.GATHER.GATHERING"); 601 642 } 643 644 // Call "OnUnitIssuedOrder" event of the triggers. 645 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 646 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Gather", "metadata": msg, "target": this.order.data.target}); 602 647 }, 603 648 604 649 "Order.GatherNearPosition": function(msg) { … … 605 650 // Move the unit to the position to gather from. 606 651 this.MoveToPoint(this.order.data.x, this.order.data.z); 607 652 this.SetNextState("INDIVIDUAL.GATHER.WALKING"); 653 654 // Call "OnUnitIssuedOrder" event of the triggers. 655 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 656 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.GatherNearPosition", "metadata": msg, "target": this.order.data.target}); 608 657 }, 609 658 610 659 "Order.ReturnResource": function(msg) { … … 628 677 // Try to move to the dropsite 629 678 if (this.MoveToTargetRange(this.order.data.target, IID_ResourceGatherer)) 630 679 { 680 // Call "OnUnitIssuedOrder" event of the triggers. 681 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 682 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.ReturnResource", "metadata": msg, "target": this.order.data.target}); 683 631 684 // We've started walking to the target 632 685 this.SetNextState("INDIVIDUAL.RETURNRESOURCE.APPROACHING"); 633 686 return; … … 660 713 this.waypoints = undefined; 661 714 if (this.MoveToMarket(nextMarket)) 662 715 { 716 // Call "OnUnitIssuedOrder" event of the triggers. 717 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 718 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Trade", "metadata": msg, "target": this.order.data.target}); 719 663 720 // We've started walking to the next market 664 721 this.SetNextState(state); 665 722 } … … 682 739 this.StopMoving(); 683 740 this.SetNextState("INDIVIDUAL.REPAIR.REPAIRING"); 684 741 } 742 743 // Call "OnUnitIssuedOrder" event of the triggers. 744 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 745 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Repair", "metadata": msg, "target": this.order.data.target}); 685 746 }, 686 747 687 748 "Order.Garrison": function(msg) { 749 // Call "OnUnitIssuedOrder" event of the triggers. 750 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 751 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Garrison", "metadata": msg, "target": this.order.data.target}); 752 688 753 // For packable units: 689 754 // 1. If packed, we can move to the garrison target. 690 755 // 2. If unpacked, we first need to pack, then follow case 1. … … 709 774 710 775 "Order.Autogarrison": function(msg) { 711 776 this.SetNextState("INDIVIDUAL.AUTOGARRISON"); 777 778 // Call "OnUnitIssuedOrder" event of the triggers. 779 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 780 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Autogarrison", "metadata": msg}); 712 781 }, 713 782 714 783 "Order.Alert": function(msg) { … … 722 791 this.ReplaceOrder("Garrison", {"target": this.alertGarrisoningTarget}); 723 792 else 724 793 this.FinishOrder(); 794 795 // Call "OnUnitIssuedOrder" event of the triggers. 796 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 797 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Alert", "metadata": msg}); 725 798 }, 726 799 727 800 "Order.Cheering": function(msg) { 728 801 this.SetNextState("INDIVIDUAL.CHEERING"); 802 803 // Call "OnUnitIssuedOrder" event of the triggers. 804 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 805 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Cheering", "metadata": msg}); 729 806 }, 730 807 731 808 "Order.Pack": function(msg) { … … 733 810 { 734 811 this.StopMoving(); 735 812 this.SetNextState("INDIVIDUAL.PACKING"); 813 814 // Call "OnUnitIssuedOrder" event of the triggers. 815 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 816 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Pack", "metadata": msg}); 736 817 } 737 818 }, 738 819 … … 741 822 { 742 823 this.StopMoving(); 743 824 this.SetNextState("INDIVIDUAL.UNPACKING"); 825 826 // Call "OnUnitIssuedOrder" event of the triggers. 827 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 828 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.Unpack", "metadata": msg}); 744 829 } 745 830 }, 746 831 … … 749 834 if (cmpPack && cmpPack.IsPacking() && !cmpPack.IsPacked()) 750 835 cmpPack.CancelPack(); 751 836 this.FinishOrder(); 837 838 // Call "OnUnitIssuedOrder" event of the triggers. 839 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 840 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.CancelPack", "metadata": msg}); 752 841 }, 753 842 754 843 "Order.CancelUnpack": function(msg) { … … 756 845 if (cmpPack && cmpPack.IsPacking() && cmpPack.IsPacked()) 757 846 cmpPack.CancelPack(); 758 847 this.FinishOrder(); 848 849 // Call "OnUnitIssuedOrder" event of the triggers. 850 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 851 cmpTrigger.CallEvent("OnUnitIssuedOrder", {"entity": this.entity, "order": "Order.CancelUnpack", "metadata": msg}); 759 852 }, 760 853 761 854 // States for the special entity representing a group of units moving in formation: … … 820 913 var cmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI); 821 914 if (cmpTargetUnitAI && cmpTargetUnitAI.IsFormationMember()) 822 915 target = cmpTargetUnitAI.GetFormationController(); 823 916 824 917 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 825 918 // Check if we are already in range, otherwise walk there 826 919 if (!this.CheckTargetAttackRange(target, target)) … … 849 942 this.FinishOrder(); 850 943 return; 851 944 } 945 852 946 // Check if we are already in range, otherwise walk there 853 947 if (!this.CheckGarrisonRange(msg.data.target)) 854 948 { … … 926 1020 } 927 1021 928 1022 this.CallMemberFunction("GatherNearPosition", [msg.data.x, msg.data.z, msg.data.type, msg.data.template, false]); 929 1023 930 1024 this.SetNextStateAlwaysEntering("MEMBER"); 931 1025 }, 932 1026 … … 945 1039 } 946 1040 947 1041 this.CallMemberFunction("Heal", [msg.data.target, false]); 948 1042 949 1043 this.SetNextStateAlwaysEntering("MEMBER"); 950 1044 }, 951 1045 … … 1199 1293 1200 1294 // Stop moving as soon as the formation disbands 1201 1295 this.StopMoving(); 1202 1296 1203 1297 // If the controller handled an order but some members rejected it, 1204 1298 // they will have no orders and be in the FORMATIONMEMBER.IDLE state. 1205 1299 if (this.orderQueue.length) -
binaries/data/mods/public/simulation/components/interfaces/Trigger.js
1 Engine.RegisterInterface("Trigger"); -
binaries/data/mods/public/simulation/helpers/Damage.js
74 74 // Damage the target 75 75 var targetState = cmpDamageReceiver.TakeDamage(data.strengths.hack * data.multiplier, data.strengths.pierce * data.multiplier, data.strengths.crush * data.multiplier, data.attacker); 76 76 77 // Call the related trigger event 78 // We have to call the event instead of listening to it by messages because the message is sent 79 // after the target gets killed, which is not our intended case 80 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 81 cmpTrigger.CallEvent("OnEntityTookDamage", {"attackerEntity": data.attacker, "attackedEntity": data.target, "type":data.type, "ammount":-targetState.change}); 82 77 83 // If the target was killed run some cleanup 78 84 if (targetState.killed) 79 85 Damage.TargetKilled(data.attacker, data.target); … … 110 116 // Call RangeManager with dummy entity and return the result. 111 117 var rangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 112 118 var rangeQuery = rangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, IID_DamageReceiver); 119 113 120 return rangeQuery; 114 121 }; 115 122 … … 133 140 var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter); 134 141 if (cmpLooter) 135 142 cmpLooter.Collect(targetEntity); 143 144 // Call the related trigger event 145 var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); 146 cmpTrigger.CallEvent("OnEntityKilled", {"killerEntity": killerEntity, "killedEntity": targetEntity}); 136 147 }; 137 148 138 149 Engine.RegisterGlobal("Damage", Damage); -
binaries/data/mods/public/simulation/helpers/TriggerHelpers.js
1 // Contains standardized functions suitable for using in trigger scripts. 2 // Do not use them in any other simulation script. 3 4 // the global triggers variable used to exchange messages with the map scripts 5 var g_Triggers = {} 6 Engine.RegisterGlobal("g_Triggers", g_Triggers); 7 8 /** 9 * A function to get the owner of an entity. 10 * Returns the ID of a player. Returns 0 if the owner is Gaia. 11 */ 12 function GetEntityOwner(entity) 13 { 14 var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership) 15 if (!cmpOwnership) 16 return null; 17 return cmpOwnership.GetOwner(); 18 } 19 20 /** 21 * A function to get the generic name of an entity 22 */ 23 function GetEntityGenericName(entity) 24 { 25 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 26 if (!cmpIdentity) 27 return null; 28 return cmpIdentity.GetGenericName(); 29 } 30 31 /** 32 * A function to get a list of the classes of an entity 33 */ 34 function GetEntityClassesList(entity) 35 { 36 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 37 if (!cmpIdentity) 38 return null; 39 return cmpIdentity.GetClassesList(); 40 } 41 42 /** 43 * A function to determine if an entity has a specific class 44 */ 45 function EntityHasClass(entity, classname) 46 { 47 var classes = GetEntityClassesList(entity); 48 return (classes && classes.indexOf(classname) != -1); 49 } 50 51 /** 52 * Returns the entity id of a player based on the id of the player 53 * Useful when one wants to change a player's properties. 54 */ 55 function GetPlayerEntityByID(id) 56 { 57 var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 58 return cmpPlayerMan.GetPlayerByID(id); 59 } 60 61 /** 62 * Can be used to "force" a building to spawn a group of entities. 63 * Only works for buildings that can already train units. 64 */ 65 function BuildingSpawnUnits(entity, template, count) 66 { 67 var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue); 68 cmpProductionQueue.SpawnUnits(template, count, null); 69 } 70 71 /** 72 * Shows a message in the top center of the screen 73 */ 74 function PushNotification(players, message) 75 { 76 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 77 for each (var player in players) 78 cmpGUIInterface.PushNotification({"player": player, "message": message}); 79 } 80 81 /** 82 * Returns the resource type that can be gathered from an entity 83 */ 84 function GetEntityResourceType(entity) 85 { 86 var cmpResourceSupply = Engine.QueryInterface(entity, IID_ResourceSupply); 87 if (!cmpResourceSupply) 88 return null; 89 return cmpResourceSupply.GetType(); 90 } 91 92 /** 93 * Returns a list of entities owned by the player 94 */ 95 function GetEntitiesByPlayer(playerID) 96 { 97 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 98 return cmpRangeManager.GetEntitiesByPlayer(playerID); 99 } 100 101 /** 102 * Wins the game for a player 103 */ 104 function SetPlayerWon(playerID) 105 { 106 var playerEnt = GetPlayerEntityByID(playerID); 107 var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player); 108 cmpPlayer.SetState("won") 109 } 110 111 /** 112 * Defeats a player 113 */ 114 function DefeatPlayer(playerID) 115 { 116 var playerEnt = GetPlayerEntityByID(playerID); 117 Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": playerID } ); 118 } 119 120 Engine.RegisterGlobal("GetEntityOwner", GetEntityOwner); 121 Engine.RegisterGlobal("GetEntityGenericName", GetEntityGenericName); 122 Engine.RegisterGlobal("GetEntityClassesList", GetEntityClassesList); 123 Engine.RegisterGlobal("EntityHasClass", EntityHasClass); 124 Engine.RegisterGlobal("GetPlayerEntityByID", GetPlayerEntityByID); 125 Engine.RegisterGlobal("BuildingSpawnUnits", BuildingSpawnUnits); 126 Engine.RegisterGlobal("PushNotification", PushNotification); 127 Engine.RegisterGlobal("GetEntityResourceType", GetEntityResourceType); 128 Engine.RegisterGlobal("GetEntitiesByPlayer", GetEntitiesByPlayer); 129 Engine.RegisterGlobal("SetPlayerWon", SetPlayerWon); 130 Engine.RegisterGlobal("DefeatPlayer", DefeatPlayer); 131 -
source/simulation2/Simulation2.cpp
133 133 LOAD_SCRIPTED_COMPONENT("PlayerManager"); 134 134 LOAD_SCRIPTED_COMPONENT("TechnologyTemplateManager"); 135 135 LOAD_SCRIPTED_COMPONENT("Timer"); 136 LOAD_SCRIPTED_COMPONENT("Trigger"); 136 137 LOAD_SCRIPTED_COMPONENT("ValueModificationManager"); 137 138 138 139 #undef LOAD_SCRIPTED_COMPONENT … … 748 749 749 750 if (!m->m_StartupScript.empty()) 750 751 GetScriptInterface().LoadScript(L"map startup script", m->m_StartupScript); 752 753 // Load the trigger script after we have loaded the simulation and the map. 754 if (GetScriptInterface().HasProperty(m->m_MapSettings.get(), "TriggerScript")) 755 { 756 std::string script_name; 757 GetScriptInterface().GetProperty(m->m_MapSettings.get(), "TriggerScript", script_name); 758 759 script_name = "maps/scripts/" + script_name; 760 m->m_ComponentManager.LoadScript(script_name.data()); 761 } 751 762 } 752 763 753 764 int CSimulation2::ProgressiveLoad()