DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
Trigger.c
Go to the documentation of this file.
1
3{
4 ref OLinkT insider; // DEPRECATED
5
7 protected Object m_Object;
8
11
14
17
19 {
20 insider = new OLinkT(obj);
21 m_Object = obj;
22 }
23
25 {
26 }
27
29 {
30 return m_Object;
31 }
32};
33
34#ifdef DIAG_DEVELOPER
35typedef Param7<vector, vector, vector, vector, float, string, array<ref TriggerInsider>> DebugTriggerInfo;
36#endif
37
40{
42 const int TIMEOUT = 1000;
45
46 #ifdef DIAG_DEVELOPER
47 bool m_Local;//is this trigger spawning on client only ?
48 string m_DebugAreaType;
49 ref array<ref TriggerInsider> m_dbgInsiders;
50 #endif
51
53 private void Trigger()
54 {
55 SetEventMask(EntityEvent.INIT /*| EntityEvent.TOUCH*/ | EntityEvent.FRAME | EntityEvent.ENTER | EntityEvent.LEAVE );
56 SetFlags(EntityFlags.TRIGGER, false);
57
59 }
60
62 private void ~Trigger()
63 {
64 #ifdef DIAG_DEVELOPER
65 CleanupDebugShapes(dbgTargets);
66 #endif
67 }
68
74 override void EOnInit(IEntity other, int extra)
75 {
76 SetExtents("-2 -4 -2", "2 4 2");
77 }
78
80 /*override void EOnTouch(IEntity other, int extra)
81 {
82 Object obj;
83 if (Class.CastTo(obj, other) && CanAddObjectAsInsider(obj))
84 AddInsider(obj);
85 }*/
86
88 override void EOnFrame(IEntity other, float timeSlice)
89 {
91 }
92
94 override void EOnEnter(IEntity other, int extra)
95 {
96 Object obj;
97 if (Class.CastTo(obj, other) && CanAddObjectAsInsider(obj))
98 AddInsider(obj);
99 }
100
102 override void EOnLeave(IEntity other, int extra)
103 {
104 Object obj;
105 if (Class.CastTo(obj, other))
107 }
109
110
116 void SetExtents(vector mins, vector maxs)
117 {
118 SetCollisionBox(mins, maxs);
119 }
120
122 float GetRadius(vector min, vector max)
123 {
124 return GetCollisionRadius();
125 }
126
129 {
130 return m_insiders;
131 }
132
135 {
136 TriggerInsider ins;
137
138 for ( int n = 0; n < m_insiders.Count(); ++n )
139 {
140 ins = m_insiders[n];
141 if (ins.GetObject() == object)
142 return ins;
143 }
144
145 return null;
146 }
147
150 {
151 TriggerInsider ins;
152
153 for ( int n = 0; n < m_insiders.Count(); ++n )
154 {
155 ins = m_insiders[n];
156 if (ins.GetObject() == object)
157 return n;
158 }
159
160 return -1;
161 }
163
164
169 override protected void OnEnterBeginEvent(TriggerInsider insider)
170 {
171 // Call the old event for backwards compatibility
172 OnEnter(insider.GetObject());
173 }
174
175 override protected void OnLeaveBeginEvent(TriggerInsider insider)
176 {
177 // Call the old event for backwards compatibility
178 OnLeave(insider.GetObject());
179 }
181
182
187 void OnEnter(Object obj) {}
188
189 void OnLeave(Object obj) {}
191
192
198 protected bool CanAddObjectAsInsider(Object object)
199 {
200 return true;
201 }
202
204 protected bool ShouldRemoveInsider(TriggerInsider insider)
205 {
206 return false;
207 }
208
211 {
212 return false;
213 }
215
216
223 {
224 return new TriggerInsider(obj);
225 }
226
228 protected void AddInsider(Object obj)
229 {
230 if ( !obj )
231 return;
232
233 // Already in?
234 if ( GetInsiderForObject( obj ) )
235 {
236 Error(string.Format("[WARNING] :: [Trigger] :: [%1] :: Insider (%2) is already inside.", GetDebugName(this), GetDebugName(obj)));
237 return;
238 }
239
240 // New Object entered! Fill the data.
241 TriggerInsider insider = CreateInsider(obj);
242 insider.timeStamp = g_Game.GetTime();
243 insider.timeEntered = g_Game.GetTickTime();
244 insider.lastUpdated = insider.timeEntered;
245
246 // Don't add if it is going to be removed anyways..
247 if ( ShouldRemoveInsider(insider) || ShouldRemoveInsiderNoLeave(insider) )
248 return;
249
250 // Keep track of the Object as long as it is inside the Trigger
251 int index = m_insiders.Insert(insider);
252
253 // Call the enter event to signal this Object entered
254 Enter(insider);
255 obj.OnEnterTrigger(this);
256
257 #ifdef TRIGGER_DEBUG_NORMAL
258 Debug.TriggerLog(string.Format("%1: inserted at index %2", GetDebugName(obj), index), "Trigger", "", "AddInsider", GetDebugName(this));
259 #endif
260
262 #ifdef DIAG_DEVELOPER
263 DebugSendDmgTrigger();
264 #endif
265 }
266
268 protected void RemoveInsider(TriggerInsider insider, int index = -1)
269 {
270 Leave(insider);
271 insider.GetObject().OnLeaveTrigger(this);
272
273 #ifdef TRIGGER_DEBUG_NORMAL
274 Debug.TriggerLog(string.Format("%1: removing at index %2", GetDebugName(insider.GetObject()), index), "Trigger", "", "RemoveInsider", GetDebugName(this));
275 #endif
276
277 if (index >= 0)
278 m_insiders.Remove(index);
279 else
280 m_insiders.RemoveItemUnOrdered(insider);
281
283 #ifdef DIAG_DEVELOPER
284 DebugSendDmgTrigger();
285 #endif
286 }
287
289 protected void RemoveInsiderByObject(Object object)
290 {
291 TriggerInsider ins;
292 for ( int n = 0; n < m_insiders.Count(); ++n )
293 {
294 ins = m_insiders[n];
295 if (ins.GetObject() == object)
296 {
297 RemoveInsider(ins, n);
298 return;
299 }
300 }
301
302 // As EOnLeave can call this, it is perfectly valid that this Object is not found on Script side
303 // because of "ShouldRemoveInsider" and "ShouldRemoveInsiderNoLeave"
304 }
305
307 protected void UpdateInsiders(int timeout)
308 {
310 #ifdef DIAG_DEVELOPER
311 DebugSendDmgTrigger();
312 #endif
313
314 // Don't do anything if there aren't any insiders
315 if ( m_insiders.Count() == 0 )
316 return;
317
318 // Mark the beginning of the update loop
319 StayStart(m_insiders.Count());
320
321 // Iterate over the current insiders, backwards because we are deleting
322 for ( int n = m_insiders.Count() - 1; n >= 0 ; --n)
323 {
324 TriggerInsider insider = m_insiders.Get(n);
325 Object obj = insider.GetObject();
326
327 // Check if the Object still exists or should be removed without calling OnLeaveEvent
328 if ( !obj || ShouldRemoveInsiderNoLeave(insider) )
329 {
330 #ifdef TRIGGER_DEBUG_BASIC
331 Debug.TriggerLog(string.Format("%1: removed with no Leave.", GetDebugName(obj)), "Trigger", "", "UpdateInsiders", GetDebugName(this));
332 #endif
333
334 m_insiders.Remove(n);
335 continue;
336 }
337
338 // Check if Object left the Trigger or should be removed regardless
339 if ( ShouldRemoveInsider(insider) )
340 {
341 RemoveInsider(insider, n);
342 continue;
343 }
344
345 // Call the OnStayEvent, Object is still inside the Trigger and can be updated
346 // Pass in the time since the Object was last updated (or entered)
347 float currentTime = g_Game.GetTickTime();
348 Stay(insider, currentTime - insider.lastUpdated);
349 insider.lastUpdated = currentTime;
350 }
351
352 // Mark the end of the update loop
353 StayFinish();
354 }
356
361 override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
362 {
363 super.OnRPC(sender, rpc_type, ctx);
364 #ifdef DIAG_DEVELOPER
365 switch ( rpc_type )
366 {
367 case ERPCs.DIAG_TRIGGER_DEBUG:
368 DebugTriggerInfo data = new DebugTriggerInfo(vector.Zero, vector.Zero, vector.Zero, vector.Zero, 0, "", null);
369
370 if ( ctx.Read( data ) )
371 DebugDmgTrigger( data.param1, data.param2, data.param3, data.param4, data.param5, data.param6, data.param7 );
372 break;
373 }
374 #endif
375 }
376
377#ifdef DIAG_DEVELOPER
378 void DebugSendDmgTrigger()
379 {
380 vector minmax[2];
381 GetCollisionBox(minmax);
382
383 DebugTriggerInfo data = new DebugTriggerInfo(vector.Zero, vector.Zero, vector.Zero, vector.Zero, 0, "", null);
384 data.param1 = GetWorldPosition();
385 data.param2 = GetOrientation();
386 data.param3 = minmax[0];
387 data.param4 = minmax[1];
388 data.param5 = GetCollisionRadius();
389 data.param6 = m_DebugAreaType;
390 data.param7 = m_insiders;
391
392 if ( GetGame().IsMultiplayer() && GetGame().IsServer() )
393 PluginDiagMenuServer.SendDataToSubscribersServer(this, ESubscriberSystems.TRIGGERS, ERPCs.DIAG_TRIGGER_DEBUG, data, false);
394 else if (!GetGame().IsMultiplayer() || m_Local)
395 DebugDmgTrigger( data.param1, data.param2, data.param3, data.param4, data.param5, data.param6, data.param7 );
396 }
397
398 protected ref array<Shape> dbgTargets = new array<Shape>();
399
400 void DebugDmgTrigger( vector pos, vector orientation, vector min, vector max, float radius, string dmgType, array<ref TriggerInsider> insiders)
401 {
402 CleanupDebugShapes( dbgTargets );
403
404 bool enableDebug = DiagMenu.GetBool(DiagMenuIDs.TRIGGER_DEBUG);
405 if ( enableDebug )
406 {
407 if ( GetGame().IsMultiplayer() && GetGame().IsServer() )
408 {
409 return;
410 }
411
412 vector w_pos, w_pos_sphr, w_pos_lend;
413
414 w_pos = pos;
415 // sphere pos tweaks
416 w_pos_sphr = w_pos;
417 // line pos tweaks
418 w_pos_lend = w_pos;
419
420 //Find way to change colour of box depending on ammoType in a more elegant fashion
421 m_DebugAreaType = dmgType;
422 Shape dbgShape;
423
424 switch ( m_DebugAreaType )
425 {
426 case "FireDamage":
427 dbgShape = DrawDebugShape(pos, min, max, radius, COLOR_RED_A);
428 break;
429
430 case "BarbedWireHit":
431 dbgShape = DrawDebugShape(pos, min, max, radius, COLOR_BLUE_A);
432 break;
433
434 default:
435 dbgShape = DrawDebugShape(pos, min, max, radius, COLOR_GREEN_A);
436 break;
437 }
438
439 if ( GetGame().IsMultiplayer() || GetGame().IsServer() )
440 m_dbgInsiders = insiders;
441
442 if ( m_dbgInsiders.Count() > 0 )
443 {
444 //Change colour to make state clearer
445 dbgShape.SetColor( COLOR_YELLOW_A );
446
447 for ( int i = 0; i < m_dbgInsiders.Count(); i++ )
448 {
449 EntityAI insider_EAI = EntityAI.Cast( m_dbgInsiders[i].GetObject() );
450 if ( insider_EAI )
451 {
452 vector insiderPos = insider_EAI.GetWorldPosition() + "0 0.1 0";
453 dbgTargets.Insert( Debug.DrawArrow( w_pos, insiderPos ) );
454 }
455 }
456 }
457 }
458 }
459
460 protected Shape DrawDebugShape(vector pos, vector min, vector max, float radius, int color)
461 {
462 Shape dbgShape;
463
464 switch (GetTriggerShape())
465 {
466 case TriggerShape.BOX:
467 dbgShape = Debug.DrawBox(min, max, color);
468
469 vector mat[4];
470 GetTransform(mat);
471 dbgShape.CreateMatrix(mat);
472 dbgShape.SetMatrix(mat);
473 break;
474 case TriggerShape.CYLINDER:
475 dbgShape = Debug.DrawCylinder(pos, radius, max[1], color, ShapeFlags.TRANSP|ShapeFlags.NOZWRITE);
476 break;
477 case TriggerShape.SPHERE:
478 dbgShape = Debug.DrawSphere(pos, radius, color, ShapeFlags.TRANSP|ShapeFlags.NOZWRITE);
479 break;
480 default:
481 ErrorEx("TriggerShape not found", ErrorExSeverity.WARNING);
482 break;
483 }
484
485 dbgTargets.Insert(dbgShape);
486
487 return dbgShape;
488 }
489
490 protected void CleanupDebugShapes(array<Shape> shapes)
491 {
492 for (int it = 0; it < shapes.Count(); ++it)
493 {
494 Debug.RemoveShape(shapes[it]);
495 }
496
497 shapes.Clear();
498 }
499
500#endif
502};
void DrawDebugShape()
Object GetObject()
vector GetOrientation()
DayZGame g_Game
Definition DayZGame.c:3654
DiagMenuIDs
Definition EDiagMenuIDs.c:2
ERPCs
Definition ERPCs.c:2
override string GetDebugName()
Gets the debug name for the ParticleManager.
proto native void SetCollisionBox(vector mins, vector maxs)
Sets collision box for object.
proto native TriggerShape GetTriggerShape()
Get the current TriggerShape.
TriggerShape
Super root of all classes in Enforce script.
Definition EnScript.c:11
Definition Debug.c:14
static void TriggerLog(string message=LOG_DEFAULT, string plugin=LOG_DEFAULT, string author=LOG_DEFAULT, string label=LOG_DEFAULT, string entity=LOG_DEFAULT)
Definition Debug.c:163
static Shape DrawArrow(vector from, vector to, float size=0.5, int color=0xFFFFFFFF, int flags=0)
Definition Debug.c:383
static void RemoveShape(out Shape shape)
Definition Debug.c:107
static Shape DrawBox(vector pos1, vector pos2, int color=0x1fff7f7f)
Definition Debug.c:273
static Shape DrawSphere(vector pos, float size=1, int color=0x1fff7f7f, ShapeFlags flags=ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE)
Definition Debug.c:306
static Shape DrawCylinder(vector pos, float radius, float height=1, int color=0x1fff7f7f, ShapeFlags flags=ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE)
Definition Debug.c:322
The class that will be instanced (moddable)
Definition gameplay.c:378
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
proto bool Read(void value_in)
protected void Enter(TriggerInsider insider)
protected void Leave(TriggerInsider insider)
protected void StayFinish()
protected void StayStart(int nrOfInsiders)
protected void Stay(TriggerInsider insider, float deltaTime)
Scripted Trigger.
Definition Hologram.c:1538
protected TriggerInsider CreateInsider(Object obj)
Used for easily overriding TriggerInsider creation without rewriting AddInsider.
Definition Trigger.c:222
protected bool CanAddObjectAsInsider(Object object)
Condition whether an Object can be added as TriggerInsider (checked before calling AddInsider)
Definition Trigger.c:198
override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
Definition Trigger.c:361
void SetExtents(vector mins, vector maxs)
Set the size of the Trigger, avoid using SetCollisionBox directly.
Definition Trigger.c:116
override void EOnLeave(IEntity other, int extra)
When an Object exits the trigger remove it from Insiders.
Definition Trigger.c:102
protected void RemoveInsider(TriggerInsider insider, int index=-1)
Removing of TriggerInsider.
Definition Trigger.c:268
protected void UpdateInsiders(int timeout)
Update the current TriggerInsider inside the Trigger, timeout paramter is deprecated.
Definition Trigger.c:307
override protected void OnLeaveBeginEvent(TriggerInsider insider)
Definition Trigger.c:175
void OnLeave(Object obj)
Definition Trigger.c:189
protected bool ShouldRemoveInsider(TriggerInsider insider)
Condition whether a TriggerInsider should still be updated or not (checked in update loop and before ...
Definition Trigger.c:204
protected bool ShouldRemoveInsiderNoLeave(TriggerInsider insider)
Condition whether a TriggerInsider should still be updated or not, skips OnLeaveEvent (checked in upd...
Definition Trigger.c:210
protected void AddInsider(Object obj)
Adding of new TriggerInsider.
Definition Trigger.c:228
protected void RemoveInsiderByObject(Object object)
Removing of TriggerInsider through Object.
Definition Trigger.c:289
override protected void OnEnterBeginEvent(TriggerInsider insider)
Definition Trigger.c:169
float GetRadius(vector min, vector max)
Get the radius of the CollisionBox, simply left for backwards compatibility.
Definition Trigger.c:122
override void OnEnter(Object obj)
Definition Hologram.c:1543
void OnEnter(Object obj)
Definition Trigger.c:187
private void ~Trigger()
dtor
Definition Trigger.c:62
override void OnLeave(Object obj)
Definition Hologram.c:1553
override void EOnInit(IEntity other, int extra)
Set the default extents of the Trigger only once it is properly initialized.
Definition Trigger.c:74
const int TIMEOUT
DEPRECATED.
Definition Trigger.c:42
override protected void UpdateInsiders(int timeout)
Definition Hologram.c:1562
int GetInsiderIndexForObject(Object object)
Gets the index in m_insiders for the Object.
Definition Trigger.c:149
ref array< ref TriggerInsider > m_insiders
The objects and their metadata which are currently inside the Trigger.
Definition Trigger.c:44
TriggerInsider GetInsiderForObject(Object object)
Gets the TriggerInsider for the Object if it exists.
Definition Trigger.c:134
array< ref TriggerInsider > GetInsiders()
Get the current TriggerInsider array, left for backwards compatibility, moved down from ManTrigger.
Definition Trigger.c:128
override void EOnFrame(IEntity other, float timeSlice)
When an Object touches the Trigger, we want to register it being inside the Trigger -> Replaced by EO...
Definition Trigger.c:88
private void Trigger()
ctor
Definition Trigger.c:53
override void EOnEnter(IEntity other, int extra)
When an Object enters the trigger add it to Insiders.
Definition Trigger.c:94
The object which is in a trigger and its metadata.
Definition Trigger.c:3
ref OLinkT insider
Definition Trigger.c:4
protected Object m_Object
Object that data belongs to.
Definition Trigger.c:7
void ~TriggerInsider()
Definition Trigger.c:24
int timeStamp
Last time the object was seen in ms.
Definition Trigger.c:10
float lastUpdated
Last time the object was updated in seconds, is used for calculating deltaTime.
Definition Trigger.c:16
Object GetObject()
Definition Trigger.c:28
float timeEntered
Time the object was first seen in seconds.
Definition Trigger.c:13
void TriggerInsider(Object obj)
Definition Trigger.c:18
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
static const vector Zero
Definition EnConvert.c:110
Link< Object > OLinkT
Definition gameplay.c:1453
proto native CGame GetGame()
const int COLOR_BLUE_A
Definition constants.c:71
const int COLOR_RED_A
Definition constants.c:69
const int COLOR_YELLOW_A
Definition constants.c:72
const int COLOR_GREEN_A
Definition constants.c:70
ErrorExSeverity
Definition EnDebug.c:62
void Error(string err)
Messagebox with error message.
Definition EnDebug.c:90
enum ShapeType ErrorEx
proto native void SetFlags(ShapeFlags flags)
ShapeFlags
Definition EnDebug.c:126
static proto bool GetBool(int id, bool reverse=false)
Get value as bool from the given script id.
class DiagMenu Shape
don't call destructor directly. Use Destroy() instead
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition EnEntity.c:45
EntityFlags
Entity flags.
Definition EnEntity.c:115