Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_CampaignSeizingComponent.c
Go to the documentation of this file.
4
5void OnCaptureStateChangedDelegate(SCR_EBaseCaptureState spawnpoint);
7typedef ScriptInvokerBase<OnCaptureStateChangedDelegate> OnCaptureStateChangedInvoker;
8
10{
11 [Attribute("60", params: "0 inf 0.1", category: "Campaign")]
12 protected float m_fExtraTimePerService;
13
14 [Attribute("60", params: "0 inf 0.1", category: "Campaign")]
16
18
19 protected SCR_EBaseCaptureState m_eCaptureState;
21
22 [RplProp()]
24
25 //------------------------------------------------------------------------------------------------
27 {
28 if (!m_Base || m_Base.IsHQ() || !m_Base.IsInitialized())
29 return null;
30
31 SCR_Faction faction = super.EvaluateEntityFaction(ent);
32
33 return faction;
34 }
35
36 //------------------------------------------------------------------------------------------------
37 override protected void OnQueryFinished(BaseGameTriggerEntity trigger)
38 {
39 m_bQueryFinished = true;
40
41 array<IEntity> presentEntities = {};
42 int presentEntitiesCount = m_Trigger.GetEntitiesInside(presentEntities);
43 m_bCharacterPresent = presentEntitiesCount != 0;
44
45 // Nobody is here, no need to evaluate
47 {
48 if (m_eCaptureState != SCR_EBaseCaptureState.NONE)
49 {
50 m_eCaptureState = SCR_EBaseCaptureState.NONE;
53 }
54
56 {
61 }
62
63 return;
64 }
65
66 map<SCR_Faction, int> factionsPresence = new map<SCR_Faction, int>();
67 map<SCR_Faction, bool> factionsPlayerPresence = new map<SCR_Faction, bool>();
68
69 SCR_Faction evaluatedEntityFaction;
70 int factionCount;
71 PlayerManager playerManager = GetGame().GetPlayerManager();
72
73 // Go through all entities and check their factions
74 for (int i = 0; i < presentEntitiesCount; i++)
75 {
76 IEntity entity = presentEntities[i];
77
79 {
80 RplComponent.DeleteRplEntity(entity, false);
81 continue;
82 }
83
84 evaluatedEntityFaction = EvaluateEntityFaction(presentEntities[i]);
85
86 if (!evaluatedEntityFaction)
87 continue;
88
89 factionCount = factionsPresence.Get(evaluatedEntityFaction);
90
91 // If faction is not yet registered, do it now - otherwise just increase its presence counter
92 if (factionCount == 0)
93 factionsPresence.Insert(evaluatedEntityFaction, 1);
94 else
95 factionsPresence.Set(evaluatedEntityFaction, factionCount + 1);
96
97 // Check if there are some players present in case they are required
98 if (m_bCapturingRequiresPlayer && playerManager.GetPlayerIdFromControlledEntity(entity) != 0)
99 factionsPlayerPresence.Set(evaluatedEntityFaction, true);
100 }
101
102 int totalFactionPresenceCount, maxFactionPresence;
104 bool multipleMaxPresence;
105 foreach (SCR_Faction faction, int presence : factionsPresence)
106 {
107 totalFactionPresenceCount += presence;
109
110 if (presence > maxFactionPresence)
111 {
112 maxFactionPresence = presence;
113 multipleMaxPresence = false;
114 }
115 else if (presence == maxFactionPresence)
116 {
117 multipleMaxPresence = true;
118 }
119 }
120
121 Replication.BumpMe();
122
123 SCR_Faction defenderFaction = m_Base.GetCampaignFaction();
124 if (defenderFaction && !factionsPresence.Contains(defenderFaction))
125 factionsPresence.Insert(defenderFaction, 0); // defending faction should always be evaluated to make sure contested is registered properly.
126
127 // prevailing faction is the faction that is able to capture the base, if the defenders are winning prevailing faction is null
128 m_bDeleteDisabledAIs = false;
129 SCR_Faction prevailingFaction;
130 SCR_CampaignFaction cFaction;
131 int curSeizingCharacters;
132
133 SCR_EBaseCaptureState baseCaptureState = SCR_EBaseCaptureState.NONE;
134
135 // Evaluate if capture, needs more than half the amount of players to capture!
136 foreach (SCR_Faction faction, int presence : factionsPresence)
137 {
138 if (faction == defenderFaction)
139 {
140 // if its equal, it will go to the defenders!
141 if (presence * 2 >= totalFactionPresenceCount)
142 {
143 prevailingFaction = null;
144 curSeizingCharacters = 0;
145 }
146 else
147 {
148 // no cap < contested < capture in terms of relevancy so we make sure contested doesnt overwrite capture state
149 if (baseCaptureState == SCR_EBaseCaptureState.NONE)
150 baseCaptureState = SCR_EBaseCaptureState.CONTESTED;
151 }
152 }
153 else
154 {
155 if (!faction.CanCaptureBases())
156 continue;
157
158 // Non-playable attackers are not allowed
160 continue;
161
162 // In case players are required but are not present, ignore this faction for attacking
163 if (m_bCapturingRequiresPlayer && !factionsPlayerPresence.Get(faction))
164 continue;
165
166 // Needs to have superior presence in the area, and radio coverage to be able to capture
167 cFaction = SCR_CampaignFaction.Cast(faction);
168 if (presence == maxFactionPresence && !multipleMaxPresence && cFaction && (!cFaction.IsPlayable() || m_Base.IsHQRadioTrafficPossible(cFaction)))
169 {
170 prevailingFaction = faction;
171 curSeizingCharacters = presence;
172 baseCaptureState = SCR_EBaseCaptureState.CAPTURING;
173 }
174 }
175 }
176
177 // Get amount of effectively seizing characters (clamp for max attackers attribute or set to 0 if there is no prevailing faction)
178 if (prevailingFaction)
179 curSeizingCharacters = Math.Min(totalFactionPresenceCount - curSeizingCharacters, m_iMaximumSeizingCharacters);
180
181 if (baseCaptureState != m_eCaptureState)
182 {
183 m_eCaptureState = baseCaptureState;
186 }
187
188 if (prevailingFaction != m_PrevailingFaction)
189 {
190 m_iSeizingCharacters = curSeizingCharacters;
192 m_PrevailingFaction = prevailingFaction;
194 }
195 else if (prevailingFaction && curSeizingCharacters != m_iSeizingCharacters)
196 {
197 m_iSeizingCharacters = curSeizingCharacters;
199 }
200 }
201
202 //------------------------------------------------------------------------------------------------
203 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
205 {
208 }
209
210 //------------------------------------------------------------------------------------------------
219
220 //------------------------------------------------------------------------------------------------
225
226 //------------------------------------------------------------------------------------------------
227 override void RefreshSeizingTimer()
228 {
230 return;
231
232 int servicesCount;
233
234 if (m_Base)
235 {
236 array<SCR_EServicePointType> checkedTypes = {
238 SCR_EServicePointType.HELIPAD,
239 SCR_EServicePointType.BARRACKS,
240 SCR_EServicePointType.RADIO_ANTENNA,
241 SCR_EServicePointType.FIELD_HOSPITAL,
242 SCR_EServicePointType.LIGHT_VEHICLE_DEPOT,
243 SCR_EServicePointType.HEAVY_VEHICLE_DEPOT
244 };
245
246 foreach (SCR_EServicePointType type : checkedTypes)
247 {
248 if (m_Base.GetServiceDelegateByType(type))
249 servicesCount++;
250 }
251 }
252
253 int radioConnectionsCount;
254 SCR_CoverageRadioComponent comp = SCR_CoverageRadioComponent.Cast(m_Base.GetOwner().FindComponent(SCR_CoverageRadioComponent));
255
256 if (comp)
257 {
258 SCR_CampaignFaction faction = m_Base.GetCampaignFaction();
259
260 if (faction && faction.IsPlayable())
261 radioConnectionsCount = comp.GetRadiosInRangeOfCount(faction.GetFactionRadioEncryptionKey());
262 }
263
264 float seizingTimeVar = m_fMaximumSeizingTime - m_fMinimumSeizingTime;
265 float deduct;
266
267 if (m_iMaximumSeizingCharacters > 1) // Avoid division by 0
268 {
269 float deductPerPlayer = seizingTimeVar / (m_iMaximumSeizingCharacters - 1);
270 deduct = deductPerPlayer * (m_iSeizingCharacters - 1);
271 }
272
273 float multiplier = 1;
274
276 {
277 multiplier += (servicesCount * (m_fExtraTimePerService / (m_fMaximumSeizingTime - m_fMinimumSeizingTime)));
278 multiplier += (radioConnectionsCount * (m_fExtraTimePerRadioConnection / (m_fMaximumSeizingTime - m_fMinimumSeizingTime)));
279 }
280
281 m_fSeizingEndTimestamp = m_fSeizingStartTimestamp.PlusSeconds(multiplier * (m_fMaximumSeizingTime - deduct));
282
283 ChimeraWorld world = GetGame().GetWorld();
284 WorldTimestamp currentTime = world.GetServerTimestamp();
285
286 // Add a tiny delay if removing a service would cause immediate capture
287 if (m_fSeizingEndTimestamp.LessEqual(currentTime))
288 m_fSeizingEndTimestamp = currentTime.PlusMilliseconds(SCR_GameModeCampaign.DEFAULT_DELAY);
289
292
293 Replication.BumpMe();
295 }
296
297// //------------------------------------------------------------------------------------------------
298// //!
299// //! \param[in] maxSeizingTime
300// //! \param[in] minSeizingTime
301// //! \param[in] extraTime
302// //! \param[in] players
303// //! \param[in] services
304// static void TestValues(float maxSeizingTime, float minSeizingTime, float extraTime, int players, int services)
305// {
306// float seizingTimeVar = maxSeizingTime - minSeizingTime;
307// float deductPerPlayer = seizingTimeVar / 11;
308// float deduct = deductPerPlayer * (players - 1);
309// float servicesMultiplier = 1 + (services * (extraTime / (maxSeizingTime - minSeizingTime)));
310// Print(servicesMultiplier * (maxSeizingTime - deduct));
311// }
312
313 //------------------------------------------------------------------------------------------------
314 override void OnBaseRegistered(notnull SCR_MilitaryBaseComponent base)
315 {
316 super.OnBaseRegistered(base);
317
319
320 if (!campaignBase)
321 {
323 base.UnregisterLogicComponent(this);
324 }
325
326 if (!campaignBase || campaignBase.IsHQ())
327 return;
328
329 m_Base = campaignBase;
330 }
331}
332
333[EnumLinear()]
334enum SCR_EBaseCaptureState
336 // No capture happening
337 NONE,
338 // Contested = the amount of defenders are less than the combined amount of attackers from other factions
339 CONTESTED,
340 // Base is being captured by another faction
ArmaReforgerScripted GetGame()
Definition game.c:1398
SCR_CacheNoteComponentClass ScriptComponentClass RplProp()] protected ref array< string > m_aLines
ScriptInvokerBase< OnCaptureStateChangedDelegate > OnCaptureStateChangedInvoker
SCR_CampaignSeizingComponent SCR_SeizingComponent EnumLinear()] enum SCR_EBaseCaptureState
func OnCaptureStateChangedDelegate
EDamageType type
@ CONTESTED
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
void UnregisterBase(notnull SCR_MilitaryBaseComponent base)
Definition Math.c:13
Main replication API.
Definition Replication.c:14
void OnQueryFinished(BaseGameTriggerEntity trigger)
ref OnCaptureStateChangedInvoker m_OnCaptureStateChanged
SCR_CampaignMilitaryBaseComponent m_Base
override SCR_Faction EvaluateEntityFaction(IEntity ent)
override void OnBaseRegistered(notnull SCR_MilitaryBaseComponent base)
OnCaptureStateChangedInvoker GetOnCaptureStateChanged()
bool CanCaptureBases()
bool IsPlayable()
void HandleGradualReset()
When capture started after getting interrupted, take into account the time spent on it.
WorldTimestamp m_fSeizingStartTimestamp
BaseGameTriggerEntity m_Trigger
SCR_Faction m_PrevailingFactionPrevious
WorldTimestamp m_fSeizingEndTimestamp
bool IsDisabledAI(IEntity ent)
Definition Types.c:486
@ NONE
When Shape is created and not initialized yet.
Definition ShapeType.c:15
SCR_FieldOfViewSettings Attribute
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