Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
RplTestComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Test", description: "Test component showcasing doing the replication from script the RIGHT way")]
2 class SCR_RplTestComponentClass : ScriptComponentClass
3 {
4 }
5 
7 {
8  protected ChimeraCharacter m_CharacterOwner = null;
9  private RplComponent m_RplComponent = null;
10 
11  // NoOwner - executed everywhere but on the owner. Note both client and server can be owners.
12  // Thus, when the client is owner, this won't be called for it.
13  // onRplName: "OnTestChanged" - if the target is right,
14  // everytime the value changes OnTestChanged is executed
15  [RplProp(condition: RplCondition.NoOwner, onRplName: "OnTestChanged")]
16  private int m_iTest = 0;
17 
18  float m_fdelay = 0;
19 
20  //------------------------------------------------------------------------------------------------
23  void Do_TestRpc(int testNum)
24  {
25  Print("RPC TestRpc EXECUTED: " + testNum, LogLevel.NORMAL);
26  }
27 
28  //------------------------------------------------------------------------------------------------
31  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
32  void RpcAsk_TestRpc(int testNum)
33  {
34  Do_TestRpc(testNum);
35  Rpc(RpcDo_TestRpc, testNum);
36  }
37 
38  //------------------------------------------------------------------------------------------------
48  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
49  void RpcDo_TestRpc(int testNum)
50  {
51  Print("RPC NetTestRpc EXECUTED: " + testNum, LogLevel.NORMAL);
52  }
53 
54  //------------------------------------------------------------------------------------------------
57  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
58  void RpcAsk_ChangePropValue(float timeSlice)
59  {
60  m_fdelay -= timeSlice;
61  if (m_fdelay > 0)
62  return;
63 
64  m_fdelay += 2;
65 
66  // Change the value server side
67  // This will trigger OnTestChanged on clients
68  m_iTest = Math.RandomIntInclusive(0, 100);
69  Replication.BumpMe();
70  Print("RPLPROP m_iTest CHANGED on SERVER: " + m_iTest, LogLevel.NORMAL);
71  }
72 
73  //------------------------------------------------------------------------------------------------
74  // Called on client everytime m_iTest changes value. No need to use m_iTestLast
75  // unless you really need to know the previous value
77  {
78  Print("RPLPROP m_iTest CHANGED on CLIENT: " + m_iTest, LogLevel.NORMAL);
79  }
80 
81  //------------------------------------------------------------------------------------------------
83  void Do_TestFire()
84  {
85  Print("RPC TestFire EXECUTED", LogLevel.NORMAL);
86  }
87 
88  //------------------------------------------------------------------------------------------------
90  [RplRpc(RplChannel.Reliable, RplRcver.Server)]
92  {
93  // You might want to do some security checks here.
94  // E.g., could the shot have been fired?
95  // if (!...)
96  // return;
97 
98  // Assuming the server is the authority here, we perform the action
99  // right away.
100  // If it weren't the case, we'd need to do the opposite condition we
101  // did before calling the RPC which in our would result in:
102  // if (m_RplComponent && !m_RplComponent.IsOwnerProxy())
103  // Do_TestFire();
104  // Otherwise, Do_TestFire would be performed twice in some cases.
105  // However, we design our code with security in mind and want the server
106  // be the authority. Therefor, it's enough to have:
107  Do_TestFire();
108 
109  Rpc(RpcDo_TestFire);
110  }
111 
112  //------------------------------------------------------------------------------------------------
114  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast, RplCondition.NoOwner)]
116  {
117  Do_TestFire();
118  }
119 
120  //------------------------------------------------------------------------------------------------
121  override void OnPostInit(IEntity owner)
122  {
123  super.OnPostInit(owner);
124  SetEventMask(owner, EntityEvent.FRAME | EntityEvent.INIT);
125  owner.SetFlags(EntityFlags.ACTIVE, false);
126  }
127 
128  //------------------------------------------------------------------------------------------------
129  override void EOnInit(IEntity owner)
130  {
131  m_CharacterOwner = ChimeraCharacter.Cast(owner);
132  if (m_CharacterOwner)
133  m_RplComponent = RplComponent.Cast(m_CharacterOwner.FindComponent(RplComponent));
134  }
135 
136  //------------------------------------------------------------------------------------------------
137  override void EOnFrame(IEntity owner, float timeSlice)
138  {
139  if (Debug.KeyState(KeyCode.KC_P))
140  {
141  Debug.ClearKey(KeyCode.KC_P);
142  int rndRPCNum = Math.RandomIntInclusive(0, 100);
143  // Print first
144  Print("Requesting TestRpc: " + rndRPCNum, LogLevel.NORMAL);
145  // Execute second! Otherwise, when calling this on server,
146  // you'd first print you changed the value and only then
147  // you'd print your requested a change.
148  Rpc(RpcAsk_TestRpc, rndRPCNum);
149  }
150 
151  // Ask the server to update the property value
152  Rpc(RpcAsk_ChangePropValue, timeSlice);
153 
154  // There might be times when you want some local effect be performed
155  // right away. E.g., you start shooting and want to hide the network
156  // latency (request + response could take 100+ ms and you would notice
157  // this immediatelly).
158  // In this case, if we assume the server has the authority (which should
159  // always be the case to keep the game secure), I recommend doing:
160  if (m_RplComponent && m_RplComponent.IsOwnerProxy())
161  Do_TestFire(); // local effect right away
162  // Ask the server to perform the action and if possible, broadcast it
163  // to everybody but the owner
164  Rpc(RpcAsk_TestFire);
165 
166  // IMPORTANT:
167  // ONLY OWNERS CAN PERFORM RPCs! Calling RPCs from a non-owner equals
168  // doing nothing.
169  }
170 
171  //------------------------------------------------------------------------------------------------
172  // constructor
176  void SCR_RplTestComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
177  {
178  }
179 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
Do_TestRpc
void Do_TestRpc(int testNum)
Definition: RplTestComponent.c:23
Do_TestFire
void Do_TestFire()
Definition: RplTestComponent.c:83
ScriptComponent
SCR_SiteSlotEntityClass ScriptComponent
RplProp
SCR_RplTestEntityClass RplProp
Used for handling entity spawning requests for SCR_CatalogEntitySpawnerComponent and inherited classe...
OnTestChanged
void OnTestChanged()
Definition: RplTestComponent.c:76
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
EOnFrame
override void EOnFrame(IEntity owner, float timeSlice)
Definition: RplTestComponent.c:137
RpcDo_TestFire
void RpcDo_TestFire()
Definition: RplTestComponent.c:115
SCR_RplTestComponent
void SCR_RplTestComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: RplTestComponent.c:176
SCR_RplTestComponentClass
Definition: RplTestComponent.c:2
m_CharacterOwner
SCR_RplTestComponentClass m_CharacterOwner
RpcAsk_ChangePropValue
void RpcAsk_ChangePropValue(float timeSlice)
Definition: RplTestComponent.c:58
OnPostInit
override void OnPostInit(IEntity owner)
Editable Mine.
Definition: RplTestComponent.c:121
RpcDo_TestRpc
void RpcDo_TestRpc(int testNum)
Definition: RplTestComponent.c:49
RpcAsk_TestRpc
void RpcAsk_TestRpc(int testNum)
Definition: RplTestComponent.c:32
EOnInit
override void EOnInit(IEntity owner)
Initialise this component with data from FactionsManager.
Definition: RplTestComponent.c:129
RpcAsk_TestFire
void RpcAsk_TestFire()
Definition: RplTestComponent.c:91
m_iTest
private int m_iTest
Definition: RplTestComponent.c:16
m_fdelay
float m_fdelay
Definition: RplTestComponent.c:18
m_RplComponent
private RplComponent m_RplComponent
Definition: RplTestComponent.c:9
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180