1 [
EntityEditorProps(
category:
"GameScripted/GameMode", description:
"Area that provides basic events and api to serve as a captureable area.")]
30 protected ref map<Faction, ref array<SCR_ChimeraCharacter>> m_mOccupants =
new map<Faction, ref array<SCR_ChimeraCharacter>>();
39 return m_pOnCharacterEnter;
49 return m_pOnCharacterExit;
59 return m_pOnOwnershipChanged;
63 protected Faction m_pOwnerFaction;
65 Faction GetOwningFaction() {
return m_pOwnerFaction; }
68 protected RplComponent m_pRplComponent;
72 protected override void OnInit(IEntity owner)
81 FactionManager factionManager =
GetGame().GetFactionManager();
84 Debug.Error(
"No faction manager present in the world! Capture area will malfunction!");
89 m_pRplComponent = RplComponent.Cast(FindComponent(RplComponent));
92 Debug.Error(
"SCR_CaptureArea requires RplComponent to function!");
97 SetEventMask(EntityEvent.FRAME);
99 array<Faction> availableFactions = {};
100 factionManager.GetFactionsList(availableFactions);
103 foreach (
Faction faction : availableFactions)
104 m_mOccupants.Insert(faction,
new array<SCR_ChimeraCharacter>());
110 protected override bool RplLoad(ScriptBitReader reader)
112 int factionIndex = -1;
113 reader.ReadInt(factionIndex);
116 if (factionIndex != -1)
117 ownerFaction =
GetGame().GetFactionManager().GetFactionByIndex(factionIndex);
119 m_pOwnerFaction = ownerFaction;
127 protected override bool RplSave(ScriptBitWriter writer)
129 int factionIndex = -1;
131 factionIndex =
GetGame().GetFactionManager().GetFactionIndex(m_pOwnerFaction);
133 writer.WriteInt(factionIndex);
139 protected override bool ScriptedEntityFilterForQuery(IEntity ent)
142 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
147 return !character.GetCharacterController().IsDead();
152 protected override void OnActivate(IEntity ent)
157 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
161 Faction faction = character.GetFaction();
165 if (faction && !m_mOccupants[faction].
Contains(character))
167 m_mOccupants[faction].Insert(character);
168 OnCharacterEntered(faction, character);
174 protected event void OnCharacterEntered(
Faction faction, SCR_ChimeraCharacter character)
176 m_pOnCharacterEnter.Invoke(
this, faction, character);
181 protected override void OnDeactivate(IEntity ent)
183 SCR_ChimeraCharacter character = SCR_ChimeraCharacter.Cast(ent);
184 Faction faction = character.GetFaction();
188 m_mOccupants[faction].RemoveItem(character);
189 OnCharacterExit(faction, character);
195 protected event void OnCharacterExit(
Faction faction, SCR_ChimeraCharacter character)
197 m_pOnCharacterExit.Invoke(
this, faction, character);
207 int GetOccupants(
Faction faction, notnull array<SCR_ChimeraCharacter> outCharacters)
209 array<SCR_ChimeraCharacter> characters = m_mOccupants[faction];
210 if (!characters || characters.IsEmpty())
213 outCharacters.Copy(characters);
214 return characters.Count();
223 int GetOccupantsCount(
Faction faction)
225 return m_mOccupants[faction].Count();
235 protected Faction EvaluateOwnerFaction()
238 array<Faction> availableFactions = {};
239 GetGame().GetFactionManager().GetFactionsList(availableFactions);
244 foreach (
Faction faction : availableFactions)
246 occupantsCount = GetOccupantsCount(faction);
247 if (occupantsCount == 0)
250 if (occupantsCount > maxCount)
252 maxCount = occupantsCount;
253 maxFaction = faction;
269 protected override event void OnFrame(IEntity owner,
float timeSlice)
271 super.OnFrame(owner, timeSlice);
275 foreach (
Faction faction, array<SCR_ChimeraCharacter> characters : m_mOccupants)
277 for (
int i = characters.Count() - 1; i >= 0; --i)
279 SCR_ChimeraCharacter occupant = characters[i];
280 if (!occupant || occupant.GetCharacterController().IsDead())
282 characters.Remove(i);
290 if (!m_pRplComponent || !m_pRplComponent.IsMaster())
293 Faction newOwner = EvaluateOwnerFaction();
294 if (newOwner != m_pOwnerFaction)
296 Faction previousOwner = m_pOwnerFaction;
297 SetOwningFactionInternal(previousOwner, newOwner);
301 FactionManager factionManager =
GetGame().GetFactionManager();
302 int previousIndex = factionManager.GetFactionIndex(previousOwner);
303 int newIndex = factionManager.GetFactionIndex(newOwner);
304 Rpc(Rpc_SetOwningFaction_BC, previousIndex, newIndex);
310 protected void SetOwningFactionInternal(
Faction previousFaction,
Faction newFaction)
312 m_pOwnerFaction = newFaction;
313 OnOwningFactionChanged(previousFaction, newFaction);
321 [
RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
322 protected void Rpc_SetOwningFaction_BC(
int previousFactionIndex,
int newFactionIndex)
324 FactionManager factionManager =
GetGame().GetFactionManager();
327 if (previousFactionIndex != -1)
328 previousFaction = factionManager.GetFactionByIndex(previousFactionIndex);
331 if (newFactionIndex != -1)
332 newFaction = factionManager.GetFactionByIndex(newFactionIndex);
334 SetOwningFactionInternal(previousFaction, newFaction);
343 protected event void OnOwningFactionChanged(
Faction previousFaction,
Faction newFaction)
345 m_pOnOwnershipChanged.Invoke(
this, previousFaction, newFaction);