Ticket #4066: GarrisonHolder_Mod.js

File GarrisonHolder_Mod.js, 4.9 KB (added by AlThePhoenix, 8 years ago)

Tested with Alpha 20

Line 
1
2GarrisonHolder.prototype.Schema +=
3 "<optional>" +
4 "<element name='StartingGarrison' a:help='Units that are garrisoned in this unit / structure after its creation'>" +
5 "<zeroOrMore>" +
6 "<element a:help='Element containing the offset coordinates'>" +
7 "<anyName/>" +
8 "<interleave>" +
9 "<element name='Template'>" +
10 "<text/>" +
11 "</element>" +
12 "<element name='Count'>" +
13 "<data type='nonNegativeInteger'/>" +
14 "</element>" +
15 "</interleave>" +
16 "</element>" +
17 "</zeroOrMore>" +
18 "</element>" +
19 "</optional>";
20
21/**
22 * Initialize GarrisonHolder Component
23 *
24 * Garrisoning when loading a map is set in the script of the map, by setting initGarrison
25 * which should contain the array of garrisoned entities
26 */
27GarrisonHolder.prototype.Init = function()
28{
29 // Garrisoned Units
30 this.entities = [];
31 this.timer = undefined;
32 this.allowGarrisoning = {};
33 this.visibleGarrisonPoints = [];
34 this.startingGarrison = [];
35 this.startingGarrisonCount = 0;
36 this.startingGarrisonObtained = false;
37 if (this.template.VisibleGarrisonPoints)
38 {
39 for (let key in this.template.VisibleGarrisonPoints)
40 {
41 let offset = this.template.VisibleGarrisonPoints[key];
42 let o = {};
43 o.x = +offset.X;
44 o.y = +offset.Y;
45 o.z = +offset.Z;
46 this.visibleGarrisonPoints.push({"offset":o, "entity": null});
47 }
48 }
49 if (this.template.StartingGarrison)
50 {
51 for (let key in this.template.StartingGarrison)
52 {
53 if (this.startingGarrisonCount < this.template.Max)
54 {
55 let group = this.template.StartingGarrison[key];
56 let template = group.Template;
57 let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
58 if (!cmpTemplateManager.TemplateExists(template))
59 warn("Specified StartingGarrison template '" +template+ "' in group '" +key+ "' does not exist");
60 else
61 {
62 let count;
63 count = group.Count;
64 if (Number(count) > Number(this.template.Max))
65 count = this.template.Max;
66 if ((Number(this.startingGarrisonCount) + Number(count)) > Number(this.template.Max))
67 {
68 count = Number(this.template.Max) - Number(count);
69 warn("Tried adding too many units. "+key+"'s count has been reduced to " +count+ ".");
70 }
71 this.startingGarrison.push({"template":template, "count": count});
72 this.startingGarrisonCount = Number(this.startingGarrisonCount) + Number(count);
73 }
74 }
75 else
76 warn(key+ ": The maximum garrison capacity of the entity has been reached already.");
77 }
78 }
79};
80
81/**
82 * Execute some magic when the ownership of an entity is given to a player for the first time
83 */
84GarrisonHolder.prototype.OnOwnershipChanged = function(msg)
85{
86 if (msg.from == -1)
87 {
88 if (this.startingGarrisonObtained == false)
89 {
90 this.SpawnStartingGarrison();
91 this.startingGarrisonObtained = true;
92 }
93 }
94};
95
96GarrisonHolder.prototype.PerformGarrison = function(entity, enforce)
97{
98 if (enforce == 0 && !this.HasEnoughHealth())
99 return false;
100
101 // Check if the unit is allowed to be garrisoned inside the building
102 if(!this.AllowedToGarrison(entity))
103 return false;
104
105 // check the capacity
106 var extraCount = 0;
107 var cmpGarrisonHolder = Engine.QueryInterface(entity, IID_GarrisonHolder);
108 if (cmpGarrisonHolder)
109 extraCount += cmpGarrisonHolder.GetGarrisonedEntitiesCount();
110 if (this.GetGarrisonedEntitiesCount() + extraCount >= this.GetCapacity())
111 return false;
112
113 if (!this.timer && this.GetHealRate() > 0)
114 {
115 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
116 this.timer = cmpTimer.SetTimeout(this.entity, IID_GarrisonHolder, "HealTimeout", 1000, {});
117 }
118
119 // Actual garrisoning happens here
120 this.entities.push(entity);
121 this.UpdateGarrisonFlag();
122 var cmpProductionQueue = Engine.QueryInterface(entity, IID_ProductionQueue);
123 if (cmpProductionQueue)
124 cmpProductionQueue.PauseProduction();
125
126 var cmpAura = Engine.QueryInterface(entity, IID_Auras);
127 if (cmpAura && cmpAura.HasGarrisonAura())
128 cmpAura.ApplyGarrisonBonus(this.entity);
129
130 Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
131
132 var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
133 if (cmpUnitAI && cmpUnitAI.IsUnderAlert())
134 Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity});
135
136 return true;
137};
138
139GarrisonHolder.prototype.SpawnStartingGarrison = function()
140{
141 if (this.template.StartingGarrison)
142 {
143 for (let key in this.startingGarrison)
144 {
145 for (let i = 0; i < this.startingGarrison[key].count; ++i)
146 {
147 var newEnt = Engine.AddEntity(this.startingGarrison[key].template);
148 var cmpOwnership = Engine.QueryInterface(newEnt, IID_Ownership);
149 var cmpOwnership2 = Engine.QueryInterface(this.entity, IID_Ownership);
150 if (!cmpOwnership)
151 {
152 Engine.DestroyEntity(newEnt);
153 continue;
154 }
155 cmpOwnership.SetOwner(cmpOwnership2.GetOwner());
156 this.PerformGarrison(newEnt, 1);
157 }
158 }
159 }
160};
161
162Engine.ReRegisterComponentType(IID_GarrisonHolder, "GarrisonHolder", GarrisonHolder);