Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
totem.c
Go to the documentation of this file.
2{
3 const float MAX_ACTION_DETECTION_ANGLE_RAD = 1.3; //1.3 RAD = ~75 DEG
4 const float MAX_ACTION_DETECTION_DISTANCE = 2.0; //meters
5
6 bool m_RefresherActive;
7 bool m_RefresherActiveLocal;
8 bool m_RefresherInitialized;
9 int m_RefresherTimeRemaining;
10 int m_RefreshTimeCounter;
11
12 protected int m_FlagRefresherFrequency = GameConstants.REFRESHER_FREQUENCY_DEFAULT; //how often does the flag increase lifetimes
13 protected int m_FlagRefresherMaxDuration = GameConstants.REFRESHER_MAX_DURATION_DEFAULT; //how long will the refresher run; multiple of m_FlagRefresherFrequency by default
14
16 {
17 m_RefresherActive = false;
18 m_RefresherActiveLocal = false;
19 m_RefresherInitialized = false;
20 m_RefresherTimeRemaining = 0;
21
22 if ( GetCEApi() )
23 {
24 InitRefresherData();
25 }
26 RegisterNetSyncVariableBool("m_RefresherActive");
27 }
28
30 {
31 RemoveRefresherPosition();
32 }
33
35 {
36 int frequency = GetCEApi().GetCEGlobalInt("FlagRefreshFrequency");
37 int max_duration = GetCEApi().GetCEGlobalInt("FlagRefreshMaxDuration");
38
39 if ( frequency > 0)
40 {
41 m_FlagRefresherFrequency = frequency;
42 }
43 if ( max_duration > 0 )
44 {
45 m_FlagRefresherMaxDuration = max_duration;
46 }
47 m_RefresherInitialized = true;
48 }
49
50 override string GetConstructionKitType()
51 {
52 return "TerritoryFlagKit";
53 }
54
55 override int GetMeleeTargetType()
56 {
57 return EMeleeTargetType.NONALIGNABLE;
58 }
59
60 /*override bool NameOverride(out string output)
61 {
62 if ( m_GateState != GATE_STATE_NONE )
63 {
64 output = "#str_cfgvehicles_construction_part_gate"; //changes object displayed name if in 'gate' state
65 output.ToUpper();
66 return true;
67 }
68 return false;
69 }*/
70
71 //--- CONSTRUCTION KIT
73 {
74 if ( MemoryPointExists( "kit_spawn_position" ) )
75 {
76 vector position;
77 position = GetMemoryPointPos( "kit_spawn_position" );
78
79 return ModelToWorld( position );
80 }
81
82 return GetPosition();
83 }
84
85 override bool CanDisplayAttachmentCategory( string category_name )
86 {
87 if ( category_name == "Base" && !HasBase() )
88 return true;
89 else if ( category_name == "Support" && HasBase() && !GetConstruction().IsPartConstructed("support") )
90 return true;
91 else if ( category_name == "Pole" && GetConstruction().IsPartConstructed("support") && !GetConstruction().IsPartConstructed("pole") )
92 return true;
93 else if ( category_name == "Flag" && GetConstruction().IsPartConstructed("pole") )
94 return true;
95 else
96 return false;
97 }
98 // ---
99
100 // --- EVENTS
101 override void OnStoreSave( ParamsWriteContext ctx )
102 {
103 super.OnStoreSave( ctx );
104
105 ctx.Write( m_RefresherTimeRemaining );
106 ctx.Write( m_RefreshTimeCounter );
107 ctx.Write( m_FlagRefresherMaxDuration );
108 ctx.Write( m_RefresherActive );
109 }
110
111 override bool OnStoreLoad( ParamsReadContext ctx, int version )
112 {
113 if ( !super.OnStoreLoad( ctx, version ) )
114 return false;
115
116 //int loaded_frequency;
117 int loaded_max_duration;
118
119 if ( !ctx.Read( m_RefresherTimeRemaining ) )
120 {
121 return false;
122 }
123
124 if ( !ctx.Read( m_RefreshTimeCounter ) )
125 {
126 return false;
127 }
128
129 if ( !ctx.Read( loaded_max_duration ) )
130 {
131 return false;
132 }
133
134 if ( version >= 118 && !ctx.Read( m_RefresherActive ) )
135 {
136 return false;
137 }
138
139 CheckLoadedVariables(loaded_max_duration);
140 AnimateFlag(1 - GetRefresherTime01());
141
142 return true;
143 }
144
145 override void AfterStoreLoad()
146 {
147 super.AfterStoreLoad();
148
149 if (!m_RefresherInitialized && GetCEApi())
150 {
151 InitRefresherData();
152 }
153 SetSynchDirty();
155 }
156
157 override void OnCEUpdate()
158 {
159 super.OnCEUpdate();
160
161 int time_elapsed_rounded = Math.Round(m_ElapsedSinceLastUpdate);
162
163 if ( m_RefresherTimeRemaining > 0 )
164 {
165 m_RefreshTimeCounter += time_elapsed_rounded;
166 if ( m_RefreshTimeCounter >= m_FlagRefresherFrequency )
167 {
168 GetCEApi().RadiusLifetimeReset(GetPosition(),GameConstants.REFRESHER_RADIUS);
169 m_RefresherTimeRemaining = Math.Clamp(m_RefresherTimeRemaining - m_RefreshTimeCounter,0,m_FlagRefresherMaxDuration);
170 m_RefreshTimeCounter = 0; //possibly carry over the rest?
171 AnimateFlag( 1 - GetRefresherTime01() );
172 }
173 }
174
175 SetRefresherActive(m_RefresherTimeRemaining > 0);
176 }
177
180 {
181 Mission mission = GetGame().GetMission();
182 if (!mission.m_ActiveRefresherLocations)
183 return;
184
185 int idx = mission.m_ActiveRefresherLocations.Find(GetPosition());
186 if ( m_RefresherActive && idx == -1 )
187 {
188 InsertRefresherPosition();
189 }
190 else if ( !m_RefresherActive && idx > -1 )
191 {
192 RemoveRefresherPosition(idx);
193 }
194 }
195
196 void SetRefresherActive(bool state)
197 {
198 if ( m_RefresherActive != state )
199 {
200 m_RefresherActive = state;
201 SetSynchDirty();
202
203 HandleRefreshers();
204
205 //update on refresher activation / last update on refresher deactivation
206 if (GetCEApi())
207 GetCEApi().RadiusLifetimeReset(GetPosition(),GameConstants.REFRESHER_RADIUS);
208 }
209 }
210
212 {
213 Mission mission = GetGame().GetMission();
214 mission.m_ActiveRefresherLocations.Insert(GetPosition());
215 }
216
217 void RemoveRefresherPosition(int idx = -2)
218 {
219 if (!GetGame())
220 return;
221
222 Mission mission = GetGame().GetMission();
223 if (!mission || !mission.m_ActiveRefresherLocations)
224 return;
225
226 if (idx == -2)
227 {
228 idx = mission.m_ActiveRefresherLocations.Find(GetPosition());
229 }
230
231 if (idx > -1)
232 {
233 mission.m_ActiveRefresherLocations.Remove(idx);
234 }
235 }
236
238 {
239 super.OnVariablesSynchronized();
240
241 if ( m_RefresherActive != m_RefresherActiveLocal )
242 {
243 HandleRefreshers();
244 m_RefresherActiveLocal = m_RefresherActive;
245 }
246 }
247
248 //--- BUILD EVENTS
249 //CONSTRUCTION EVENTS
250 override void OnPartBuiltServer( notnull Man player, string part_name, int action_id )
251 {
252 //ConstructionPart constrution_part = GetConstruction().GetConstructionPart( part_name );
253
254 super.OnPartBuiltServer( player, part_name, action_id );
255
256 //update visuals (server)
258 }
259
260 override void OnPartDismantledServer( notnull Man player, string part_name, int action_id )
261 {
262 ConstructionPart constrution_part = GetConstruction().GetConstructionPart( part_name );
263
264 super.OnPartDismantledServer( player, part_name, action_id );
265
266 //update visuals (server)
268 }
269
270 override void OnPartDestroyedServer( Man player, string part_name, int action_id, bool destroyed_by_connected_part = false )
271 {
272 super.OnPartDestroyedServer( player, part_name, action_id );
273
274 //update visuals (server)
276 }
277
278 //--- ATTACHMENT & CONDITIONS
279 override void EEItemDetached( EntityAI item, string slot_name )
280 {
281 super.EEItemDetached( item, slot_name );
282
283 if (GetGame().IsServer()) // reset totem state is flag is decrafted while raised
284 {
285 float state = GetAnimationPhase("flag_mast");
286 if (state < 1)
287 {
288 AnimateFlag(1);
289 SetRefreshTimer01(0);
290 }
291 }
292 }
293
294 override bool CanReceiveAttachment( EntityAI attachment, int slotId ) //TODO
295 {
296 if ( !super.CanReceiveAttachment(attachment, slotId) )
297 return false;
298
299 //manage action initiator (AT_ATTACH_TO_CONSTRUCTION)
300 if ( !GetGame().IsDedicatedServer() )
301 {
302 PlayerBase player = PlayerBase.Cast( GetGame().GetPlayer() );
303 if ( player )
304 {
305 ConstructionActionData construction_action_data = player.GetConstructionActionData();
306
307 //reset action initiator
308 construction_action_data.SetActionInitiator( NULL );
309 }
310 }
311
312 //conditions
313 string slot_name = InventorySlots.GetSlotName(slotId);
314 //flag item attachment
315 if ( slot_name == "Material_FPole_Flag" )
316 {
317 if ( GetConstruction().IsPartConstructed("pole") )
318 return true;
319 else
320 return false;
321 }
322 //materials
323 ConstructionPart part;
324 ConstructionPart part_lowest;
325 int part_id = -1;
326 for (int i = 0; i < GetConstruction().GetConstructionParts().Count(); i++)
327 {
328 part = GetConstruction().GetConstructionParts().GetElement(i);
329 if (!part.IsBuilt())
330 {
331 if (part_id == -1 || part_id > part.GetId())
332 {
333 part_lowest = part;
334 part_id = part.GetId();
335 }
336 }
337 }
338
339 if (part_lowest /*&& !part_lowest.IsBuilt()*/)
340 {
341 string cfg_path = "cfgVehicles " + GetType() + " Construction " + part_lowest.GetMainPartName() + " " + part_lowest.GetPartName() + " Materials";
342 string material_path;
343 if ( GetGame().ConfigIsExisting(cfg_path) )
344 {
345 string child_name;
346 string child_slot_name;
347 for ( i = 0; i < GetGame().ConfigGetChildrenCount( cfg_path ); i++ )
348 {
349 GetGame().ConfigGetChildName( cfg_path, i, child_name );
350 material_path = "" + cfg_path + " " + child_name + " slot_name";
351 if ( GetGame().ConfigGetText(material_path,child_slot_name) && child_slot_name == slot_name )
352 {
353 return true;
354 }
355 }
356 }
357 }
358
359 return false;
360 }
361
362 //hands
363 override bool CanPutIntoHands( EntityAI parent )
364 {
365 return false;
366 }
367
369 {
370 return true;
371 }
372
373 //--- ACTION CONDITIONS
374 override bool IsPlayerInside( PlayerBase player, string selection )
375 {
376 return true; //TODO
377
378 vector player_pos = player.GetPosition();
379 vector fence_pos = GetPosition();
380 vector ref_dir = GetDirection();
381 ref_dir[1] = 0;
382 ref_dir.Normalize();
383
384 vector x[2];
385 vector b1,b2;
386 GetCollisionBox(x);
387 b1 = x[0];
388 b2 = x[1];
389
390 vector dir_to_fence = fence_pos - player_pos;
391 dir_to_fence[1] = 0;
392 float len = dir_to_fence.Length();
393
394 dir_to_fence.Normalize();
395
396 vector ref_dir_angle = ref_dir.VectorToAngles();
397 vector dir_to_fence_angle = dir_to_fence.VectorToAngles();
398 vector test_angles = dir_to_fence_angle - ref_dir_angle;
399
400 vector test_position = test_angles.AnglesToVector() * len;
401
402 if(test_position[0] < b1[0] || test_position[0] > b2[0] || test_position[2] < 0.2 || test_position[2] > 2.2 )
403 {
404 return false;
405 }
406 else
407 {
408 return true;
409 }
410 }
411
412 override bool IsFacingPlayer( PlayerBase player, string selection )
413 {
414 return true; //TODO
415
416 vector fence_pos = GetPosition();
417 vector player_pos = player.GetPosition();
418 vector ref_dir = GetDirection();
419
420 //vector fence_player_dir = player_pos - fence_pos;
421 vector fence_player_dir = player.GetDirection();
422 fence_player_dir.Normalize();
423 fence_player_dir[1] = 0; //ignore height
424
425 ref_dir.Normalize();
426 ref_dir[1] = 0; //ignore height
427
428 if ( ref_dir.Length() != 0 )
429 {
430 float angle = Math.Acos( fence_player_dir * ref_dir );
431
432 if ( angle >= MAX_ACTION_DETECTION_ANGLE_RAD )
433 {
434 return true;
435 }
436 }
437
438 return false;
439 }
440
441 override bool IsFacingCamera( string selection )
442 {
443 return false; //TODO
444
445 vector ref_dir = GetDirection();
446 vector cam_dir = GetGame().GetCurrentCameraDirection();
447
448 //ref_dir = GetGame().GetCurrentCameraPosition() - GetPosition();
449 ref_dir.Normalize();
450 ref_dir[1] = 0; //ignore height
451
452 cam_dir.Normalize();
453 cam_dir[1] = 0; //ignore height
454
455 if ( ref_dir.Length() != 0 )
456 {
457 float angle = Math.Acos( cam_dir * ref_dir );
458
459 if ( angle >= MAX_ACTION_DETECTION_ANGLE_RAD )
460 {
461 return true;
462 }
463 }
464
465 return false;
466 }
467
468 override bool HasProperDistance( string selection, PlayerBase player )
469 {
470 //TODO
471 if ( MemoryPointExists( selection ) )
472 {
473 vector selection_pos = ModelToWorld( GetMemoryPointPos( selection ) );
474 float distance = vector.Distance( selection_pos, player.GetPosition() );
475 if ( distance >= MAX_ACTION_DETECTION_DISTANCE )
476 {
477 return false;
478 }
479 }
480
481 return true;
482 }
483
484 //================================================================
485 // SOUNDS
486 //================================================================
487 //TODO
488
489 override void SetActions()
490 {
491 super.SetActions();
492
496 }
497
498 /*override void UpdateVisuals()
499 {
500 super.UpdateVisuals();
501 }*/
502
503 //================================================================
504 // FLAG MANIPULATION + REFRESHER
505 //================================================================
506 void AnimateFlagEx(float delta, PlayerBase player = null)
507 {
508 float temp = Math.Clamp( delta,0,1 );
509 float phase_new;
510 if (temp < 0.01 || temp > 0.99)
511 {
512 phase_new = Math.Round(temp);
513 }
514 else
515 phase_new = temp;
516
517 SetAnimationPhase("flag_mast",phase_new);
518
519 if (player)
520 LogAnimateFlag(phase_new, player);
521
522 GetInventory().SetSlotLock(InventorySlots.GetSlotIdFromString("Material_FPole_Flag"),phase_new != 1);
523
524 }
525
526 void AnimateFlag(float delta)
527 {
528 AnimateFlagEx(delta);
529 }
530
531 protected void LogAnimateFlag(float newPhase, notnull PlayerBase player)
532 {
533 PluginAdminLog logs = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
534 if (newPhase == 0)
535 {
536 // at the top(it's inverted)
537 logs.TotemFlagChange(true, player, this);
538 }
539 else if (newPhase == 1)
540 {
541 // at the bottom(it's inverted)
542 logs.TotemFlagChange(false, player, this);
543 }
544
545 }
546
547 void SetRefreshTimer01(float fraction)
548 {
549 float temp = Math.Clamp(m_FlagRefresherMaxDuration * fraction, 0, m_FlagRefresherMaxDuration);
550 m_RefresherTimeRemaining = Math.Round(temp);
551 }
552
553 /*void AddRefresherTimeFlat(float seconds) //seconds?
554 {
555 float temp = Math.Clamp(m_RefresherTimeRemaining + seconds, 0, m_FlagRefresherMaxDuration);
556 m_RefresherTimeRemaining = Math.Round(temp);
557 SetRefresherActive(m_RefresherTimeRemaining > 0);
558 }*/
559
560 void AddRefresherTime01(float fraction)
561 {
562 float temp = Math.Clamp(m_RefresherTimeRemaining + (fraction * m_FlagRefresherMaxDuration), 0, m_FlagRefresherMaxDuration);
563 m_RefresherTimeRemaining = Math.Round(temp);
564 SetRefresherActive(m_RefresherTimeRemaining > 0);
565 //Print(m_RefresherTimeRemaining);
566 }
567
569 {
570 return m_RefresherTimeRemaining / m_FlagRefresherMaxDuration;
571 }
572
573 void CheckLoadedVariables(int max_duration)
574 {
575 if (max_duration != m_FlagRefresherMaxDuration)
576 {
577 m_RefresherTimeRemaining = m_FlagRefresherMaxDuration * m_RefresherTimeRemaining / max_duration;
578 }
579 }
580
581 //================================================================
582 // DEBUG
583 //================================================================
584 /*
585 override void DebugCustomState()
586 {
587 //debug
588 m_SyncParts01 = 881; //full fence with gate
589 m_HasHinges = true;
590 m_HasBase = true;
591
592 OnVariablesSynchronized();
593 }
594 */
595
596 //Debug menu Spawn Ground Special
597 override void OnDebugSpawn()
598 {
599 super.OnDebugSpawn();
600
601 GetInventory().CreateInInventory("Flag_DayZ");
602 AnimateFlag(0);
603 AddRefresherTime01(1);
604 }
605}
eBleedingSourceType GetType()
ActionFoldBaseBuildingObjectCB ActionContinuousBaseCB ActionFoldBaseBuildingObject()
void AddAction(typename actionName)
Construction GetConstruction()
bool HasBase()
override bool CanDisplayAttachmentCategory(string category_name)
Definition totem.c:85
void TerritoryFlag()
Definition totem.c:15
override void OnDebugSpawn()
Definition totem.c:597
override bool IsPlayerInside(PlayerBase player, string selection)
Definition totem.c:374
override void OnVariablesSynchronized()
Definition totem.c:237
void ~TerritoryFlag()
Definition totem.c:29
void SetRefreshTimer01(float fraction)
Definition totem.c:547
void RemoveRefresherPosition(int idx=-2)
Definition totem.c:217
override string GetConstructionKitType()
Definition totem.c:50
float GetRefresherTime01()
Definition totem.c:568
override void EEItemDetached(EntityAI item, string slot_name)
Definition totem.c:279
override bool CanPutIntoHands(EntityAI parent)
Definition totem.c:363
override void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
Definition totem.c:250
override void SetActions()
Definition totem.c:489
void AddRefresherTime01(float fraction)
Definition totem.c:560
void SetRefresherActive(bool state)
Definition totem.c:196
override bool IsFacingCamera(string selection)
Definition totem.c:441
override bool IsFacingPlayer(PlayerBase player, string selection)
Definition totem.c:412
override void OnCEUpdate()
Definition totem.c:157
override void AfterStoreLoad()
Definition totem.c:145
override bool OnStoreLoad(ParamsReadContext ctx, int version)
Definition totem.c:111
void LogAnimateFlag(float newPhase, notnull PlayerBase player)
Definition totem.c:531
override int GetMeleeTargetType()
Definition totem.c:55
override bool HasProperDistance(string selection, PlayerBase player)
Definition totem.c:468
void HandleRefreshers()
Saves positions of active lifetime refreshers to MissionGameplay / MissionServer.
Definition totem.c:179
void InitRefresherData()
Definition totem.c:34
override void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
Definition totem.c:270
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Definition totem.c:294
void CheckLoadedVariables(int max_duration)
Definition totem.c:573
override void OnStoreSave(ParamsWriteContext ctx)
Definition totem.c:101
void InsertRefresherPosition()
Definition totem.c:211
override vector GetKitSpawnPosition()
Definition totem.c:72
override bool CanBeRepairedToPristine()
Definition totem.c:368
void AnimateFlagEx(float delta, PlayerBase player=null)
Definition totem.c:506
void AnimateFlag(float delta)
Definition totem.c:526
override void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
Definition totem.c:260
void SetActionInitiator(PlayerBase action_initiator)
provides access to slot configuration
Definition enmath.c:7
Mission class.
Definition gameplay.c:687
Serialization general interface. Serializer API works with:
Definition serializer.c:56
void UpdateVisuals()
bool IsPartConstructed(string part_name)
Mission mission
EMeleeTargetType
proto native CGame GetGame()
class JsonUndergroundAreaTriggerData GetPosition
Icon x
PlayerBase GetPlayer()
PluginBase GetPlugin(typename plugin_type)