Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_GameModeCampaign.c
Go to the documentation of this file.
2{
3}
4
5//------------------------------------------------------------------------------------------------
7{
8 [Attribute("1", desc: "Terminate the scenario when Conflict is finished.", category: "Campaign")]
9 protected bool m_bTerminateScenario;
10
11 [Attribute("2", desc: "How many control points does a faction need to win", params: "1 inf 1", category: "Campaign")]
12 protected int m_iControlPointsThreshold;
13
14 [Attribute("300", desc: "How long does a faction need to hold the control points to win (seconds).", params: "0 inf 1", category: "Campaign")]
15 protected float m_fVictoryTimer;
16
17 [Attribute("1000", desc: "Supplies will be autoreplenished in bases until this limit is reached.", params: "0 inf 1", category: "Campaign")]
18 protected int m_iSuppliesReplenishThreshold;
19
20 [Attribute("200", desc: "Supplies will be autoreplenished in bases quickly until this limit is reached (HQs are not affected).", params: "0 inf 1", category: "Campaign")]
21 protected int m_iQuickSuppliesReplenishThreshold;
22
23 [Attribute("2", desc: "Supplies income will be multiplied by this number unless the quick replenish threshold has been reached.", params: "1 inf 0.05", category: "Campaign")]
24 protected float m_fQuickSuppliesReplenishMultiplier;
25
26 [Attribute("5", desc: "How often are supplies replenished in bases (seconds).", params: "1 inf 1", category: "Campaign")]
27 protected int m_iSuppliesArrivalInterval;
28
29 [Attribute("40", desc: "How many supplies are periodically replenished in HQs.", params: "0 inf 1", category: "Campaign")]
30 protected int m_iRegularSuppliesIncome;
31
32 [Attribute("4", desc: "How many supplies are periodically replenished in non-HQ bases.", params: "0 inf 1", category: "Campaign")]
33 protected int m_iRegularSuppliesIncomeBase;
34
35 [Attribute("4", desc: "How many extra supplies are periodically replenished in non-HQ bases per base connected via radio.", params: "0 inf 1", category: "Campaign")]
36 protected int m_iRegularSuppliesIncomeExtra;
37
38 [Attribute("600", desc: "The amount of supplies in HQs.", params: "0 inf 1", category: "Campaign")]
39 protected int m_iHQStartingSupplies;
40
41 [Attribute("100", desc: "When randomized, the least supplies a base can hold at the start.", params: "0 inf 1", category: "Campaign")]
42 protected int m_iMinStartingSupplies;
43
44 [Attribute("500", desc: "When randomized, the most supplies a base can hold at the start.", params: "0 inf 1", category: "Campaign")]
45 protected int m_iMaxStartingSupplies;
46
47 [Attribute("25", desc: "The step by which randomized supplies will be added in randomization. Min and Max limits should be divisible by this.", params: "1 inf 1", category: "Campaign")]
48 protected int m_iStartingSuppliesInterval;
49
50 [Attribute("0.5", desc: "Fraction of XP awarded to players unloading supplies which they have not loaded themselves.", params: "0 inf", category: "Campaign")]
51 protected float m_fSupplyOffloadAssistanceReward;
52
53 [Attribute("US", category: "Campaign")]
54 protected FactionKey m_sBLUFORFactionKey;
55
56 [Attribute("USSR", category: "Campaign")]
57 protected FactionKey m_sOPFORFactionKey;
58
59 [Attribute("FIA", category: "Campaign")]
60 protected FactionKey m_sINDFORFactionKey;
61
62 [Attribute("RNGD", category: "Campaign")]
63 protected FactionKey m_sRNGDFactionKey;
64
65 [Attribute("1", UIWidgets.CheckBox, "Randomized starting supplies in small bases", category: "Campaign")]
66 protected bool m_bRandomizeSupplies;
67
68 [Attribute("1200", UIWidgets.EditBox, "The furthest an independent supply depot can be from the nearest base to still be visible in the map.", params: "0 inf 1", category: "Campaign")]
69 protected int m_iSupplyDepotIconThreshold;
70
71 [Attribute("{B3E7B8DC2BAB8ACC}Prefabs/AI/Waypoints/AIWaypoint_SearchAndDestroy.et", category: "Campaign")]
72 protected ResourceName m_sSeekDestroyWaypointPrefab;
73
74 [Attribute("1800", UIWidgets.EditBox, "If suicide is committed more than once in this time (seconds), a respawn penalty is issued.", params: "0 inf 1", category: "Campaign")]
76
77 [Attribute("30", UIWidgets.EditBox, "Stacking extra deploy cooldown after suicide (seconds). Gets deducted over time.", params: "0 inf 1", category: "Campaign")]
79
80 [Attribute("600", UIWidgets.EditBox, "How often is the post-suicide deploy cooldown penalty deducted (seconds).", params: "0 inf 1", category: "Campaign")]
82
83 [Attribute("0", UIWidgets.CheckBox, "Player can volunteer for Commander role", category: "Campaign")]
85
86 [Attribute("2000", desc: "HQ candidates with greater distance than this are considered for selection", params: "0 inf 1", category: "Campaign")]
88
89 [Attribute("3000", desc: "HQ candidates with greater distance than this are preferred for selection", params: "0 inf 1", category: "Campaign")]
91
92 [Attribute("0", UIWidgets.CheckBox, "Players can establish bases. If disabled, the game starts with existing FOBs", category: "Campaign")]
94
95 [Attribute("0", UIWidgets.CheckBox, "INDFOR players can spawn on bases at the start of the game", category: "Campaign")]
97
98 [Attribute("0", UIWidgets.CheckBox, "INDFOR players can spawn on distant bases at the start of the game", category: "Campaign")]
100
101 [Attribute("0", UIWidgets.CheckBox, desc: "When enabled, random caches will spawn around the map")]
102 protected bool m_bSpawnRandomCaches;
103
104 [Attribute("0", UIWidgets.CheckBox, desc: "When enabled, are allowed to have a Randomized Spawnpoint")]
106
107 [Attribute("0", UIWidgets.CheckBox, "When enabled, FOBs automatically regenerate supplies", category: "Campaign")]
109
110 [Attribute("300", desc: "How often are supplies replenished in source bases (seconds).", params: "1 inf 1", category: "Campaign")]
112
113 [Attribute("2500", desc: "How many supplies are periodically replenished in source bases.", params: "0 inf 1", category: "Campaign")]
115
116 [Attribute("1", desc: "Priority of HQ spawn point in spawn point list. Spawn points are listed from highest priority to lowest.", params: "0 inf 1", category: "Campaign")]
118
119 [Attribute(SCR_ECharacterRank.PRIVATE.ToString(), uiwidget: UIWidgets.ComboBox, desc: "All players will start the match at this rank.", enums: ParamEnumArray.FromEnum(SCR_ECharacterRank), category: "Campaign")]
120 protected SCR_ECharacterRank m_eStartingRank;
121
122 [Attribute("-1", desc: "Maximum amount of bases that can be established per faction. The amount of Established bases is also limited by the amount of callsigns. If value of -1 is used, the amount of established bases is only limited by callsign amount.", params: "-1 inf 1", category: "Campaign")]
124
125 [Attribute("{11A29F36F362D318}Prefabs/MP/Campaign/SCR_HQRadioSoundEntity.et", desc:"Entity with a sound component that is used to load and play HQ radio sounds.", params: "et", category: "Campaign")]
127
128 static const int MINIMUM_DELAY = 100;
129 static const int UI_UPDATE_DELAY = 250;
130 static const int MEDIUM_DELAY = 1000;
131 static const int DEFAULT_DELAY = 2000;
132 static const int BACKEND_DELAY = 25000;
133
139
140 protected ref array<SCR_PlayerRadioSpawnPointCampaign> m_aRadioSpawnPoints = {};
141 protected ref array<ref SCR_CampaignClientData> m_aRegisteredClients = {};
142
144 protected bool m_bIsTutorial;
145 protected bool m_bMatchOver;
146
148
149 [RplProp(onRplName: "OnStarted")]
150 protected bool m_bStarted;
151
152 [RplProp(onRplName: "OnMatchSituationChanged")]
154
155 [RplProp(onRplName: "OnMatchSituationChanged")]
157
158 [RplProp(onRplName: "OnMatchSituationChanged")]
160
161 [RplProp(onRplName: "OnCallsignOffsetChanged")]
162 protected int m_iCallsignOffset = SCR_MilitaryBaseComponent.INVALID_BASE_CALLSIGN;
163
164 //------------------------------------------------------------------------------------------------
169
170 //------------------------------------------------------------------------------------------------
175
176 //------------------------------------------------------------------------------------------------
178 {
180 }
181
182 //------------------------------------------------------------------------------------------------
187
188 //------------------------------------------------------------------------------------------------
193
194 //------------------------------------------------------------------------------------------------
199
200 //------------------------------------------------------------------------------------------------
205
206 //------------------------------------------------------------------------------------------------
211
212 //------------------------------------------------------------------------------------------------
217
218 //------------------------------------------------------------------------------------------------
223
224 //------------------------------------------------------------------------------------------------
225 SCR_ECharacterRank GetStartingRank()
226 {
227 return m_eStartingRank;
228 }
229
230 //------------------------------------------------------------------------------------------------
235
236 //------------------------------------------------------------------------------------------------
241
242 //------------------------------------------------------------------------------------------------
251
252 //------------------------------------------------------------------------------------------------
255 {
256 if (!m_OnStarted)
258
259 return m_OnStarted;
260 }
261
262 //------------------------------------------------------------------------------------------------
271
272 //------------------------------------------------------------------------------------------------
280
281 //------------------------------------------------------------------------------------------------
289
290 //------------------------------------------------------------------------------------------------
292 {
293 return m_iSuppliesReplenishThreshold;
294 }
295
296 //------------------------------------------------------------------------------------------------
298 {
299 return m_iQuickSuppliesReplenishThreshold;
300 }
301
302 //------------------------------------------------------------------------------------------------
304 {
305 return m_fQuickSuppliesReplenishMultiplier;
306 }
307
308 //------------------------------------------------------------------------------------------------
310 {
311 return m_iSuppliesArrivalInterval;
312 }
313
314 //------------------------------------------------------------------------------------------------
316 {
317 return m_iRegularSuppliesIncome;
318 }
319
320 //------------------------------------------------------------------------------------------------
325
326 //------------------------------------------------------------------------------------------------
328 {
329 return m_iRegularSuppliesIncomeExtra;
330 }
331
332 //------------------------------------------------------------------------------------------------
334 {
335 return m_iSupplyDepotIconThreshold;
336 }
337
338 //------------------------------------------------------------------------------------------------
343
344 //------------------------------------------------------------------------------------------------
346 {
347 return m_fVictoryTimer;
348 }
349
350 //------------------------------------------------------------------------------------------------
352 {
353 return m_iControlPointsThreshold;
354 }
355
356 //------------------------------------------------------------------------------------------------
358 {
359 return m_iMinStartingSupplies;
360 }
361
362 //------------------------------------------------------------------------------------------------
364 {
365 return m_iMaxStartingSupplies;
366 }
367
368 //------------------------------------------------------------------------------------------------
370 {
371 return m_iStartingSuppliesInterval;
372 }
373
374 //------------------------------------------------------------------------------------------------
376 {
377 return m_fSupplyOffloadAssistanceReward;
378 }
379
380 //------------------------------------------------------------------------------------------------
382 {
383 return m_sSeekDestroyWaypointPrefab;
384 }
385
386 //------------------------------------------------------------------------------------------------
388 {
390 }
391
392 //------------------------------------------------------------------------------------------------
394 {
395 return m_iWinningFactionId;
396 }
397
398 //------------------------------------------------------------------------------------------------
403
404 //------------------------------------------------------------------------------------------------
409
410 //------------------------------------------------------------------------------------------------
412 {
413 return m_bIsTutorial;
414 }
415
416 //------------------------------------------------------------------------------------------------
418 {
419 return m_bMatchOver;
420 }
421
422 //------------------------------------------------------------------------------------------------
424 {
425 return m_bStarted;
426 }
427
428 //------------------------------------------------------------------------------------------------
430 {
431 return m_iCallsignOffset;
432 }
433
434 //------------------------------------------------------------------------------------------------
435 [Friend(SCR_GameModeCampaignSerializer)]
436 protected void SetCallsignOffset(int offset)
437 {
438 if (m_iCallsignOffset == offset)
439 return;
440
441 m_iCallsignOffset = offset;
442
443 Replication.BumpMe();
445 }
446
447 //------------------------------------------------------------------------------------------------
453
454 //------------------------------------------------------------------------------------------------
455 override bool RplSave(ScriptBitWriter writer)
456 {
457 // Sync respawn radios & control points amount
458 writer.WriteInt(m_BaseManager.GetTargetActiveBasesCount());
459
460 int controlPointsHeldBLUFOR;
461 int controlPointsHeldOPFOR;
462
465
466 if (factionBLUFOR)
467 controlPointsHeldBLUFOR = factionBLUFOR.GetControlPointsHeld();
468
469 if (factionOPFOR)
470 controlPointsHeldOPFOR = factionOPFOR.GetControlPointsHeld();
471
472 writer.WriteInt(controlPointsHeldBLUFOR);
473 writer.WriteInt(controlPointsHeldOPFOR);
474
475 return true;
476 }
477
478 //------------------------------------------------------------------------------------------------
479 override bool RplLoad(ScriptBitReader reader)
480 {
481 // Sync respawn radios & control points amount
482 int activeBasesTotal;
483
484 reader.ReadInt(activeBasesTotal);
485
486 m_BaseManager.SetTargetActiveBasesCount(activeBasesTotal);
487
488 if (m_BaseManager.GetActiveBasesCount() == activeBasesTotal)
489 m_BaseManager.OnAllBasesInitialized();
490
491 int controlPointsHeldBLUFOR, controlPointsHeldOPFOR
492
493 reader.ReadInt(controlPointsHeldBLUFOR);
494 reader.ReadInt(controlPointsHeldOPFOR);
495
496 GetFactionByEnum(SCR_ECampaignFaction.BLUFOR).SetControlPointsHeld(controlPointsHeldBLUFOR);
497 GetFactionByEnum(SCR_ECampaignFaction.OPFOR).SetControlPointsHeld(controlPointsHeldOPFOR);
498
499 return true;
500 }
501
502 //------------------------------------------------------------------------------------------------
503 static SCR_GameModeCampaign GetInstance()
504 {
506 }
507
508 //------------------------------------------------------------------------------------------------
512 SCR_CampaignClientData GetClientData(int playerId, bool create = false)
513 {
514 if (playerId == 0)
515 return null;
516
517 const UUID playerIdentity = SCR_PlayerIdentityUtils.GetPlayerIdentityId(playerId);
518 if (playerIdentity.IsNull())
519 return null;
520
521 SCR_CampaignClientData clientData;
522
523 for (int i = 0, clientsCount = m_aRegisteredClients.Count(); i < clientsCount; i++)
524 {
525 if (m_aRegisteredClients[i].GetID() == playerIdentity)
526 {
527 clientData = m_aRegisteredClients[i];
528 break;
529 }
530 }
531
532 if (!clientData && create)
533 {
534 clientData = new SCR_CampaignClientData();
535 clientData.SetID(playerIdentity);
536 m_aRegisteredClients.Insert(clientData);
537 }
538
539 return clientData;
540 }
541
542 //------------------------------------------------------------------------------------------------
543 void SetControlPointsHeld(SCR_CampaignFaction faction, int newCount)
544 {
545 if (faction.GetControlPointsHeld() == newCount)
546 return;
547
548 int index = GetGame().GetFactionManager().GetFactionIndex(faction);
549
550 Rpc(RPC_DoSetControlPointsHeld, index, newCount);
552 }
553
554 //------------------------------------------------------------------------------------------------
555 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
556 protected void RPC_DoSetControlPointsHeld(int factionIndex, int count)
557 {
558 SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(GetGame().GetFactionManager().GetFactionByIndex(factionIndex));
559
560 if (!faction)
561 return;
562
563 faction.SetControlPointsHeld(count);
565 }
566
567 //------------------------------------------------------------------------------------------------
568 void BroadcastMHQFeedback(SCR_EMobileAssemblyStatus msgID, int playerID, int factionID)
569 {
570 Rpc(RpcDo_BroadcastMHQFeedback, msgID, playerID, factionID);
571
572 if (RplSession.Mode() != RplMode.Dedicated)
573 RpcDo_BroadcastMHQFeedback(msgID, playerID, factionID);
574 }
575
576 //------------------------------------------------------------------------------------------------
577 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
578 void RpcDo_BroadcastMHQFeedback(SCR_EMobileAssemblyStatus msgID, int playerID, int factionID)
579 {
580 SCR_CampaignFeedbackComponent comp = SCR_CampaignFeedbackComponent.GetInstance();
581
582 if (!comp)
583 return;
584
585 comp.MobileAssemblyFeedback(msgID, playerID, factionID)
586 }
587
588 //------------------------------------------------------------------------------------------------
589 protected void Start()
590 {
591 if (IsProxy() || m_bStarted)
592 return;
593
596
597 m_BaseManager.UpdateBases(true);
598
599 m_bStarted = true;
600 Replication.BumpMe();
601 m_BaseManager.OnAllBasesInitialized();
602 OnStarted();
603 }
604
605 //------------------------------------------------------------------------------------------------
606 protected void InitalBaseSetup()
607 {
608 // Compose custom bases array from header
610 if (!baseManager)
611 return;
612
613 float hQSupplies = m_iHQStartingSupplies;
614 bool whitelist = false;
615 array<string> customBaseList = {};
616
617 SCR_MissionHeaderCampaign header = SCR_MissionHeaderCampaign.Cast(GetGame().GetMissionHeader());
618 if (header)
619 {
620 if (header.m_iStartingHQSupplies != -1)
621 hQSupplies = header.m_iStartingHQSupplies;
622
623 whitelist = header.m_bCustomBaseWhitelist;
624 foreach (SCR_CampaignCustomBase customBase : header.m_aCampaignCustomBaseList)
625 {
626 customBaseList.Insert(customBase.GetBaseName());
627 }
628 }
629
630 array<SCR_CampaignMilitaryBaseComponent> candidatesForHQ = {};
631 array<SCR_CampaignMilitaryBaseComponent> controlPoints = {};
632 array<SCR_MilitaryBaseComponent> bases = {};
633 baseManager.GetBases(bases);
634
635 foreach (SCR_MilitaryBaseComponent base : bases)
636 {
638 if (!campaignBase)
639 continue;
640
641 // Ignore the base if it's disabled in mission header
642 if (header)
643 {
644 const string baseName = campaignBase.GetOwner().GetName();
645 const int listIndex = customBaseList.Find(baseName);
646
647 if (listIndex != -1)
648 {
649 if (!whitelist)
650 continue;
651 }
652 else if (whitelist)
653 {
654 continue;
655 }
656
657 if (whitelist && listIndex != -1)
658 campaignBase.ApplyHeaderSettings(header.m_aCampaignCustomBaseList[listIndex]);
659 }
660
661 if (!campaignBase.CanBeHQ())
662 campaignBase.Initialize();
663
664 if (campaignBase.CanBeHQ())
665 candidatesForHQ.Insert(campaignBase);
666
667 if (campaignBase.IsControlPoint())
668 controlPoints.Insert(campaignBase);
669 }
670
671 if (candidatesForHQ.Count() < 2)
672 {
673 Print("Not enough suitable starting locations found in current setup. Check 'Can Be HQ' attributes in SCR_CampaignMilitaryBaseComponent!", LogLevel.ERROR);
674 return;
675 }
676
677 // Process HQ selection
678 array<SCR_CampaignMilitaryBaseComponent> selectedHQs = {};
679
680 m_BaseManager.SelectHQs(candidatesForHQ, controlPoints, selectedHQs);
681 m_BaseManager.SetHQFactions(selectedHQs);
682 // Call analytic event
683 //SCR_AnalyticsApplication.GetInstance().OnMOBSelected(selectedHQs);
684
685 foreach (SCR_CampaignMilitaryBaseComponent hq : selectedHQs)
686 {
687 hq.SetAsHQ(true);
688 hq.SetStartingSupplies(hQSupplies);
689 hq.Initialize();
690 }
691
692 foreach (SCR_CampaignMilitaryBaseComponent candidate : candidatesForHQ)
693 {
694 if (candidate.IsHQ())
695 continue;
696
697 if (!candidate.DisableWhenUnusedAsHQ())
698 {
699 candidate.Initialize();
700 continue;
701 }
702
703 RplComponent baseRplComponent = RplComponent.Cast(candidate.GetOwner().FindComponent(RplComponent));
704 if (!baseRplComponent)
705 continue;
706
707 baseManager.UnregisterBase(candidate);
708 baseRplComponent.DeleteRplEntity(candidate.GetOwner(), false);
709 }
710
711 m_BaseManager.UpdateBases();
712
713 m_BaseManager.InitializeBases(selectedHQs, m_bRandomizeSupplies);
714
715 if (m_iCallsignOffset == SCR_MilitaryBaseComponent.INVALID_BASE_CALLSIGN)
716 {
717 const int basesCount = baseManager.GetBasesCount();
718 const int basesHalf = Math.Ceil(basesCount * 0.5);
719 const int offset = Math.RandomIntInclusive(1, basesHalf);
720 SetCallsignOffset(offset);
721 }
722 }
723
724 //------------------------------------------------------------------------------------------------
725 protected void OnStarted()
726 {
728 if (coverageSystem)
729 coverageSystem.TogglePeriodicUpdates(false);
730
731 if (IsMaster())
732 {
733 // Start periodical checks for winning faction
734 GetGame().GetCallqueue().CallLater(CheckForWinner, DEFAULT_DELAY, true);
735
736 SCR_CharacterRankComponent.s_OnRankChanged.Insert(OnRankChanged);
737
739 if (vehiclesManager)
740 vehiclesManager.GetOnVehicleSpawned().Insert(OnAmbientVehicleSpawned);
741
742 array<SCR_SpawnPoint> spawnpoints = SCR_SpawnPoint.GetSpawnPoints();
743 foreach (SCR_SpawnPoint spawnpoint : spawnpoints)
744 {
745 if (!spawnpoint)
746 continue;
747
748 DisableExtraSpawnpoint(spawnpoint);
749 SetPrioritySpawnpoint(spawnpoint);
750 }
751
752 SCR_SpawnPoint.Event_SpawnPointAdded.Insert(DisableExtraSpawnpoint);
753 }
754
755 SCR_SpawnPoint.Event_SpawnPointFactionAssigned.Insert(OnSpawnPointFactionAssigned);
756
757 if (m_OnStarted)
758 m_OnStarted.Invoke();
759 }
760
761 //------------------------------------------------------------------------------------------------
762 override void OnPlayerRegistered(int playerId)
763 {
764 super.OnPlayerRegistered(playerId);
765
767 if (!localController)
768 return;
769
770 if (playerId != localController.GetPlayerId())
771 return; // Not about own local controller
772
774 if (!playerFactionAff)
775 return;
776
777 // Listen for future changes
779
780 const SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(playerFactionAff.GetAffiliatedFaction());
781 if (faction) // Faction known already so trigger event
782 OnLocalPlayerFactionAssigned(playerFactionAff, null, faction);
783 }
784
785 //------------------------------------------------------------------------------------------------
791
792 //------------------------------------------------------------------------------------------------
793 protected void DisableExtraSpawnpoint(SCR_SpawnPoint spawnpoint)
794 {
796 spawnpoint.SetFaction(null);
797
798 if (spawnpoint.Type() != SCR_SpawnPoint)
799 return;
800
801 spawnpoint.SetFaction(null);
802 }
803
804 //------------------------------------------------------------------------------------------------
805 protected void SetPrioritySpawnpoint(SCR_SpawnPoint spawnpoint)
806 {
807 IEntity spawnpointParent = spawnpoint.GetRootParent();
808 if (!spawnpointParent)
809 return;
810
812 if (!baseComponent || !baseComponent.IsHQ())
813 return;
814
816 }
817
818 //------------------------------------------------------------------------------------------------
820 protected void CheckForWinner()
821 {
822 FactionManager factionManager = GetGame().GetFactionManager();
823 array<Faction> factions = {};
824 factionManager.GetFactionsList(factions);
825 ChimeraWorld world = GetWorld();
826 WorldTimestamp curTime = world.GetServerTimestamp();
827 WorldTimestamp lowestVictoryTimestamp;
828 WorldTimestamp blockPauseTimestamp;
829 WorldTimestamp actualVictoryTimestamp;
830 SCR_CampaignFaction winner;
831
832 foreach (Faction faction : factions)
833 {
834 SCR_CampaignFaction fCast = SCR_CampaignFaction.Cast(faction);
835
836 if (!fCast || !fCast.IsPlayable() || fCast == GetFactionByEnum(SCR_ECampaignFaction.INDFOR))
837 continue;
838
839 blockPauseTimestamp = fCast.GetPauseByBlockTimestamp();
840
841 if (blockPauseTimestamp == 0)
842 actualVictoryTimestamp = fCast.GetVictoryTimestamp();
843 else
844 actualVictoryTimestamp = curTime.PlusMilliseconds(
845 fCast.GetVictoryTimestamp().DiffMilliseconds(fCast.GetPauseByBlockTimestamp())
846 );
847
848 if (actualVictoryTimestamp != 0)
849 {
850 if (!winner || actualVictoryTimestamp.Less(lowestVictoryTimestamp))
851 {
852 lowestVictoryTimestamp = actualVictoryTimestamp;
853 winner = fCast;
854 }
855 }
856 }
857
858 if (winner)
859 {
860 if (lowestVictoryTimestamp.LessEqual(curTime))
861 {
862 GetGame().GetCallqueue().Remove(CheckForWinner);
863 int winnerId = factionManager.GetFactionIndex(winner);
864 RPC_DoEndMatch(winnerId);
865 Rpc(RPC_DoEndMatch, winnerId);
867 }
868 else if (factionManager.GetFactionIndex(winner) != m_iWinningFactionId || winner.GetVictoryTimestamp() != m_fVictoryTimestamp || winner.GetPauseByBlockTimestamp() != m_fVictoryPauseTimestamp)
869 {
870 m_iWinningFactionId = factionManager.GetFactionIndex(winner);
874 Replication.BumpMe();
875 }
876 }
877 else if (m_iWinningFactionId != -1 || m_fVictoryTimestamp != 0)
878 {
880 m_fVictoryTimestamp = null;
883 Replication.BumpMe();
884 }
885 }
886
887 //------------------------------------------------------------------------------------------------
888 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
889 protected void RPC_DoEndMatch(int winningFactionId)
890 {
891 m_bMatchOver = true;
892
893 if (IsProxy())
894 return;
895
896 FactionManager fManager = GetGame().GetFactionManager();
897 array<Faction> factions = {};
898 fManager.GetFactionsList(factions);
899 Faction winningFaction = fManager.GetFactionByIndex(winningFactionId);
900
901 if (winningFaction)
902 {
903 foreach (Faction faction : factions)
904 {
906
907 if (!f)
908 continue;
909
910 if (winningFaction == f)
911 f.SendHQMessage(SCR_ERadioMsg.VICTORY, param: winningFactionId);
912 else
913 f.SendHQMessage(SCR_ERadioMsg.DEFEAT, param: winningFactionId);
914 }
915 }
916
917 // Match is over, save it so if "Continue" is selected following this the game is not loaded at an end screen
918 //GetGame().GetSaveManager().Save(ESaveType.AUTO);
919
920 // For the server end the game, replicate to all clients.
921 // listening components can react to this by e.g. showing end screen
922 if (m_bTerminateScenario)
923 {
924 SCR_GameModeEndData endData = SCR_GameModeEndData.CreateSimple(EGameOverTypes.ENDREASON_SCORELIMIT, winnerFactionId: winningFactionId);
925 EndGameMode(endData);
926 }
927 }
928 //------------------------------------------------------------------------------------------------
929 override void OnGameStart()
930 {
931 super.OnGameStart();
932
933 if (GetGame().InPlayMode() && IsMaster())
934 Start();
935 }
936
937 //------------------------------------------------------------------------------------------------
939 {
940 switch (faction)
941 {
942 case SCR_ECampaignFaction.INDFOR:
943 return m_sINDFORFactionKey;
944
945 case SCR_ECampaignFaction.BLUFOR:
946 return m_sBLUFORFactionKey;
947
948 case SCR_ECampaignFaction.OPFOR:
949 return m_sOPFORFactionKey;
950
951 case SCR_ECampaignFaction.RNGD:
952 return m_sRNGDFactionKey;
953 }
954
955 return FactionKey.Empty;
956 }
957
958 //------------------------------------------------------------------------------------------------
960 {
961 FactionManager fManager = GetGame().GetFactionManager();
962
963 if (!fManager)
964 return null;
965
966 return SCR_CampaignFaction.Cast(fManager.GetFactionByKey(GetFactionKeyByEnum(faction)));
967 }
968
969 //------------------------------------------------------------------------------------------------
970 bool IsProxy()
971 {
972 return (m_RplComponent && m_RplComponent.IsProxy());
973 }
974
975 //------------------------------------------------------------------------------------------------
977 // TRUE, if rank requirement is disabled
982
983 //------------------------------------------------------------------------------------------------
984 void SetIsTutorial(bool isTutorial)
985 {
986 m_bIsTutorial = isTutorial;
987
988 if (m_bIsTutorial)
990 else
992 }
993
994 //------------------------------------------------------------------------------------------------
995 protected void OnAmbientVehicleSpawned(SCR_AmbientVehicleSpawnPointComponent spawnpoint, Vehicle vehicle)
996 {
997 SCR_HelicopterDamageManagerComponent helicopterDamageManager = SCR_HelicopterDamageManagerComponent.Cast(vehicle.FindComponent(SCR_HelicopterDamageManagerComponent));
998
999 // Ignore non-helicopter vehicles
1000 if (!helicopterDamageManager)
1001 return;
1002
1003 array<HitZone> hitZones = {};
1004 helicopterDamageManager.GetAllHitZonesInHierarchy(hitZones);
1005 vector transform[3];
1006 transform[0] = vehicle.GetOrigin();
1007 transform[1] = vector.Forward;
1008 transform[2] = vector.Up;
1009
1010 DamageManagerComponent damageManager;
1011
1012 // Damage the engine and hull
1013 foreach (HitZone hitZone : hitZones)
1014 {
1015 if (!hitZone.IsInherited(SCR_EngineHitZone) && !hitZone.IsInherited(SCR_FlammableHitZone))
1016 continue;
1017
1018 damageManager = DamageManagerComponent.Cast(hitZone.GetHitZoneContainer());
1019 if (!damageManager)
1020 continue;
1021
1022 SCR_DamageContext damageContext = new SCR_DamageContext(EDamageType.TRUE, hitZone.GetMaxHealth() * 0.75, transform, damageManager.GetOwner(), hitZone, Instigator.CreateInstigator(null), null, -1, -1);
1023 helicopterDamageManager.HandleDamage(damageContext);
1024 }
1025
1026 array<SCR_FuelManagerComponent> fuelManagers = {};
1027 array<BaseFuelNode> fuelNodes = {};
1028 SCR_FuelManagerComponent.GetAllFuelManagers(vehicle, fuelManagers);
1029
1030 // Remove all fuel
1031 foreach (SCR_FuelManagerComponent fuelManager : fuelManagers)
1032 {
1033 fuelNodes.Clear();
1034 fuelManager.GetFuelNodesList(fuelNodes);
1035
1036 foreach (BaseFuelNode fuelNode : fuelNodes)
1037 {
1038 fuelNode.SetFuel(0.0);
1039 }
1040 }
1041 }
1042
1043 //------------------------------------------------------------------------------------------------
1044 protected void OnRankChanged(SCR_ECharacterRank oldRank, SCR_ECharacterRank newRank, notnull IEntity owner, bool silent)
1045 {
1046 if (silent)
1047 return;
1048
1049 int playerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(owner);
1050 SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(SCR_FactionManager.SGetPlayerFaction(playerId));
1051 if (!faction)
1052 return;
1053
1054 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
1055 if (!factionManager)
1056 return;
1057
1058 SCR_RankInfoCampaign rank = SCR_RankInfoCampaign.Cast(factionManager.GetFactionRanks(playerId).GetRankByID(newRank));
1059 if (!rank)
1060 return;
1061
1062 SCR_ERadioMsg radio;
1063 if (newRank < oldRank && !rank.IsRankRenegade())
1064 radio = SCR_ERadioMsg.DEMOTION;
1065 else
1066 radio = rank.GetRadioMsg();
1067
1068 faction.SendHQMessage(radio, calledID: playerId, public: false, param: newRank)
1069 }
1070
1071 //------------------------------------------------------------------------------------------------
1072 protected void SetStartingRank(notnull PlayerController playerController)
1073 {
1074 if (m_eStartingRank == SCR_ECharacterRank.INVALID)
1075 return;
1076
1077 int xp;
1078 SCR_PlayerXPHandlerComponent handlerXP = SCR_PlayerXPHandlerComponent.Cast(playerController.FindComponent(SCR_PlayerXPHandlerComponent));
1079
1080 if (handlerXP)
1081 xp = handlerXP.GetPlayerXP();
1082
1083 SCR_XPHandlerComponent comp = SCR_XPHandlerComponent.Cast(FindComponent(SCR_XPHandlerComponent));
1084
1085 if (!comp)
1086 return;
1087
1088 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
1089
1090 if (!factionManager)
1091 return;
1092
1093 int playerID = playerController.GetPlayerId();
1094 SCR_RankContainer ranks = factionManager.GetFactionRanks(playerID);
1095 if (!ranks)
1096 return;
1097
1098 int requiredXp = ranks.GetRequiredRankXP(m_eStartingRank) - xp;
1099
1100 // Remove XP only for renegade ranks, also prevent going into negatives for Private rank
1101 if (requiredXp <= 0 && !ranks.IsRankRenegade(m_eStartingRank))
1102 return;
1103
1104 comp.AwardXP(playerController.GetPlayerId(), SCR_EXPRewards.STARTING_RANK, 1, false, requiredXp);
1105 }
1106
1107 //------------------------------------------------------------------------------------------------
1108 override void OnPlayerAuditSuccess(int iPlayerID)
1109 {
1110 super.OnPlayerAuditSuccess(iPlayerID);
1111
1112 // Apply data with a delay so client's game has time to initialize and register faction setting
1113 GetGame().GetCallqueue().CallLater(ApplyClientData, MINIMUM_DELAY, false, iPlayerID);
1114 }
1115
1116 //------------------------------------------------------------------------------------------------
1117 override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
1118 {
1119 UpdateClientData(playerId); // Must be done before super call to know faction before it is cleared.
1120
1121 super.OnPlayerDisconnected(playerId, cause, timeout);
1122 m_BaseManager.OnPlayerDisconnected(playerId)
1123 }
1124
1125 //------------------------------------------------------------------------------------------------
1126 override void OnPlayerEntityChanged_S(int playerId, IEntity previousEntity, IEntity newEntity)
1127 {
1128 super.OnPlayerEntityChanged_S(playerId, previousEntity, newEntity);
1129 if (!newEntity)
1130 return; // Not spawned
1131
1132 PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerId);
1133 if (!pc)
1134 return;
1135
1136 SCR_CampaignNetworkComponent campaignNetworkComponent = SCR_CampaignNetworkComponent.Cast(pc.FindComponent(SCR_CampaignNetworkComponent));
1137 if (campaignNetworkComponent)
1138 campaignNetworkComponent.OnPlayerAliveStateChanged(true);
1139 }
1140
1141 //------------------------------------------------------------------------------------------------
1142 override void OnPlayerSpawnOnPoint_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, IEntity entity, SCR_SpawnPointSpawnData spawnPointData)
1143 {
1144 super.OnPlayerSpawnOnPoint_S(requestComponent, handlerComponent, entity, spawnPointData);
1145
1146 // Award XP for the owner of the respawn radio (if applicable)
1147 SCR_XPHandlerComponent compXP = SCR_XPHandlerComponent.Cast(FindComponent(SCR_XPHandlerComponent));
1148
1149 if (compXP)
1150 {
1151 SCR_SpawnPoint spawnpoint = spawnPointData.GetSpawnPoint();
1152
1153 if (spawnpoint)
1154 {
1155 SCR_PlayerSpawnPoint playerSpawnpoint = SCR_PlayerSpawnPoint.Cast(spawnpoint);
1156 SCR_DeployableSpawnPoint radioSpawnpoint = SCR_DeployableSpawnPoint.Cast(spawnpoint);
1157
1158 if (playerSpawnpoint)
1159 {
1160 compXP.AwardXP(playerSpawnpoint.GetPlayerID(), SCR_EXPRewards.SPAWN_PROVIDER);
1161 }
1162 else if (radioSpawnpoint)
1163 {
1164 SCR_BaseDeployableSpawnPointComponent comp = radioSpawnpoint.GetDeployableSpawnPointComponent();
1165
1166 if (comp)
1167 {
1168 int playerId = comp.GetItemOwnerID();
1169
1170 // Don't award XP if player respawns on their own spawnpoint
1171 if (playerId != GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(entity))
1172 compXP.AwardXP(playerId, SCR_EXPRewards.SPAWN_PROVIDER);
1173 }
1174 }
1175 }
1176 }
1177
1178 // Location popup for player
1179 PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(requestComponent.GetPlayerId());
1180
1181 if (playerController)
1182 {
1183 SCR_CampaignMilitaryBaseComponent spawnPointParentBase;
1184 IEntity parent = spawnPointData.GetSpawnPoint();
1185
1186 //~ Check if spawn target is a base
1187 while (parent)
1188 {
1190
1191 if (spawnPointParentBase)
1192 break;
1193
1194 parent = parent.GetParent();
1195 }
1196
1197 //~ If spawned on base
1198 if (spawnPointParentBase)
1199 {
1200 SCR_CampaignNetworkComponent campaignNetworkComponent = SCR_CampaignNetworkComponent.Cast(playerController.FindComponent(SCR_CampaignNetworkComponent));
1201
1202 if (campaignNetworkComponent)
1203 campaignNetworkComponent.RespawnLocationPopup(spawnPointParentBase.GetCallsign());
1204 }
1205 }
1206
1207 }
1208
1209 //------------------------------------------------------------------------------------------------
1211 {
1212 IEntity owner = spawnpoint.GetParent();
1213 if (!owner)
1214 return;
1215
1217 if (parentBase)
1218 parentBase.OnSpawnPointFactionAssigned(spawnpoint.GetFactionKey());
1219 }
1220
1221 //------------------------------------------------------------------------------------------------
1222 override void OnPlayerKilledEx(notnull SCR_InstigatorContextData instigatorContextData)
1223 {
1224 super.OnPlayerKilledEx(instigatorContextData);
1225
1226 if (IsProxy())
1227 return;
1228
1229 int playerId = instigatorContextData.GetVictimPlayerID();
1230 PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerId);
1231 if (!pc)
1232 return;
1233
1234 SCR_CampaignNetworkComponent campaignNetworkComponent = SCR_CampaignNetworkComponent.Cast(pc.FindComponent(SCR_CampaignNetworkComponent));
1235 if (campaignNetworkComponent)
1236 {
1237 campaignNetworkComponent.OnPlayerAliveStateChanged(false);
1238 campaignNetworkComponent.ResetSavedSupplies();
1239 }
1240
1241 UpdateRespawnPenalty(playerId);
1242
1243 if (instigatorContextData.HasAnyVictimKillerRelation(SCR_ECharacterDeathStatusRelations.SUICIDE))
1244 OnSuicide(playerId);
1245 }
1246
1247 //------------------------------------------------------------------------------------------------
1249 protected void UpdateRespawnPenalty(int playerId)
1250 {
1252 return;
1253
1254 SCR_CampaignClientData clientData = GetClientData(playerId, true);
1255 if (!clientData)
1256 return;
1257
1258 float respawnPenalty = clientData.GetRespawnPenalty();
1259 if (respawnPenalty == 0)
1260 return;
1261
1262 float curTime = GetGame().GetWorld().GetWorldTime();
1263 float penaltyCooldownMs = (float)m_iSuicideForgiveCooldown * 1000;
1264 float timeSinceLastDeduction = curTime - clientData.GetLastPenaltyDeductionTimestamp();
1265 float penaltiesForgiven = Math.Floor(timeSinceLastDeduction / penaltyCooldownMs);
1266
1267 if (penaltiesForgiven < 1)
1268 return;
1269
1270 clientData.SetLastPenaltyDeductionTimestamp(curTime);
1271 float forgivenPenalty = (float)m_iSuicideRespawnDelay * penaltiesForgiven;
1272 clientData.SetRespawnPenalty(respawnPenalty - forgivenPenalty);
1273
1274 array<Managed> timers = {};
1275 FindComponents(SCR_RespawnTimerComponent, timers);
1276
1277 foreach (Managed timer : timers)
1278 {
1279 // Skip this specific type as it's handled separately for radio spawns
1280 if (timer.Type() == SCR_TimedSpawnPointComponent)
1281 continue;
1282
1284
1285 if (!timerCast)
1286 continue;
1287
1288 timerCast.SetRespawnTime(playerId, timerCast.GetRespawnTime() - respawnPenalty - forgivenPenalty);
1289 }
1290 }
1291
1292 //------------------------------------------------------------------------------------------------
1293 protected void OnSuicide(int playerId)
1294 {
1295 // Don't issue penalties in WB so it doesn't interfere with debugging etc.
1296#ifdef WORKBENCH
1297 return;
1298#endif
1299#ifdef NO_SUICIDE_PENALTY
1300 return;
1301#endif
1302 if (m_bIsTutorial)
1303 return;
1304
1305 if (m_iSuicideRespawnDelay == 0)
1306 return;
1307
1308 PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerId);
1309
1310 // Do not process suicide if player was unconscious upon death
1311 if (pc)
1312 {
1313 SCR_CampaignFeedbackComponent comp = SCR_CampaignFeedbackComponent.Cast(pc.FindComponent(SCR_CampaignFeedbackComponent));
1314
1315 if (comp && !comp.IsConscious())
1316 return;
1317 }
1318
1319 SCR_CampaignClientData clientData = GetClientData(playerId, true);
1320 if (!clientData)
1321 {
1322 Print("Client data is null, this should only be happening in a dev environment.", LogLevel.WARNING);
1323 return;
1324 }
1325
1326 float respawnPenalty = clientData.GetRespawnPenalty();
1327 float lastSuicideTimestamp = clientData.GetLastSuicideTimestamp();
1328 float curTime = GetGame().GetWorld().GetWorldTime();
1329 clientData.SetLastSuicideTimestamp(curTime);
1330
1331 if (lastSuicideTimestamp == 0)
1332 return;
1333
1334 float timeSinceLastSuicide = curTime - lastSuicideTimestamp;
1335 float penaltyCooldownMs = (float)m_iSuicidePenaltyCooldown * 1000;
1336
1337 // Last suicide happened long enough time ago, don't issue a penalty
1338 if (timeSinceLastSuicide > penaltyCooldownMs)
1339 return;
1340
1341 float addedPenalty = m_iSuicideRespawnDelay;
1342
1343 clientData.SetLastPenaltyDeductionTimestamp(curTime);
1344 clientData.SetRespawnPenalty(respawnPenalty + addedPenalty);
1345
1346 array<Managed> timers = {};
1347 FindComponents(SCR_RespawnTimerComponent, timers);
1348
1349 foreach (Managed timer : timers)
1350 {
1351 // Skip this specific type as it's handled separately for radio spawns
1352 if (timer.Type() == SCR_TimedSpawnPointComponent)
1353 continue;
1354
1356
1357 if (!timerCast)
1358 continue;
1359
1360 timerCast.SetRespawnTime(playerId, timerCast.GetRespawnTime() + respawnPenalty + addedPenalty);
1361 }
1362 }
1363
1364 //------------------------------------------------------------------------------------------------
1366
1375 override bool CanPlayerSpawn_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, SCR_SpawnData data, out SCR_ESpawnResult result = SCR_ESpawnResult.SPAWN_NOT_ALLOWED)
1376 {
1377 if (!super.CanPlayerSpawn_S(requestComponent, handlerComponent, data, result))
1378 return false;
1379
1380 SCR_SpawnPointSpawnData spawnpointSpawnData = SCR_SpawnPointSpawnData.Cast(data);
1381
1382 if (!spawnpointSpawnData)
1383 return true;
1384
1385 SCR_SpawnPoint spawnpoint = spawnpointSpawnData.GetSpawnPoint();
1386 SCR_CampaignSpawnPointGroup spawnpointCampaign = SCR_CampaignSpawnPointGroup.Cast(spawnpoint);
1388 PlayerController pc = requestComponent.GetPlayerController();
1389
1390 if (spawnpointCampaign)
1391 {
1392 IEntity spawnpointParent = spawnpointCampaign.GetParent();
1393
1394 if (spawnpointParent)
1395 {
1397
1398 if (base && pc && base.GetCapturingFaction() && base.GetCapturingFaction() != SCR_FactionManager.SGetPlayerFaction(pc.GetPlayerId()))
1399 {
1400 result = SCR_ESpawnResult.NOT_ALLOWED_BASE_UNDER_ATTACK;
1401 return false;
1402 }
1403 }
1404 }
1405
1406 SCR_PlayerLoadoutComponent loadoutComp = SCR_PlayerLoadoutComponent.Cast(requestComponent.GetPlayerController().FindComponent(SCR_PlayerLoadoutComponent));
1407
1408 if (!loadoutComp)
1409 return true;
1410
1411 // Check if player has the required rank for the picked loadout
1412 if (pc)
1413 {
1415 if (xpHandler)
1416 {
1417 SCR_ECharacterRank rankRequirement = SCR_BasePlayerLoadout.GetLoadoutRequiredRank(loadoutComp.GetLoadout(), requestComponent.GetPlayerId());
1418 if (xpHandler.GetPlayerRankByXP() < rankRequirement)
1419 {
1420 result = SCR_ESpawnResult.NOT_ALLOWED_RANK_TOO_LOW;
1421 return false;
1422 }
1423 }
1424 }
1425
1427 if (!loadout || !spawnpoint)
1428 return true;
1429
1430 // Spawning on MHQ or random spawn points with custom loadouts is not allowed
1431 if (spawnpoint.IsSpawnPointRandom() || spawnpoint.FindComponent(SCR_CampaignMobileAssemblyStandaloneComponent))
1432 {
1433 result = SCR_ESpawnResult.NOT_ALLOWED_CUSTOM_LOADOUT;
1434 return false;
1435 }
1436
1437 if (!base)
1438 return true;
1439
1440 SCR_CampaignFaction baseFaction = base.GetCampaignFaction();
1441 if (baseFaction && baseFaction.CanSpawnOnSourceBases())
1442 return true;
1443
1444 SCR_ServicePointDelegateComponent armory = base.GetServiceDelegateByType(SCR_EServicePointType.ARMORY);
1445
1446 if (armory)
1447 return true;
1448
1449 result = SCR_ESpawnResult.NOT_ALLOWED_NO_ARSENAL;
1450 return false;
1451 }
1452
1453 //------------------------------------------------------------------------------------------------
1455 override void OnControllableDestroyedEx(notnull SCR_InstigatorContextData instigatorContextData)
1456 {
1457 super.OnControllableDestroyedEx(instigatorContextData);
1458
1459 if (IsProxy())
1460 return;
1461
1462 Instigator instigator = instigatorContextData.GetInstigator();
1463
1464 // Ignore AI or NONE instigators
1465 if (instigator.GetInstigatorType() != InstigatorType.INSTIGATOR_PLAYER)
1466 return;
1467
1468 //~ Only handle cases were the player kills a character (No Suicide or friendly fire) and the player is not a possessed AI
1469 if (!instigatorContextData.HasAnyVictimKillerRelation(SCR_ECharacterDeathStatusRelations.KILLED_BY_ENEMY_PLAYER) || !instigatorContextData.HasAnyKillerCharacterControlType(SCR_ECharacterControlType.PLAYER))
1470 return;
1471
1472 SCR_XPHandlerComponent compXP = SCR_XPHandlerComponent.Cast(FindComponent(SCR_XPHandlerComponent));
1473 if (!compXP)
1474 return;
1475
1476 //~ Victim is not a character (Safty check)
1477 SCR_ChimeraCharacter victimCharacter = SCR_ChimeraCharacter.Cast(instigatorContextData.GetVictimEntity());
1478 if (!victimCharacter)
1479 return;
1480
1481 vector victimPos = victimCharacter.GetOrigin();
1482
1483 //~ Get nearest base
1484 SCR_CampaignMilitaryBaseComponent nearestBase = m_BaseManager.FindClosestBase(victimPos);
1485 if (!nearestBase)
1486 return;
1487
1488 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
1489 if (!factionManager)
1490 return;
1491
1492 int killerId = instigator.GetInstigatorPlayerID();
1493
1494 //~ Get killer faction to check if the closest base has the same faction as the killer
1495 Faction factionKiller = factionManager.GetPlayerFaction(killerId);
1496 if (!factionKiller)
1497 return;
1498
1499 //this awards additional XP to base defenders, so if the instigator is not in his own base, there should be no reward
1500 if (nearestBase.GetFaction() != factionKiller)
1501 return;
1502
1503 //~ Not in defending range
1504 if (vector.DistanceXZ(victimPos, nearestBase.GetOwner().GetOrigin()) > nearestBase.GetRadius())
1505 return;
1506
1507 //~ Award defending XP
1508 compXP.AwardXP(killerId, SCR_EXPRewards.CUSTOM_1);
1509 }
1510
1511 //------------------------------------------------------------------------------------------------
1513 {
1514 const SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(current);
1515 if (faction)
1516 {
1517 m_BaseManager.SetLocalPlayerFaction(faction);
1518
1520 m_OnFactionAssignedLocalPlayer.Invoke(faction);
1521
1522 return;
1523 }
1524
1526 m_OnFactionAssignedLocalPlayer.Invoke(current);
1527 }
1528
1529 //------------------------------------------------------------------------------------------------
1531 void OnEntityRequested(notnull IEntity spawnedEntity, IEntity user, SCR_Faction faction, SCR_MilitaryBaseLogicComponent service)
1532 {
1533 if (IsProxy())
1534 return;
1535
1537 s_OnEntityRequested.Invoke(user, spawnedEntity);
1538
1539 SCR_AIGroup aiGroup = SCR_AIGroup.Cast(spawnedEntity);
1540 if (aiGroup)
1541 {
1542 SCR_CampaignMilitaryBaseManager militaryBaseManager = GetBaseManager();
1543 if (!militaryBaseManager)
1544 return;
1545
1546 militaryBaseManager.OnDefenderGroupSpawned(service, aiGroup);
1547 }
1548
1549 if (!spawnedEntity.IsInherited(Vehicle))
1550 return;
1551
1552 // Vehicles requested in bases without fuel depot should have only a small amount of fuel
1553 array<SCR_FuelManagerComponent> fuelManagers = {};
1554 array<BaseFuelNode> fuelNodes = {};
1555 SCR_FuelManagerComponent.GetAllFuelManagers(spawnedEntity, fuelManagers);
1556 array<SCR_MilitaryBaseComponent> serviceBases = {};
1557 service.GetBases(serviceBases);
1558 bool fuelDepotNearby;
1559
1560 foreach (SCR_MilitaryBaseComponent serviceBase : serviceBases)
1561 {
1562 if (serviceBase.GetServiceByType(SCR_EServicePointType.FUEL_DEPOT))
1563 {
1564 fuelDepotNearby = true;
1565 break;
1566 }
1567 }
1568
1569 if (!fuelDepotNearby)
1570 {
1571 foreach (SCR_FuelManagerComponent fuelManager : fuelManagers)
1572 {
1573 fuelNodes.Clear();
1574 fuelManager.GetFuelNodesList(fuelNodes);
1575
1576 foreach (BaseFuelNode fuelNode : fuelNodes)
1577 {
1578 fuelNode.SetFuel(fuelNode.GetMaxFuel() * 0.3);
1579 }
1580 }
1581 }
1582
1583 PlayerManager playerManager = GetGame().GetPlayerManager();
1584
1585 int playerId = playerManager.GetPlayerIdFromControlledEntity(user);
1586
1587 if (playerId == 0)
1588 return;
1589
1590 SCR_PlayerController playerController = SCR_PlayerController.Cast(playerManager.GetPlayerController(playerId));
1591
1592 if (!playerController)
1593 return;
1594
1595 SCR_CampaignNetworkComponent networkComp = SCR_CampaignNetworkComponent.Cast(playerController.FindComponent(SCR_CampaignNetworkComponent));
1596
1597 if (!networkComp)
1598 return;
1599
1600 ChimeraWorld world = spawnedEntity.GetWorld();
1601 networkComp.SetLastRequestTimestamp(world.GetServerTimestamp());
1602
1603 BaseRadioComponent radioComponent = BaseRadioComponent.Cast(spawnedEntity.FindComponent(BaseRadioComponent));
1604
1605 // Assign faction radio frequency
1606 if (radioComponent && faction)
1607 {
1608 BaseTransceiver transceiver = radioComponent.GetTransceiver(0);
1609
1610 if (transceiver)
1611 {
1612 radioComponent.SetPower(false);
1613 transceiver.SetFrequency(faction.GetFactionRadioFrequency());
1614 radioComponent.SetEncryptionKey(faction.GetFactionRadioEncryptionKey());
1615 }
1616 }
1617
1618 // Handle Conflict-specific vehicles
1619 SlotManagerComponent slotManager = SlotManagerComponent.Cast(spawnedEntity.FindComponent(SlotManagerComponent));
1620 if (!slotManager)
1621 return;
1622
1623 array<EntitySlotInfo> slots = {};
1624 slotManager.GetSlotInfos(slots);
1625
1626 IEntity truckBed;
1627 SCR_CampaignMobileAssemblyComponent mobileAssemblyComponent;
1628
1629 foreach (EntitySlotInfo slot : slots)
1630 {
1631 if (!slot)
1632 continue;
1633
1634 truckBed = slot.GetAttachedEntity();
1635 if (!truckBed)
1636 continue;
1637
1638 mobileAssemblyComponent = SCR_CampaignMobileAssemblyComponent.Cast(truckBed.FindComponent(SCR_CampaignMobileAssemblyComponent));
1639 if (mobileAssemblyComponent)
1640 networkComp.SendVehicleSpawnHint(EHint.CONFLICT_MOBILE_HQ);
1641 }
1642 }
1643
1644 //------------------------------------------------------------------------------------------------
1646 protected void UpdateClientData(int playerID)
1647 {
1648 const PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerID);
1649 if (!pc)
1650 return;
1651
1652 SCR_CampaignClientData clientData = GetClientData(playerID, true);
1653 if (!clientData)
1654 {
1655 Print("SCR_GameModeCampaign.UpdateClientData: Game was unable to fetch information about the player with playerID = " + playerID, LogLevel.WARNING);
1656 return;
1657 }
1658
1660 if (factionComp)
1661 clientData.SetFactionIndex(GetGame().GetFactionManager().GetFactionIndex(factionComp.GetAffiliatedFaction()));
1662
1664 if (xpComp)
1665 clientData.SetXP(xpComp.GetPlayerXP());
1666
1667 SCR_FastTravelComponent fastTravel = SCR_FastTravelComponent.Cast(pc.FindComponent(SCR_FastTravelComponent));
1668 if (fastTravel)
1669 clientData.SetNextFastTravelTimestamp(fastTravel.GetNextTransportTimestamp());
1670
1671 SCR_PlayerSupplyAllocationComponent supplyAllocationComp = SCR_PlayerSupplyAllocationComponent.Cast(pc.FindComponent(SCR_PlayerSupplyAllocationComponent));
1672 if (supplyAllocationComp)
1673 clientData.SetAvailableAllocatedSupplies(supplyAllocationComp.GetPlayerAvailableAllocatedSupplies());
1674 }
1675
1676 //------------------------------------------------------------------------------------------------
1677 protected void ApplyClientData(int playerId)
1678 {
1679 PlayerController pc = GetGame().GetPlayerManager().GetPlayerController(playerId);
1680 if (!pc)
1681 return;
1682
1683 SCR_CampaignClientData clientData = GetClientData(playerId);
1684 if (!clientData)
1685 {
1686 SetStartingRank(GetGame().GetPlayerManager().GetPlayerController(playerId));
1687 return; // Not a reconnecting client so kick off defaults.
1688 }
1689
1690 bool allowFactionLoad = true;
1691
1692#ifdef ENABLE_DIAG
1693 if (SCR_RespawnComponent.Diag_IsCLISpawnEnabled())
1694 allowFactionLoad = false;
1695#endif
1696
1697 // Automatically apply the client's previous faction
1698 int forcedFaction = clientData.GetFactionIndex();
1699 if (allowFactionLoad && forcedFaction != -1)
1700 {
1702 if (fac)
1703 {
1704 Faction faction = GetGame().GetFactionManager().GetFactionByIndex(forcedFaction);
1705 fac.RequestFaction(faction);
1706 }
1707 }
1708
1709 int xp;
1711 if (handlerXP)
1712 xp = handlerXP.GetPlayerXP();
1713
1714 SCR_XPHandlerComponent comp = SCR_XPHandlerComponent.Cast(FindComponent(SCR_XPHandlerComponent));
1715 if (comp)
1716 comp.AwardXP(playerId, SCR_EXPRewards.UNDEFINED, 1, false, clientData.GetXP() - xp);
1717
1718 SCR_FastTravelComponent fastTravel = SCR_FastTravelComponent.Cast(pc.FindComponent(SCR_FastTravelComponent));
1719 if (fastTravel)
1720 fastTravel.SetNextTransportTimestamp(clientData.GetNextFastTravelTimestamp());
1721
1722 SCR_PlayerSupplyAllocationComponent supplyAllocationComp = SCR_PlayerSupplyAllocationComponent.Cast(pc.FindComponent(SCR_PlayerSupplyAllocationComponent));
1723 if (supplyAllocationComp)
1724 supplyAllocationComp.SetSupplyAllocationOnReconnect(clientData.GetAvailableAllocatedSupplies());
1725 }
1726
1727#ifdef ENABLE_DIAG
1728 //------------------------------------------------------------------------------------------------
1729 override void EOnDiag(IEntity owner, float timeSlice)
1730 {
1731 super.EOnDiag(owner, timeSlice);
1732
1733 PlayerController playerController = GetGame().GetPlayerController();
1734 if (!playerController)
1735 return;
1736
1737 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_UP))
1738 {
1739 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_UP, 0);
1740
1741 SCR_PlayerXPHandlerComponent comp = SCR_PlayerXPHandlerComponent.Cast(playerController.FindComponent(SCR_PlayerXPHandlerComponent));
1742 if (comp)
1743 comp.CheatRank();
1744 }
1745
1746 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_DOWN))
1747 {
1748 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_DOWN, 0);
1749
1750 SCR_PlayerXPHandlerComponent comp = SCR_PlayerXPHandlerComponent.Cast(playerController.FindComponent(SCR_PlayerXPHandlerComponent));
1751 if (comp)
1752 comp.CheatRank(true);
1753 }
1754
1755 if (DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_UP))
1756 {
1757 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_UP, 0);
1758
1759 SCR_PlayerXPHandlerComponent comp = SCR_PlayerXPHandlerComponent.Cast(playerController.FindComponent(SCR_PlayerXPHandlerComponent));
1760 if (comp)
1761 comp.CheatXP(20);
1762 }
1763
1764 if (DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_DOWN))
1765 {
1766 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_DOWN, 0);
1767
1768 SCR_PlayerXPHandlerComponent comp = SCR_PlayerXPHandlerComponent.Cast(playerController.FindComponent(SCR_PlayerXPHandlerComponent));
1769 if (comp)
1770 comp.CheatXP(-20);
1771 }
1772
1773 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_BECOME_COMMANDER_DEBUG))
1774 {
1775 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_BECOME_COMMANDER_DEBUG, 0);
1776
1777 SCR_CampaignFactionCommanderPlayerComponent comp = SCR_CampaignFactionCommanderPlayerComponent.Cast(playerController.FindComponent(SCR_CampaignFactionCommanderPlayerComponent));
1778 if (comp)
1779 comp.CheatCommander();
1780 }
1781
1782 if (!IsProxy())
1783 {
1784 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_BLUFOR))
1785 {
1786 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_BLUFOR, 0);
1787 FactionManager fManager = GetGame().GetFactionManager();
1788
1789 if (fManager)
1790 {
1791 Rpc(RPC_DoEndMatch, fManager.GetFactionIndex(GetFactionByEnum(SCR_ECampaignFaction.BLUFOR)));
1792 RPC_DoEndMatch(fManager.GetFactionIndex(GetFactionByEnum(SCR_ECampaignFaction.BLUFOR)));
1793 }
1794 }
1795
1796 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_OPFOR))
1797 {
1798 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_OPFOR, 0);
1799 FactionManager fManager = GetGame().GetFactionManager();
1800
1801 if (fManager)
1802 {
1803 Rpc(RPC_DoEndMatch, fManager.GetFactionIndex(GetFactionByEnum(SCR_ECampaignFaction.OPFOR)));
1804 RPC_DoEndMatch(fManager.GetFactionIndex(GetFactionByEnum(SCR_ECampaignFaction.OPFOR)));
1805 }
1806 }
1807 }
1808 }
1809#endif
1810
1811 //------------------------------------------------------------------------------------------------
1813 {
1814 // Attributes check
1815 if (m_sBLUFORFactionKey == FactionKey.Empty)
1816 Print("SCR_GameModeCampaign: Empty BLUFOR faction key!", LogLevel.ERROR);
1817
1818 if (m_sOPFORFactionKey == FactionKey.Empty)
1819 Print("SCR_GameModeCampaign: Empty OPFOR faction key!", LogLevel.ERROR);
1820
1821 if (m_sINDFORFactionKey == FactionKey.Empty)
1822 Print("SCR_GameModeCampaign: Empty INDFOR faction key!", LogLevel.ERROR);
1823
1824 if (m_sRNGDFactionKey == FactionKey.Empty)
1825 Print("SCR_GameModeCampaign: Empty RNGD faction key!", LogLevel.ERROR);
1826
1827 if (!GetGame().InPlayMode())
1828 return;
1829
1830 // Cheat menu
1831#ifdef ENABLE_DIAG
1832 DiagMenu.RegisterMenu(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_MENU, "Conflict", "");
1833 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_INSTANT_BUILDING, "", "Instant composition spawning", "Conflict");
1834 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_UP, "", "Promotion", "Conflict");
1835 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_RANK_DOWN, "", "Demotion", "Conflict");
1836 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_UP, "", "+20 XP", "Conflict");
1837 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_XP_DOWN, "", "-20 XP", "Conflict");
1838 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_BECOME_COMMANDER_DEBUG, "", "Become Commander", "Conflict");
1839 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_BLUFOR, "", "Match victory: BLUFOR", "Conflict");
1840 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_CAMPAIGN_VICTORY_OPFOR, "", "Match victory: OPFOR", "Conflict");
1841 ConnectToDiagSystem();
1842#endif
1843
1844 // Parameters override from header
1845 SCR_MissionHeaderCampaign header = SCR_MissionHeaderCampaign.Cast(GetGame().GetMissionHeader());
1846 if (header)
1847 {
1848 m_bIgnoreMinimumVehicleRank = header.m_bIgnoreMinimumVehicleRank;
1849
1850 int suppliesMax = header.m_iMaximumBaseSupplies;
1851 int suppliesMin = header.m_iMinimumBaseSupplies;
1852 int controlPointsLimit = header.m_iControlPointsCap;
1853 float victoryTimeout = header.m_fVictoryTimeout;
1854 float supplyAssistanceReward = header.m_fSupplyOffloadAssistanceReward;
1855
1856 if (suppliesMax != -1)
1857 m_iMaxStartingSupplies = suppliesMax;
1858
1859 if (suppliesMin != -1)
1860 m_iMinStartingSupplies = suppliesMin;
1861
1862 if (controlPointsLimit != -1)
1863 m_iControlPointsThreshold = controlPointsLimit;
1864
1865 if (victoryTimeout != -1)
1866 m_fVictoryTimer = victoryTimeout;
1867
1868 if (supplyAssistanceReward >= 0)
1869 m_fSupplyOffloadAssistanceReward = supplyAssistanceReward;
1870
1871 m_bRandomSpawnpointsEnabled = header.m_bRandomSpawnpointsEnabled;
1872 m_bSpawnRandomCaches = header.m_bSpawnRandomCaches;
1873 m_bCommanderRoleEnabled = header.m_bCommanderRoleEnabled;
1874 m_bEstablishingBasesEnabled = header.m_bEstablishingBasesEnabled;
1875 m_bSuppliesAutoRegenerationEnabled = header.m_bSuppliesAutoRegenerationEnabled;
1876 m_eStartingRank = header.m_eStartingRank;
1877 m_bINDFORCanSpawnOnBases = header.m_bINDFORCanSpawnOnBases;
1878 m_bINDFORCanSpawnOnDistantBases = header.m_bINDFORCanSpawnOnDistantBases;
1879 }
1880
1881 // Establishing Bases can only be enabled when Commander Role is enabled
1884
1885 // prewarm acp for HQ radio sounds
1886 if (!m_sHQRadioSoundEntityPrefab.IsEmpty() && !System.IsConsoleApp())
1887 SCR_HQRadioSoundEntity.GetInstance();
1888 }
1889
1890 //------------------------------------------------------------------------------------------------
1892 {
1893 DisconnectFromDiagSystem();
1894
1895 SCR_SpawnPoint.Event_SpawnPointFactionAssigned.Remove(OnSpawnPointFactionAssigned);
1896
1898
1899 if (manager)
1901 }
1902}
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
EGameOverTypes
EHint
Definition EHint.c:11
ArmaReforgerScripted GetGame()
Definition game.c:1398
override string GetID(string fileName, string varName, array< BaseContainer > objects, array< int > indexes)
RplMode
Mode of replication.
Definition RplMode.c:9
int GetFactionIndex()
void Start()
Start this tracking time in this menu, adds it to previous time if we have not yet sended previous da...
SCR_BaseGameMode GetGameMode()
SCR_CacheNoteComponentClass ScriptComponentClass RplProp()] protected ref array< string > m_aLines
RplComponent m_RplComponent
void OnMatchSituationChanged()
void OnSpawnPointFactionAssigned(FactionKey faction)
void OnLocalPlayerFactionAssigned(Faction assignedFaction)
void SCR_CharacterRankComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void OnRankChanged(SCR_ECharacterRank prevRank, SCR_ECharacterRank newRank, bool silent)
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_ECharacterControlType
What kind of controller the character or (in some cases vehicle) has, eg: AI, Player,...
SCR_ESpawnResult
Get all prefabs that have the spawner data
void SCR_FactionManager(IEntitySource src, IEntity parent)
void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void RpcDo_BroadcastMHQFeedback(SCR_EMobileAssemblyStatus msgID, int playerID, int factionID)
float GetAcceptableDistanceBetweenFactionHQs()
SCR_CampaignFaction GetFactionByEnum(SCR_ECampaignFaction faction)
ResourceName GetHQRadioSoundEntityPrefab()
void ~SCR_GameModeCampaign()
ref ScriptInvoker m_OnStarted
void SetControlPointsHeld(SCR_CampaignFaction faction, int newCount)
bool m_bEstablishingBasesEnabled
int GetRegularSuppliesIncomeSource()
int GetCallsignOffset()
void SetCallsignOffset(int offset)
ScriptInvoker GetOnFactionAssignedLocalPlayer()
Triggered when the local player picks a faction.
void OnEntityRequested(notnull IEntity spawnedEntity, IEntity user, SCR_Faction faction, SCR_MilitaryBaseLogicComponent service)
Called when an entity is spawned by Free Roam Building.
float GetQuickSuppliesReplenishMultiplier()
float GetPreferredDistanceBetweenFactionHQs()
bool m_bCommanderRoleEnabled
int m_iCallsignOffset
ref ScriptInvoker m_OnMatchSituationChanged
float m_fAcceptableDistanceBetweenFactionHQs
ref array< ref SCR_CampaignClientData > m_aRegisteredClients
ref array< SCR_PlayerRadioSpawnPointCampaign > m_aRadioSpawnPoints
SCR_CampaignClientData GetClientData(int playerId, bool create=false)
WorldTimestamp GetVictoryPauseTimestamp()
int GetMinStartingSupplies()
int GetHQSpawnPointPriority()
int GetSuppliesReplenishThreshold()
int GetSupplyDepotIconThreshold()
bool m_bStarted
WorldTimestamp m_fVictoryTimestamp
int GetRegularSuppliesIncomeExtra()
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
void BroadcastMHQFeedback(SCR_EMobileAssemblyStatus msgID, int playerID, int factionID)
int GetRegularSuppliesIncome()
bool GetINDFORCanSpawnOnDistantBases()
int GetFactionEstablishBaseLimit()
int GetQuickSuppliesReplenishThreshold()
ScriptInvoker GetOnCallsignOffsetChanged()
void RPC_DoEndMatch(int winningFactionId)
float GetVictoryTimer()
bool GetIsMatchOver()
int m_iFactionEstablishBaseLimit
SCR_ECharacterRank GetStartingRank()
int GetWinningFactionId()
bool GetINDFORCanSpawnOnBases()
void OnCallsignOffsetChanged()
ResourceName GetSeekDestroyWaypointPrefab()
bool IsTutorial()
void SetPrioritySpawnpoint(SCR_SpawnPoint spawnpoint)
bool HasStarted()
bool m_bINDFORCanSpawnOnBases
SCR_ECharacterRank m_eStartingRank
ResourceName m_sHQRadioSoundEntityPrefab
void DisableExtraSpawnpoint(SCR_SpawnPoint spawnpoint)
void SetIsTutorial(bool isTutorial)
int GetMaxStartingSupplies()
int GetSuppliesArrivalIntervalSource()
bool m_bIsTutorial
bool m_bSuppliesAutoRegenerationEnabled
int GetSuppliesArrivalInterval()
int m_iHQSpawnPointPriority
int GetControlPointTreshold()
int m_iWinningFactionId
bool CanRequestVehicleWithoutRank()
Getter for "Rank required" parameter for spawning vehicles.
ref ScriptInvokerEntity2 s_OnEntityRequested
void OnSuicide(int playerId)
WorldTimestamp GetVictoryTimestamp()
FactionKey GetFactionKeyByEnum(SCR_ECampaignFaction faction)
ScriptInvokerEntity2 GetOnEntityRequested()
ref ScriptInvoker m_OnFactionAssignedLocalPlayer
void SetStartingRank(notnull PlayerController playerController)
float GetSupplyOffloadAssistanceReward()
ref ScriptInvoker m_OnCallsignOffsetChanged
bool m_bINDFORCanSpawnOnDistantBases
void OnStarted()
bool m_bRandomSpawnpointsEnabled
SCR_CampaignMilitaryBaseManager GetBaseManager()
bool GetSpawnRandomCaches()
ref SCR_CampaignMilitaryBaseManager m_BaseManager
void OnAmbientVehicleSpawned(SCR_AmbientVehicleSpawnPointComponent spawnpoint, Vehicle vehicle)
int GetStartingSuppliesInterval()
void InitalBaseSetup()
WorldTimestamp m_fVictoryPauseTimestamp
bool m_bMatchOver
float m_fPreferredDistanceBetweenFactionHQs
bool GetCommanderRoleEnabled()
ScriptInvoker GetOnMatchSituationChanged()
Triggered when an event happened which should be communicated to players (i.e. amount of control poin...
bool m_bSpawnRandomCaches
int m_iSuppliesArrivalIntervalSource
bool m_bIgnoreMinimumVehicleRank
int m_iSuicideRespawnDelay
void ApplyClientData(int playerId)
int GetRegularSuppliesIncomeBase()
int m_iRegularSuppliesIncomeSource
void UpdateClientData(int playerID)
Save object with player's current data.
bool GetSuppliesAutoRegenerationEnabled()
void UpdateRespawnPenalty(int playerId)
Handles forgiving of post-suicide deploy timer penalties.
int m_iSuicidePenaltyCooldown
int m_iSuicideForgiveCooldown
ScriptInvoker GetOnStarted()
Triggered when Conflict gamemode has started.
void RPC_DoSetControlPointsHeld(int factionIndex, int count)
void CheckForWinner()
Find out if any faction has won and it's time to end the match.
bool GetEstablishingBasesEnabled()
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
void SCR_RespawnComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void SCR_RespawnTimerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
ScriptInvokerBase< ScriptInvokerEntity2Method > ScriptInvokerEntity2
enum EVehicleType IEntity
Diagnostic and developer menu system.
Definition DiagMenu.c:18
Adds ability to attach an object to a slot.
proto external Managed FindComponent(typename typeName)
proto external IEntity GetParent()
Definition Math.c:13
Main replication API.
Definition Replication.c:14
OnAmbientVehicleSpawnedInvoker GetOnVehicleSpawned()
static SCR_AmbientVehicleSystem GetInstance()
sealed bool IsMaster()
override void OnPlayerAuditSuccess(int iPlayerID)
override bool RplSave(ScriptBitWriter writer)
bool CanPlayerSpawn_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, SCR_SpawnData data, out SCR_ESpawnResult result=SCR_ESpawnResult.SPAWN_NOT_ALLOWED)
override void OnPlayerRegistered(int playerId)
void EndGameMode(SCR_GameModeEndData endData)
void OnPlayerEntityChanged_S(int playerId, IEntity previousEntity, IEntity newEntity)
override bool RplLoad(ScriptBitReader reader)
void OnControllableDestroyedEx(notnull SCR_InstigatorContextData instigatorContextData)
override void OnGameStart()
override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
void OnPlayerSpawnOnPoint_S(SCR_SpawnRequestComponent requestComponent, SCR_SpawnHandlerComponent handlerComponent, IEntity entity, SCR_SpawnPointSpawnData spawnPointData)
void OnPlayerKilledEx(notnull SCR_InstigatorContextData instigatorContextData)
Used for storing client data to be reapplied for reconnecting clients.
void SetLastSuicideTimestamp(float timestamp)
void SetLastPenaltyDeductionTimestamp(float timestamp)
void SetAvailableAllocatedSupplies(int amount)
void SetNextFastTravelTimestamp(WorldTimestamp timestamp)
void SetFactionIndex(int faction)
void SetRespawnPenalty(float penalty)
WorldTimestamp GetNextFastTravelTimestamp()
void SendHQMessage(SCR_ERadioMsg msgType, int baseCallsign=SCR_MilitaryBaseComponent.INVALID_BASE_CALLSIGN, int calledID=SCR_CampaignMilitaryBaseComponent.INVALID_PLAYER_INDEX, bool public=true, int param=SCR_CampaignRadioMsg.INVALID_RADIO_MSG_PARAM)
WorldTimestamp GetPauseByBlockTimestamp()
void SetControlPointsHeld(int count)
WorldTimestamp GetVictoryTimestamp()
void ApplyHeaderSettings(notnull SCR_CampaignCustomBase settings)
void OnDefenderGroupSpawned(notnull SCR_MilitaryBaseLogicComponent service, notnull SCR_AIGroup group)
Called when a new AI group is spawned by Free Roam Building.
Takes care of Campaign-specific server <> client communication and requests.
void SetLastRequestTimestamp(WorldTimestamp timestamp)
SCR_BaseDeployableSpawnPointComponent GetDeployableSpawnPointComponent()
int GetFactionRadioFrequency()
int GetBases(notnull out array< SCR_MilitaryBaseComponent > bases)
void UnregisterBase(notnull SCR_MilitaryBaseComponent base)
static SCR_MilitaryBaseSystem GetInstance()
static sealed bool IsLoadInProgress(float msSinceLoad=1000.0)
Takes care of dynamic and static onscreen popups.
static void SetFilter(SCR_EPopupMsgFilter filter)
void TogglePeriodicUpdates(bool toggle)
static SCR_RadioCoverageSystem GetInstance()
bool IsRankRenegade(SCR_ECharacterRank rankID)
int GetRequiredRankXP(SCR_ECharacterRank rankID)
Spawn point entity defines positions on which players can possibly spawn.
void SetPriority(int priority)
string GetFactionKey()
void SetFaction(Faction faction)
bool IsSpawnPointRandom()
Definition UUID.c:28
Definition float.c:13
enum EPhysicsLayerPresets Vehicle
Definition gameLib.c:24
override void EOnDiag(IEntity owner, float timeSlice)
InstigatorType
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
proto external Faction GetFactionByIndex(int index)
proto external PlayerController GetPlayerController()
EDamageType
Definition EDamageType.c:13
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
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134