Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_CaptureArea.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/GameMode", description: "Area that provides basic events and api to serve as a captureable area.")]
5
7void CaptureAreaCharacterEventDelegate(SCR_CaptureArea area, Faction affiliatedFaction, IEntity character);
9typedef ScriptInvokerBase<CaptureAreaCharacterEventDelegate> CaptureAreaEvent;
10
14typedef ScriptInvokerBase<CaptureAreaOwnerFactionEventDelegate> CaptureAreaOwnershipEvent;
15
16//------------------------------------------------------------------------------------------------
23class SCR_CaptureArea : ScriptedGameTriggerEntity
24{
31
34
35 //------------------------------------------------------------------------------------------------
41
44
45 //------------------------------------------------------------------------------------------------
51
54
55 //------------------------------------------------------------------------------------------------
61
66
68 protected RplComponent m_pRplComponent;
69
70 //------------------------------------------------------------------------------------------------
72 protected override void OnInit(IEntity owner)
73 {
74 // Do not spam messages outside of playmode,
75 // these might not be relevant (yet) also
76 // there is no need to initialize the entity (just yet)
77 if (!GetGame().InPlayMode())
78 return;
79
80 // Mandatory, cannot work without factions
81 FactionManager factionManager = GetGame().GetFactionManager();
82 if (!factionManager)
83 {
84 Debug.Error("No faction manager present in the world! Capture area will malfunction!");
85 return;
86 }
87
88 // Neccessary to determine replication logic
89 m_pRplComponent = RplComponent.Cast(FindComponent(RplComponent));
90 if (!m_pRplComponent)
91 {
92 Debug.Error("SCR_CaptureArea requires RplComponent to function!");
93 return;
94 }
95
96 // Enable OnFrame event mask
97 SetEventMask(EntityEvent.FRAME);
98
99 array<Faction> availableFactions = {};
100 factionManager.GetFactionsList(availableFactions);
101
102 // Fetch available actions and preallocate map arrays
103 foreach (Faction faction : availableFactions)
104 m_mOccupants.Insert(faction, new array<SCR_ChimeraCharacter>());
105 }
106
110 protected override bool RplLoad(ScriptBitReader reader)
111 {
112 int factionIndex = -1;
113 reader.ReadInt(factionIndex);
114
115 Faction ownerFaction;
116 if (factionIndex != -1)
117 ownerFaction = GetGame().GetFactionManager().GetFactionByIndex(factionIndex);
118
119 m_pOwnerFaction = ownerFaction;
120 return true;
121 }
122
127 protected override bool RplSave(ScriptBitWriter writer)
128 {
129 int factionIndex = -1;
130 if (m_pOwnerFaction)
131 factionIndex = GetGame().GetFactionManager().GetFactionIndex(m_pOwnerFaction);
132
133 writer.WriteInt(factionIndex);
134 return true;
135 }
136
137 //------------------------------------------------------------------------------------------------
139 protected override bool ScriptedEntityFilterForQuery(IEntity ent)
140 {
141 // Filter for characters only
142 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
143 if (!character)
144 return false;
145
146 // That are alive.
147 return !character.GetCharacterController().IsDead();
148 }
149
150 //------------------------------------------------------------------------------------------------
152 protected override void OnActivate(IEntity ent)
153 {
154 if (!m_mOccupants)
155 return;
156
157 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
158 if (!character)
159 return;
160
161 Faction faction = character.GetFaction();
162 if (!faction)
163 return;
164
165 if (faction && !m_mOccupants[faction].Contains(character))
166 {
167 m_mOccupants[faction].Insert(character);
168 OnCharacterEntered(faction, character);
169 }
170 }
171
172 //------------------------------------------------------------------------------------------------
174 protected event void OnCharacterEntered(Faction faction, SCR_ChimeraCharacter character)
175 {
176 m_pOnCharacterEnter.Invoke(this, faction, character);
177 }
178
179 //------------------------------------------------------------------------------------------------
181 protected override void OnDeactivate(IEntity ent)
182 {
183 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
184 Faction faction = character.GetFaction();
185
186 if (faction)
187 {
188 m_mOccupants[faction].RemoveItem(character);
189 OnCharacterExit(faction, character);
190 }
191 }
192
193 //------------------------------------------------------------------------------------------------
195 protected event void OnCharacterExit(Faction faction, SCR_ChimeraCharacter character)
196 {
197 m_pOnCharacterExit.Invoke(this, faction, character);
198 }
199
200 //------------------------------------------------------------------------------------------------
207 int GetOccupants(Faction faction, notnull array<SCR_ChimeraCharacter> outCharacters)
208 {
209 array<SCR_ChimeraCharacter> characters = m_mOccupants[faction];
210 if (!characters || characters.IsEmpty())
211 return 0;
212
213 outCharacters.Copy(characters);
214 return characters.Count();
215 }
216
217 //------------------------------------------------------------------------------------------------
224 {
225 return m_mOccupants[faction].Count();
226 }
227
228 //------------------------------------------------------------------------------------------------
236 {
237 // Fetch all available factions
238 array<Faction> availableFactions = {};
239 GetGame().GetFactionManager().GetFactionsList(availableFactions);
240
241 int maxCount;
242 Faction maxFaction;
243 int occupantsCount;
244 foreach (Faction faction : availableFactions)
245 {
246 occupantsCount = GetOccupantsCount(faction);
247 if (occupantsCount == 0)
248 continue;
249
250 if (occupantsCount > maxCount)
251 {
252 maxCount = occupantsCount;
253 maxFaction = faction;
254 }
255 }
256
257 // With no alive occupants in the area, no faction can
258 // be deemed as the capturing one
259 if (maxCount == 0)
260 return null;
261
262 return maxFaction;
263 }
264
265 //------------------------------------------------------------------------------------------------
269 protected override event void OnFrame(IEntity owner, float timeSlice)
270 {
271 super.OnFrame(owner, timeSlice);
272
273 // Since trigger can be out of sync with character states,
274 // filter out dead characters if any are left in the collection
275 foreach (Faction faction, array<SCR_ChimeraCharacter> characters : m_mOccupants)
276 {
277 for (int i = characters.Count() - 1; i >= 0; --i)
278 {
279 SCR_ChimeraCharacter occupant = characters[i];
280 if (!occupant || occupant.GetCharacterController().IsDead())
281 {
282 characters.Remove(i);
283 continue;
284 }
285 }
286 }
287
288 // Only the authority will be updating the state,
289 // rpl component is prerequisite for this entity
290 if (!m_pRplComponent || !m_pRplComponent.IsMaster())
291 return;
292
293 Faction newOwner = EvaluateOwnerFaction();
294 if (newOwner != m_pOwnerFaction)
295 {
296 Faction previousOwner = m_pOwnerFaction;
297 SetOwningFactionInternal(previousOwner, newOwner);
298
299 // For the authority, this is fired straight away above,
300 // so we only send the change to all clients as broadcast
301 SetOwningFactionInternalAuthority(previousOwner, newOwner);
302 }
303 }
304
305 //------------------------------------------------------------------------------------------------
308 {
309 FactionManager factionManager = GetGame().GetFactionManager();
310 int previousIndex = factionManager.GetFactionIndex(previousOwner);
311 int newIndex = factionManager.GetFactionIndex(newOwner);
312 Rpc(Rpc_SetOwningFaction_BC, previousIndex, newIndex);
313 }
314
315 //------------------------------------------------------------------------------------------------
317 void SetOwningFactionInternal(Faction previousFaction, Faction newFaction)
318 {
319 m_pOwnerFaction = newFaction;
320 OnOwningFactionChanged(previousFaction, newFaction);
321 }
322
323 //------------------------------------------------------------------------------------------------
328 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
329 protected void Rpc_SetOwningFaction_BC(int previousFactionIndex, int newFactionIndex)
330 {
331 FactionManager factionManager = GetGame().GetFactionManager();
332
333 Faction previousFaction;
334 if (previousFactionIndex != -1)
335 previousFaction = factionManager.GetFactionByIndex(previousFactionIndex);
336
337 Faction newFaction;
338 if (newFactionIndex != -1)
339 newFaction = factionManager.GetFactionByIndex(newFactionIndex);
340
341 SetOwningFactionInternal(previousFaction, newFaction);
342 }
343
344 //------------------------------------------------------------------------------------------------
350 protected event void OnOwningFactionChanged(Faction previousFaction, Faction newFaction)
351 {
352 m_pOnOwnershipChanged.Invoke(this, previousFaction, newFaction);
353 }
354};
ArmaReforgerScripted GetGame()
Definition game.c:1398
func CaptureAreaOwnerFactionEventDelegate
ScriptInvokerBase< CaptureAreaOwnerFactionEventDelegate > CaptureAreaOwnershipEvent
ScriptInvokerBase< CaptureAreaCharacterEventDelegate > CaptureAreaEvent
func CaptureAreaCharacterEventDelegate
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
Definition Debug.c:13
override bool RplLoad(ScriptBitReader reader)
void SetOwningFactionInternal(Faction previousFaction, Faction newFaction)
Sets internal owner faction and raises corresponding callback.
RplComponent m_pRplComponent
Replication component of this entity.
event void OnCharacterExit(Faction faction, SCR_ChimeraCharacter character)
Occurs when a [character] of provided [faction] leaves the area.
override void OnInit(IEntity owner)
Initializes this area by initializing and preallocating required resources.
void SetOwningFactionInternalAuthority(Faction previousOwner, Faction newOwner)
Sets internal owner faction and raises corresponding callback for clients.
ref CaptureAreaEvent m_pOnCharacterEnter
Callback raised when a character enters this area.
override bool RplSave(ScriptBitWriter writer)
CaptureAreaEvent GetCharacterEnterInvoker()
Returns invoker that is invoked when a character enters this area.
override void OnDeactivate(IEntity ent)
callback - deactivation - occurs when and entity which was activated (OnActivate) leaves the Trigger
override bool ScriptedEntityFilterForQuery(IEntity ent)
By default queries only for characters of SCR_ChimeraCharacter type.
ref map< Faction, ref array< SCR_ChimeraCharacter > > m_mOccupants
ref CaptureAreaOwnershipEvent m_pOnOwnershipChanged
Callback raised when a new faction claims ownership of this area.
Faction EvaluateOwnerFaction()
event void OnCharacterEntered(Faction faction, SCR_ChimeraCharacter character)
Occurs when a [character] of provided [faction] enters the area.
Faction GetOwningFaction()
Returns the faction that currently owns the area or null if none.
ref CaptureAreaEvent m_pOnCharacterExit
Callback raised when a character leaves this area.
override void OnActivate(IEntity ent)
callback - activation - occurs when and entity which fulfills the filter definitions enters the Trigg...
int GetOccupantsCount(Faction faction)
event void OnOwningFactionChanged(Faction previousFaction, Faction newFaction)
CaptureAreaOwnershipEvent GetOwnershipChangedEvent()
Returns invoker that is invoked when a faction claims ownership of this area.
override event void OnFrame(IEntity owner, float timeSlice)
CaptureAreaEvent GetCharacterExitInvoker()
Returns invoker that is invoked when a character exits this area.
int GetOccupants(Faction faction, notnull array< SCR_ChimeraCharacter > outCharacters)
void Rpc_SetOwningFaction_BC(int previousFactionIndex, int newFactionIndex)
Faction m_pOwnerFaction
The faction that currently owns this area.
Definition Types.c:486
EntityEvent
Various entity events.
Definition EntityEvent.c:14
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
proto bool Contains(T value)