5 private ref array<ref SCR_BaseEditorEffect> m_EffectsSendPingFromPlayer;
8 private ref array<ref SCR_BaseEditorEffect> m_EffectsSendPingFromEditor;
11 private ref array<ref SCR_BaseEditorEffect> m_EffectsSendPingUnlimitedOnlyFromPlayer;
14 private ref array<ref SCR_BaseEditorEffect> m_EffectsSendPingUnlimitedOnlyFromEditor;
17 private ref array<ref SCR_BaseEditorEffect> m_EffectsReceivePingFromPlayer;
20 private ref array<ref SCR_BaseEditorEffect> m_EffectsReceivePingFromEditor;
23 private ref array<ref SCR_BaseEditorEffect> m_EffectsReceivePingUnlimitedOnlyFromPlayer;
26 private ref array<ref SCR_BaseEditorEffect> m_EffectsReceivePingUnlimitedOnlyFromEditor;
28 void ActivateEffects(
SCR_PingEditorComponent component,
bool isReceiver,
int reporterID,
bool reporterInEditor,
bool unlimitedOnly, vector
position, set<SCR_EditableEntityComponent> targets)
72 [
Attribute(defvalue:
"10",
desc:
"How long (in seconds) a ping entity exists before being deleted. Fading is done speratly from this value in SCR_PingEffectsEditorUIComponent.")]
73 protected float m_fPingEntityLifetime;
75 [
Attribute(defvalue:
"0.75",
desc:
"How long (in seconds) is the ping on cooldown to prevent spamming.",
params:
"0, inf, 0.05")]
76 protected float m_fCooldownTime;
79 protected float m_fCurrentCooldownTime;
82 protected float m_fCooldownUpdateFreq = 50;
84 protected bool m_bIsOnCooldown;
87 protected ref map<int, SCR_EditableEntityComponent> m_PlayerPings =
new map<int, SCR_EditableEntityComponent>;
90 protected ref ScriptInvoker Event_OnPingSend =
new ScriptInvoker;
91 protected ref ScriptInvoker Event_OnPingReceive =
new ScriptInvoker;
92 protected ref ScriptInvoker Event_OnPingEntityRegister =
new ScriptInvoker;
93 protected ref ScriptInvoker Event_OnPingEntityUnregister =
new ScriptInvoker;
105 if (IsPingOnCooldown())
107 SCR_NotificationsComponent.SendLocal(
ENotification.ACTION_ON_COOLDOWN, m_fCurrentCooldownTime * 100);
119 if (manager.IsLimited())
121 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_GM_ONLY_PING_LIMITED_RIGHTS);
125 else if (!manager.IsOpened())
133 if (playerDelegateManager && !playerDelegateManager.HasPlayerWithUnlimitedEditor())
135 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_PING_NO_GM_TO_PING);
139 int reporterID = manager.GetPlayerID();
140 bool reporterInEditor = manager.IsOpened() && !manager.IsLimited();
142 if (target) target.GetPos(
position);
143 CallEvents(manager,
false, reporterID, reporterInEditor, unlimitedOnly,
position, target);
146 Rpc(SendPingServer, unlimitedOnly,
position, Replication.FindId(target));
153 protected void ActivateCooldown()
155 m_fCurrentCooldownTime = m_fCooldownTime;
156 m_bIsOnCooldown =
true;
159 GetGame().GetCallqueue().CallLater(UpdateCooldown, m_fCooldownUpdateFreq,
true);
163 protected void UpdateCooldown()
165 m_fCurrentCooldownTime -= m_fCooldownUpdateFreq / 1000;
167 if (m_fCurrentCooldownTime <= 0)
172 protected void OnCooldownDone()
174 m_bIsOnCooldown =
false;
175 GetGame().GetCallqueue().Remove(UpdateCooldown);
178 [
RplRpc(RplChannel.Reliable, RplRcver.Server)]
179 protected void SendPingServer(
bool unlimitedOnly, vector
position, RplId targetID)
184 if (!manager)
return;
186 int reporterID = manager.GetPlayerID();
187 bool reporterInEditor = manager.IsOpened() && !manager.IsLimited();
194 m_Core.Event_OnEditorManagerPing.Invoke(reporterID, reporterInEditor, reporterEntity, unlimitedOnly,
position, targetID);
200 if (!manager || manager.GetPlayerID() == reporterID)
203 if (unlimitedOnly && manager.IsLimited())
207 if (!reporterInEditor)
210 if (!manager.IsOpened() || manager.IsLimited())
214 SCR_AccessKeysEditorComponent accessKeysManager = SCR_AccessKeysEditorComponent.Cast(manager.FindComponent(SCR_AccessKeysEditorComponent));
215 if (accessKeysManager && reporterEntity && !reporterEntity.HasAccessInHierarchy(accessKeysManager.GetAccessKey()))
220 Rpc(ReceivePingOwner, reporterID, reporterInEditor, unlimitedOnly,
position, targetID);
222 [
RplRpc(RplChannel.Reliable, RplRcver.Owner)]
223 protected void ReceivePingOwner(
int reporterID,
bool reporterInEditor,
bool unlimitedOnly, vector
position, RplId targetID)
226 if (!manager)
return;
228 if (unlimitedOnly && manager.IsLimited())
232 CallEvents(manager,
false, reporterID, reporterInEditor, unlimitedOnly,
position, target);
240 int GetPlayerPings(out notnull map<int, SCR_EditableEntityComponent> outPlayerPings)
242 return outPlayerPings.Copy(m_PlayerPings);
250 ScriptInvoker GetOnPingSend()
252 return Event_OnPingSend;
259 ScriptInvoker GetOnPingReceive()
261 return Event_OnPingReceive;
268 ScriptInvoker GetOnPingEntityRegister()
270 return Event_OnPingEntityRegister;
277 ScriptInvoker GetOnPingEntityUnregister()
279 return Event_OnPingEntityUnregister;
286 bool IsPingOnCooldown()
288 return m_bIsOnCooldown;
293 set<SCR_EditableEntityComponent> targets =
new set<SCR_EditableEntityComponent>;
294 if (target) targets.Insert(target);
296 m_LastPingEntity = target;
300 Event_OnPingReceive.Invoke(reporterID, reporterInEditor, unlimitedOnly,
position, target);
302 Event_OnPingSend.Invoke(reporterID, reporterInEditor, unlimitedOnly,
position, target);
306 if (prefabData) prefabData.ActivateEffects(
this, isReceiver, reporterID, reporterInEditor, unlimitedOnly,
position, targets);
308 if (m_LastPingEntity)
311 if (m_PlayerPings.Find(reporterID, prevPingEntity))
312 Expire(reporterID, prevPingEntity);
314 m_PlayerPings.Set(reporterID, m_LastPingEntity);
315 Event_OnPingEntityRegister.Invoke(reporterID, m_LastPingEntity);
317 GetGame().GetCallqueue().CallLater(Expire, m_fPingEntityLifetime * 1000,
false, reporterID, m_LastPingEntity);
321 int targetPlayerID = 0;
327 targetID = Replication.FindId(target);
328 targetPlayerID = SCR_PossessingManagerComponent.GetPlayerIdFromMainEntity(target.GetOwner());
335 if (reporterInEditor)
341 else if (targetPlayerID > 0)
342 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_PING_GM_TARGET_PLAYER, reporterID, targetPlayerID);
345 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_PING_GM_TARGET_ENTITY, reporterID, targetID);
352 else if (targetPlayerID > 0)
353 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_PING_PLAYER_TARGET_PLAYER, reporterID, targetPlayerID);
356 SCR_NotificationsComponent.SendLocal(
ENotification.EDITOR_PING_PLAYER_TARGET_ENTITY, reporterID, targetID);
363 SCR_NotificationsComponent.SendLocalUnlimitedEditor(
ENotification.EDITOR_GM_ONLY_PING,
position, reporterID);
365 else if (targetPlayerID > 0)
366 SCR_NotificationsComponent.SendLocalUnlimitedEditor(
ENotification.EDITOR_GM_ONLY_PING_TARGET_PLAYER, reporterID, targetPlayerID);
369 SCR_NotificationsComponent.SendLocalUnlimitedEditor(
ENotification.EDITOR_GM_ONLY_PING_TARGET_ENTITY, reporterID, targetID);
376 if (pingEntity && m_PlayerPings.Find(reporterID, currentPingEntity) && pingEntity == currentPingEntity)
378 m_PlayerPings.Remove(reporterID);
379 Event_OnPingEntityUnregister.Invoke(reporterID, pingEntity);
394 if (!Replication.IsServer())
return;
398 m_Core.Event_OnEditorManagerPing.Insert(ReceivePing);
405 if (m_Core) m_Core.Event_OnEditorManagerPing.Remove(ReceivePing);