Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
watchtower.c
Go to the documentation of this file.
1class Watchtower extends BaseBuildingBase
2{
3 typename ATTACHMENT_BARBED_WIRE = BarbedWire;
4 typename ATTACHMENT_CAMONET = CamoNet;
5
6 const float MAX_FLOOR_VERTICAL_DISTANCE = 0.5;
7
8 const float MIN_ACTION_DETECTION_ANGLE_RAD = 0.35; //0.35 RAD = 20 DEG
9 const float MAX_ACTION_DETECTION_DISTANCE = 2.0; //meters
10
11 static const string BASE_VIEW_NAME = "level_";
12 static const string BASE_WALL_NAME = "_wall_";
13 static const string BASE_ROOF_NAME = "_roof";
14 static const int MAX_WATCHTOWER_FLOORS = 3;
15 static const int MAX_WATCHTOWER_WALLS = 3;
16
17 void Watchtower()
18 {
19 }
20
21 override string GetConstructionKitType()
22 {
23 return "WatchtowerKit";
24 }
25
26 override int GetMeleeTargetType()
27 {
28 return EMeleeTargetType.NONALIGNABLE;
29 }
30
31 /*override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
32 {
33 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
34
35 if (component == -1)
36 {
37 Print("EEHitBy: " + this + "; damageType: "+ damageType +"; source: "+ source +"; component: "+ component +"; dmgZone: "+ dmgZone +"; ammo: "+ ammo +"; modelPos: "+ modelPos);
38 Print("GetDamage " + damageResult.GetDamage("","Health"));
39 Print("GetHighestDamage " + damageResult.GetHighestDamage("Health"));
40 }
41 }*/
42
43 //overriden for the express purpose of handling view geometry (interaction) animations
44 override void UpdateVisuals()
45 {
46 super.UpdateVisuals();
47
48 SetAnimationPhase( "level_1", 0); //always visible
49 SetAnimationPhase( "level_1_wall_1", 0); //always visible
50 SetAnimationPhase( "level_1_wall_2", 0); //always visible
51 SetAnimationPhase( "level_1_wall_3", 0); //always visible
52
53 string part_name = "";
54 bool built = false;
55
56 for ( int i = 1; i < MAX_WATCHTOWER_FLOORS; ++i )
57 {
58 //roof checks
59 part_name = "" + BASE_VIEW_NAME + i + BASE_ROOF_NAME;
60 built = GetConstruction().IsPartConstructed(part_name);
61 //Print(part_name);
62 //Print(built);
63
64 //string tmp = "";
65
66 if ( built )
67 {
68 SetAnimationPhase( BASE_VIEW_NAME + (i + 1), 0); //show
69 for ( int j = 1; j < MAX_WATCHTOWER_WALLS + 1; ++j )
70 {
71 //tmp = BASE_VIEW_NAME + (i + 1) + BASE_WALL_NAME + j;
72 //Print(tmp);
73 SetAnimationPhase( BASE_VIEW_NAME + (i + 1) + BASE_WALL_NAME + j, 0); //show
74 }
75 }
76 else
77 {
78 SetAnimationPhase( BASE_VIEW_NAME + (i + 1), 1 ); //hide
79 for ( j = 1; j < MAX_WATCHTOWER_WALLS + 1; ++j )
80 {
81 //tmp = BASE_VIEW_NAME + (i + 1) + BASE_WALL_NAME + j;
82 //Print(tmp);
83 SetAnimationPhase( BASE_VIEW_NAME + (i + 1) + BASE_WALL_NAME + j, 1); //hide
84 }
85 }
86 }
87 }
88
89 //--- ATTACHMENT & CONDITIONS
90 override bool CanReceiveAttachment( EntityAI attachment, int slotId )
91 {
92 if ( !super.CanReceiveAttachment( attachment, slotId ) )
93 return false;
94
95 //because CanReceiveAttachment() method can be called on all clients in the vicinity, vertical distance check needs to be skipped on clients that don't
96 //interact with the object through attach action (AT_ATTACH_TO_CONSTRUCTION)
97 PlayerBase player;
98 if ( !GetGame().IsDedicatedServer() )
99 {
100 //check action initiator (AT_ATTACH_TO_CONSTRUCTION)
101 player = PlayerBase.Cast( GetGame().GetPlayer() );
102 if ( player )
103 {
104 ConstructionActionData construction_action_data = player.GetConstructionActionData();
105 PlayerBase action_initiator = construction_action_data.GetActionInitiator();
106
107 if ( action_initiator == player )
108 {
109 construction_action_data.SetActionInitiator( NULL ); //reset action initiator
110 }
111 else
112 {
113 player = null; //do not do vertical check (next)
114 }
115 }
116 }
117 //
118
119 return CheckSlotVerticalDistance( slotId, player );
120 }
121
122 //can put into hands
123 override bool CanPutIntoHands( EntityAI parent )
124 {
125 return false;
126 }
127
128 override bool CanBeRepairedToPristine()
129 {
130 return true;
131 }
132
133 override bool PerformRoofCheckForBase( string partName, PlayerBase player, out bool result )
134 {
135 if (CfgGameplayHandler.GetDisablePerformRoofCheck())
136 return false;
137
138 if (partName != "level_1_base" && partName != "level_2_base" && partName != "level_3_base" && partName != "level_3_roof")
139 {
140 return false;
141 }
142
143 vector center;
144 vector orientation = GetOrientation();
145 vector edge_length;
146 vector min_max[2];
147 ref array<Object> excluded_objects = new array<Object>;
148 ref array<Object> collided_objects = new array<Object>;
149
150 excluded_objects.Insert( this );
151 excluded_objects.Insert( player );
152
153 if ( partName == "level_2_base" )
154 {
155 min_max[0] = GetMemoryPointPos( "level_2_wall_1_down_min" );
156 min_max[1] = GetMemoryPointPos( "level_2_roof_max" );
157 }
158 else if ( partName == "level_3_base" )
159 {
160 min_max[0] = GetMemoryPointPos( "level_3_wall_1_down_min" );
161 min_max[1] = GetMemoryPointPos( "level_3_wall_2_up_max" );
162 }
163 else if ( partName == "level_3_roof" )
164 {
165 min_max[0] = GetMemoryPointPos( "level_3_roof_min" );
166 min_max[1] = GetMemoryPointPos( "level_3_roof_max" );
167 }
168 else
169 {
170 //min_max[0] = GetMemoryPointPos( "level_1_wall_1_up_min" );
171 //min_max[0] = GetMemoryPointPos( "level_1_wall_1_down_min" );
172 min_max[0] = GetMemoryPointPos( "level_1_collisioncheck_min" );
173 min_max[1] = GetMemoryPointPos( "level_1_roof_max" );
174 }
175 center = GetPosition();
176 center[1] = center[1] + ( min_max[1][1] + min_max[0][1] ) / 2;
177
178 edge_length[0] = min_max[1][0] - min_max[0][0];
179 edge_length[2] = min_max[1][2] - min_max[0][2];
180 edge_length[1] = min_max[1][1] - min_max[0][1];
181
182 result = false;
183 /*result = */GetGame().IsBoxCollidingGeometry( center, orientation, edge_length, ObjIntersectView, ObjIntersectGeom, excluded_objects, collided_objects );
184 if ( collided_objects.Count() > 0 )
185 {
186 foreach ( Object o : collided_objects )
187 {
188 if (Building.Cast(o))
189 {
190 result = true;
191 }
192 }
193 }
194 return true;
195 }
196
197 // --- INVENTORY
198 override bool CanDisplayAttachmentSlot( int slot_id )
199 {
200 //super
201 if ( !super.CanDisplayAttachmentSlot( slot_id ) )
202 return false;
203
204 string slot_name = InventorySlots.GetSlotName(slot_id);
205 slot_name.ToLower();
206 PlayerBase player = PlayerBase.Cast( GetGame().GetPlayer() );
207 //base attachments
208 if ( slot_name.Contains( "material_l1" ) || slot_name.Contains( "level_1_" ) )
209 {
210 if ( slot_name.Contains( "woodenlogs" ) )
211 {
212 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
213 }
214 else
215 {
216 return GetConstruction().IsPartConstructed( "level_1_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
217 }
218 }
219 else if ( slot_name.Contains( "material_l2" ) || slot_name.Contains( "level_2_" ) )
220 {
221 if ( slot_name.Contains( "woodenlogs" ) )
222 {
223 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
224 }
225 else
226 {
227 return GetConstruction().IsPartConstructed( "level_2_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
228 }
229 }
230 else if ( slot_name.Contains( "material_l3" ) || slot_name.Contains( "level_3_" ) )
231 {
232 if ( slot_name.Contains( "woodenlogs" ) )
233 {
234 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
235 }
236 else
237 {
238 return GetConstruction().IsPartConstructed( "level_3_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
239 }
240 }
241
242 return true;
243 }
244
245 override bool CanDisplayAttachmentCategory( string category_name )
246 {
247 //super
248 if ( !super.CanDisplayAttachmentCategory( category_name ) )
249 return false;
250 //
251
252 category_name.ToLower();
253 PlayerBase player = PlayerBase.Cast( GetGame().GetPlayer() );
254 //level 1
255 if ( category_name.Contains( "level_1" ) )
256 {
257 if ( category_name.Contains( "level_1_" ) )
258 {
259 return GetConstruction().IsPartConstructed( "level_1_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
260 }
261 else
262 {
263 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
264 }
265 }
266 //level 2
267 if ( category_name.Contains( "level_2" ) )
268 {
269 if ( category_name.Contains( "level_2_" ) )
270 {
271 return GetConstruction().IsPartConstructed( "level_2_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
272 }
273 else
274 {
275 return GetConstruction().IsPartConstructed( "level_1_roof" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
276 }
277 }
278 //level 3
279 if ( category_name.Contains( "level_3" ) )
280 {
281 if ( category_name.Contains( "level_3_" ) )
282 {
283 return GetConstruction().IsPartConstructed( "level_3_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
284 }
285 else
286 {
287 return GetConstruction().IsPartConstructed( "level_2_roof" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
288 }
289 }
290
291 return true;
292 }
293
294 //returns true if attachment slot position is within given range
295 override bool CheckSlotVerticalDistance( int slot_id, PlayerBase player )
296 {
297 string slot_name;
298 InventorySlots.GetSelectionForSlotId( slot_id , slot_name );
299 slot_name.ToLower();
300
301 //wall attachments
302 //level 1
303 if ( slot_name.Contains( "material_l1" ) || slot_name.Contains( "level_1_" ) )
304 {
305 if ( slot_name.Contains( "woodenlogs" ) )
306 {
307 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
308 }
309 else
310 {
311 return GetConstruction().IsPartConstructed( "level_1_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_1", player );
312 }
313 }
314 //level 2
315 if ( slot_name.Contains( "material_l2" ) || slot_name.Contains( "level_2_" ) )
316 {
317 if ( slot_name.Contains( "material_l2w" ) || slot_name.Contains( "level_2_wall" ) )
318 {
319 return GetConstruction().IsPartConstructed( "level_2_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
320 }
321 else
322 {
323 if ( slot_name.Contains( "woodenlogs" ) )
324 {
325 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
326 }
327 else
328 {
329 return GetConstruction().IsPartConstructed( "level_1_roof" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_2", player );
330 }
331 }
332 }
333 //level 3
334 if ( slot_name.Contains( "material_l3" ) || slot_name.Contains( "level_3_" ) )
335 {
336 if ( slot_name.Contains( "material_l3w" ) || slot_name.Contains( "level_3_wall" ) )
337 {
338 return GetConstruction().IsPartConstructed( "level_3_base" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
339 }
340 else
341 {
342 if ( slot_name.Contains( "woodenlogs" ) )
343 {
344 return CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
345 }
346 else
347 {
348 return GetConstruction().IsPartConstructed( "level_2_roof" ) && CheckMemoryPointVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, "level_3", player );
349 }
350 }
351 }
352
353 return true;
354 }
355
356 //returns true if player->mem_point position is within given range
357 override bool CheckMemoryPointVerticalDistance( float max_dist, string selection, PlayerBase player )
358 {
359 if ( player )
360 {
361 //check vertical distance
362 vector player_pos = player.GetPosition();
363 vector pos;
364
365 if ( MemoryPointExists( selection ) )
366 {
367 pos = ModelToWorld( GetMemoryPointPos( selection ) );
368 }
369
370 if ( Math.AbsFloat( player_pos[1] - pos[1] ) <= max_dist )
371 {
372 return true;
373 }
374 else
375 {
376 return false;
377 }
378 }
379
380 return true;
381 }
382
383 override bool CheckLevelVerticalDistance( float max_dist, string selection, PlayerBase player )
384 {
385 if ( player )
386 {
387 if ( selection.Contains( "level_1_" ) )
388 return CheckMemoryPointVerticalDistance( max_dist, "level_1", player );
389
390 if ( selection.Contains( "level_2_" ) )
391 return CheckMemoryPointVerticalDistance( max_dist, "level_2", player );
392
393 if ( selection.Contains( "level_3_" ) )
394 return CheckMemoryPointVerticalDistance( max_dist, "level_3", player );
395 }
396 return false;
397 }
398 // ---
399 override void AfterStoreLoad()
400 {
401 super.AfterStoreLoad();
402
404 }
405
406 override void OnPartBuiltServer( notnull Man player, string part_name, int action_id )
407 {
408 super.OnPartBuiltServer( player, part_name, action_id );
409 //update visuals (server)
411 }
412
413 override void OnPartDismantledServer( notnull Man player, string part_name, int action_id )
414 {
415 super.OnPartDismantledServer( player, part_name, action_id );
416 //update visuals (server)
418 }
419
420 override void OnPartDestroyedServer( Man player, string part_name, int action_id, bool destroyed_by_connected_part = false )
421 {
422 super.OnPartDestroyedServer( player, part_name, action_id );
423 //update visuals (server)
425 }
426
427 //--- ACTION CONDITIONS
428 //returns dot product of player->construction direction based on existing/non-existing reference point
429 override bool IsFacingPlayer( PlayerBase player, string selection )
430 {
431 vector ref_pos;
432 vector ref_dir;
433 vector player_dir;
434 float dot;
435 bool has_memory_point = MemoryPointExists( selection );
436
437 if ( has_memory_point )
438 {
439 ref_pos = ModelToWorld( GetMemoryPointPos( selection ) );
440 ref_dir = ref_pos - GetPosition();
441 }
442 else
443 {
444 ref_pos = GetPosition();
445 ref_dir = ref_pos - player.GetPosition();
446 }
447
448 ref_dir.Normalize();
449 ref_dir[1] = 0; //ignore height
450
451 player_dir = player.GetDirection();
452 player_dir.Normalize();
453 player_dir[1] = 0; //ignore height
454
455 if ( ref_dir.Length() != 0 )
456 {
457 dot = vector.Dot( player_dir, ref_dir );
458 }
459
460 if ( has_memory_point )
461 {
462 if ( dot < 0 && Math.AbsFloat( dot ) > MIN_ACTION_DETECTION_ANGLE_RAD )
463 {
464 return true;
465 }
466 }
467 else
468 {
469 if ( dot > 0 && Math.AbsFloat( dot ) > MIN_ACTION_DETECTION_ANGLE_RAD )
470 {
471 return true;
472 }
473 }
474
475 return false;
476 }
477
478 override bool IsFacingCamera( string selection )
479 {
480 vector ref_pos;
481 vector ref_dir;
482 vector cam_dir = GetGame().GetCurrentCameraDirection();
483
484 if ( MemoryPointExists( selection ) )
485 {
486 ref_pos = ModelToWorld( GetMemoryPointPos( selection ) );
487 ref_dir = ref_pos - GetPosition();
488
489 ref_dir.Normalize();
490 ref_dir[1] = 0; //ignore height
491
492 cam_dir[1] = 0; //ignore height
493
494 if ( ref_dir.Length() > 0.5 ) //if the distance (m) is too low, ignore this check
495 {
496 float dot = vector.Dot( cam_dir, ref_dir );
497
498 if ( dot < 0 )
499 {
500 return true;
501 }
502 }
503 }
504
505 return false;
506 }
507
508 override bool IsPlayerInside( PlayerBase player, string selection )
509 {
510 if ( selection != "")
511 {
512 CheckLevelVerticalDistance( MAX_FLOOR_VERTICAL_DISTANCE, selection, player );
513 }
514 vector player_pos = player.GetPosition();
515 vector tower_pos = GetPosition();
516 vector ref_dir = GetDirection();
517 ref_dir[1] = 0;
518 ref_dir.Normalize();
519
520 vector min,max;
521
522 min = -GetMemoryPointPos( "interact_min" );
523 max = -GetMemoryPointPos( "interact_max" );
524
525 vector dir_to_tower = tower_pos - player_pos;
526 dir_to_tower[1] = 0;
527 float len = dir_to_tower.Length();
528
529
530 dir_to_tower.Normalize();
531
532 vector ref_dir_angle = ref_dir.VectorToAngles();
533 vector dir_to_tower_angle = dir_to_tower.VectorToAngles();
534 vector test_angles = dir_to_tower_angle - ref_dir_angle;
535
536 vector test_position = test_angles.AnglesToVector() * len;
537
538 if (test_position[0] > max[0] || test_position[0] < min[0] || test_position[2] > max[2] || test_position[2] < min[2] )
539 {
540 return false;
541 }
542
543 return true;
544 }
545
546 override bool HasProperDistance( string selection, PlayerBase player )
547 {
548 if ( MemoryPointExists( selection ) )
549 {
550 vector selection_pos = ModelToWorld( GetMemoryPointPos( selection ) );
551 float distance = vector.Distance( selection_pos, player.GetPosition() );
552 if ( distance >= MAX_ACTION_DETECTION_DISTANCE )
553 {
554 return false;
555 }
556 }
557
558 return true;
559 }
560
561 override void SetActions()
562 {
563 super.SetActions();
564
568 }
569
570
571 //================================================================
572 // DEBUG
573 //================================================================
574
577 {
578 array<string> excludes;
579
580 #ifdef DIAG_DEVELOPER
581 bool bWood = DiagMenu.GetBool(DiagMenuIDs.BASEBUILDING_WOOD);
582 #else
583 bool bWood = false;
584 #endif
585
586 if (bWood)
587 {
588 excludes = {"_metal_"};
589 }
590 else
591 {
592 excludes = {"_wood_"};
593 }
594
595 return excludes;
596 }
597
598 //Debug menu Spawn Ground Special
599 override void OnDebugSpawn()
600 {
601 super.OnDebugSpawn();
602
603 int i;
604
605 for (i = 0; i < MAX_WATCHTOWER_FLOORS * MAX_WATCHTOWER_WALLS; ++i)
606 {
607 GetInventory().CreateInInventory("CamoNet");
608 }
609
610 for (i = 0; i < 2 * MAX_WATCHTOWER_WALLS; ++i)
611 {
612 BarbedWire wire = BarbedWire.Cast(GetInventory().CreateInInventory("BarbedWire"));
613 wire.SetMountedState(true);
614 }
615 }
616
617}
ActionFoldBaseBuildingObjectCB ActionContinuousBaseCB ActionFoldBaseBuildingObject()
ActionPlaceObjectCB ActiondeployObjectCB ActionPlaceObject()
void AddAction(typename actionName)
vector GetOrientation()
bool CheckMemoryPointVerticalDistance(float max_dist, string selection, PlayerBase player)
bool CheckSlotVerticalDistance(int slot_id, PlayerBase player)
bool PerformRoofCheckForBase(string partName, PlayerBase player, out bool result)
Construction GetConstruction()
bool CheckLevelVerticalDistance(float max_dist, string selection, PlayerBase player)
override bool CanDisplayAttachmentCategory(string category_name)
Definition fence.c:197
override void OnDebugSpawn()
Definition fence.c:892
override bool IsPlayerInside(PlayerBase player, string selection)
Definition fence.c:615
override bool CanDisplayAttachmentSlot(int slot_id)
Definition fence.c:176
override string GetConstructionKitType()
Definition fence.c:45
override bool CanPutIntoHands(EntityAI parent)
Definition fence.c:406
override array< string > OnDebugSpawnBuildExcludes()
Excludes certain parts from being built by OnDebugSpawn, uses Contains to compare.
Definition fence.c:854
override void OnPartBuiltServer(notnull Man player, string part_name, int action_id)
Definition fence.c:297
override void SetActions()
Definition fence.c:825
override bool IsFacingCamera(string selection)
Definition fence.c:678
override bool IsFacingPlayer(PlayerBase player, string selection)
Definition fence.c:651
override void AfterStoreLoad()
Definition fence.c:257
override int GetMeleeTargetType()
Definition fence.c:50
override bool HasProperDistance(string selection, PlayerBase player)
Definition fence.c:703
override void OnPartDestroyedServer(Man player, string part_name, int action_id, bool destroyed_by_connected_part=false)
Definition fence.c:331
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Definition fence.c:367
override bool CanBeRepairedToPristine()
Definition fence.c:421
override void OnPartDismantledServer(notnull Man player, string part_name, int action_id)
Definition fence.c:309
proto native bool IsBoxCollidingGeometry(vector center, vector orientation, vector edgeLength, int iPrimaryType, int iSecondaryType, array< Object > excludeObjects, array< Object > collidedObjects=NULL)
Finds all objects with geometry iType that are in choosen oriented bounding box (OBB)
void SetActionInitiator(PlayerBase action_initiator)
provides access to slot configuration
Definition enmath.c:7
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
void UpdateVisuals()
DiagMenuIDs
Definition ediagmenuids.c:2
EMeleeTargetType
proto native CGame GetGame()
class JsonUndergroundAreaTriggerData GetPosition
PlayerBase GetPlayer()