DayZ 1.27
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
Hologram.c
См. документацию.
2{
3 #ifdef SERVER
4 protected const int SPAWN_FLAGS = ECE_CREATEPHYSICS;
5 #else
6 protected const int SPAWN_FLAGS = ECE_LOCAL;
7 #endif
8
9
10 #ifdef DIAG_DEVELOPER
11 string m_CollisionDetails;
12 #endif
13
14 protected const string SUFFIX_MATERIAL_DEPLOYABLE = "_deployable.rvmat";
15 protected const string SUFFIX_MATERIAL_UNDEPLOYABLE = "_undeployable.rvmat";
16 protected const string SUFFIX_MATERIAL_POWERED = "_powered.rvmat";
17
18 protected const vector PLACEMENT_RC_START_OFFSET = "0 1 0";
19 protected const vector PLACEMENT_RC_END_OFFSET = "0 -2 0";
20
21 protected ItemBase m_Parent;
24 protected ProjectionTrigger m_ProjectionTrigger;
25 protected string m_ProjectionTypename;
26
27 protected bool m_IsColliding;
28 protected bool m_IsCollidingGPlot;
29 protected bool m_IsSlope;
30 protected bool m_IsCollidingPlayer;
31 protected bool m_IsFloating;
32 protected bool m_UpdatePosition;
33 protected bool m_IsHidden;
34
36 protected vector m_Rotation;
40 protected const string ANIMATION_PLACING = "Placing";
41 protected const string ANIMATION_INVENTORY = "Inventory";
42 protected const string SELECTION_PLACING = "placing";
43 protected const string SELECTION_INVENTORY = "inventory";
44
45 protected const float SMALL_PROJECTION_RADIUS = 1;
46 protected const float SMALL_PROJECTION_GROUND = 2;
47 protected const float DISTANCE_SMALL_PROJECTION = 1;
48 protected const float LARGE_PROJECTION_DISTANCE_LIMIT = 6;
49 protected const float PROJECTION_TRANSITION_MIN = 1;
50 protected const float PROJECTION_TRANSITION_MAX = 0.25;
51 protected const float LOOKING_TO_SKY = 0.75;
52 static const float DEFAULT_MAX_PLACEMENT_HEIGHT_DIFF = 1.5;
53
54 protected float m_SlopeTolerance;
55 protected bool m_AlignToTerrain;
57 protected int m_ContactComponent;
58
59 protected ref set<string> m_SelectionsToRefresh = new set<string>;
60
61 // Watchtower correction variables
62 // These watchtower component names should be corrected when colliding with them as they are supposed to be "trigger boxes", not colliders
64
65 // These watchtower components are supposed to be trigger boxes, but should block placement on them (currently only the boxes above the stairs)
67
68 void Hologram(PlayerBase player, vector pos, ItemBase item)
69 {
70 m_Player = player;
71 m_Parent = item;
72 m_Projection = null;
73
75 m_UpdatePosition = true;
77
78 m_Rotation = "0 0 0";
79 m_FromAdjusted = "0 0 0";
80
81 // If the static names are empty, generate the needed names
82 // Refer to their definitions to see why these are required
83 if (m_WatchtowerIgnoreComponentNames.Count() == 0)
84 {
85 string baseStringBegin = Watchtower.BASE_VIEW_NAME;
86 string baseIgnoreStringEnd = Watchtower.BASE_WALL_NAME;
87
88 int floors = Watchtower.MAX_WATCHTOWER_FLOORS;
89 int walls = Watchtower.MAX_WATCHTOWER_WALLS;
90
91 string compName;
92 for (int i = 1; i < floors + 1; ++i)
93 {
94 compName = baseStringBegin + i.ToString();
95 for (int j = 1; j < walls + 1; ++j)
96 m_WatchtowerIgnoreComponentNames.Insert(compName + baseIgnoreStringEnd + j.ToString());
97
98 if (i != 1)
99 m_WatchtowerBlockedComponentNames.Insert(compName);
100 else
101 m_WatchtowerIgnoreComponentNames.Insert(compName);
102 }
103 }
104
105 string configPathProjectionTypename = string.Format("CfgVehicles %1 projectionTypename", m_Parent.GetType());
106 if (GetGame().ConfigIsExisting(configPathProjectionTypename))
107 {
108 m_ProjectionTypename = GetGame().ConfigGetTextOut(configPathProjectionTypename);
109 }
110
111 EntityAI projectionEntity;
112 if (GetGame().IsMultiplayer() && GetGame().IsServer())
113 {
114 projectionEntity = EntityAI.Cast(GetGame().CreateObjectEx(ProjectionBasedOnParent(), pos, ECE_PLACE_ON_SURFACE));
115 projectionEntity.SetAllowDamage(false);
116 SetProjectionEntity(projectionEntity);
118 }
119 else
120 {
121 projectionEntity = EntityAI.Cast(GetGame().CreateObjectEx(ProjectionBasedOnParent(), pos, ECE_TRACE|ECE_LOCAL));
122 if (projectionEntity == null)
123 {
124 ErrorEx(string.Format("Cannot create hologram entity from config class %1", ProjectionBasedOnParent()), ErrorExSeverity.WARNING);
125 return;
126 }
127
128 SetProjectionEntity(projectionEntity);
132 }
133
134 if (ItemBase.Cast(projectionEntity))
135 {
136 ItemBase.Cast(GetProjectionEntity()).SetIsHologram(true);
137 }
138
139 string configPathSlope = string.Format("CfgVehicles %1 slopeTolerance", GetProjectionEntity().GetType());
140 if (GetGame().ConfigIsExisting(configPathSlope))
141 {
142 m_SlopeTolerance = GetGame().ConfigGetFloat(configPathSlope);
143 }
144
145 string configPathAlign = string.Format("CfgVehicles %1 alignHologramToTerain", GetProjectionEntity().GetType());
146 if (GetGame().ConfigIsExisting(configPathAlign))
147 {
148 m_AlignToTerrain = GetGame().ConfigGetInt(configPathAlign);
149 }
150
151 string configPathOrientationLimit = string.Format("CfgVehicles %1 yawPitchRollLimit", GetProjectionEntity().GetType());
152 if (GetGame().ConfigIsExisting(configPathOrientationLimit))
153 {
154 m_YawPitchRollLimit = GetGame().ConfigGetVector(configPathOrientationLimit);
155 }
156 }
157
159 {
160 if (GetGame())
161 {
162 if (m_Projection)
163 {
165 }
166
168 {
170 }
171 }
172
173 #ifdef DIAG_DEVELOPER
175 #endif
176 }
177
179 {
180 if ( m_Projection.HasAnimation( ANIMATION_PLACING ) )
181 {
182 m_Projection.SetAnimationPhase( ANIMATION_PLACING, 0 );
184
185 if ( m_Projection.HasAnimation( ANIMATION_INVENTORY ) )
186 {
187 m_Projection.SetAnimationPhase( ANIMATION_INVENTORY, 1 );
188 }
189 }
190 else
191 {
194 }
195 }
196
197 // Updates selections on hologram object so they reflect the state of the parent object's selections.
199 {
200 string cfg_access = "CfgVehicles " + m_Projection.GetType() + " AnimationSources ";
201
202 if ( GetGame().ConfigIsExisting(cfg_access) )
203 {
204 int cfg_access_count = g_Game.ConfigGetChildrenCount(cfg_access);
205
206 for ( int i = 0; i < cfg_access_count; ++i )
207 {
208 string found_anim;
209 GetGame().ConfigGetChildName(cfg_access, i, found_anim);
210
211 float anim_phase = m_Parent.GetAnimationPhase(found_anim);
212 m_Projection.SetAnimationPhase(found_anim, anim_phase);
213 }
214 }
215 }
216
218 {
220 }
221
223 {
225 if (m_ProjectionTypename != "")
226 {
228 }
229
230 if (!item)
231 {
232 return "";
233 }
234
235 if (item.CanMakeGardenplot())
236 {
237 return "GardenPlotPlacing";
238 }
239
240 //Camping & Base building
241 if (item.IsInherited( TentBase ) || item.IsBasebuildingKit())
242 {
243 return item.GetType() + "Placing";
244 }
245
246 return item.GetType();
247 }
248
250 static bool DoesHaveProjection(ItemBase item)
251 {
252 return item && (item.IsDeployable() || item.CanMakeGardenplot() || item.IsInherited(DeployableContainer_Base));
253 }
254
255 // update loop for visuals and collisions of the hologram
256 void UpdateHologram(float timeslice)
257 {
258 if (!m_Parent)
259 {
260 m_Player.TogglePlacingLocal();
261
262 return;
263 }
264
266 {
267 m_Player.TogglePlacingLocal();
268
269 return;
270 }
271
272 if (!GetUpdatePosition())
273 return;
274
275
276 #ifdef DIAG_DEVELOPER
277 DebugConfigValues();
279 #endif
280
281 // update hologram position
284
289
290 m_Projection.OnHologramBeingPlaced(m_Player);
291 }
292
294 {
295 vector y_p_r;
296
297 if ( m_AlignToTerrain )
298 {
299 vector projection_orientation_angles = GetDefaultOrientation() + GetProjectionRotation();
300 vector mat0[3];
301 vector mat1[3];
302 vector mat2[3];
303 vector projection_position = m_Projection.GetPosition();
304 vector normal;
305
306 if ( m_ContactDir.Length() > 0 )
307 {
308 normal = m_ContactDir;
309 }
310 else
311 {
312 normal = GetGame().SurfaceGetNormal( projection_position[0], projection_position[2] );
313 }
314
315 vector angles = normal.VectorToAngles();
316 angles[1] = angles[1] + 270;
317
318 angles[0] = Math.Clamp( angles[0], 0, 360 );
319 angles[1] = Math.Clamp( angles[1], 0, 360 );
320 angles[2] = Math.Clamp( angles[2], 0, 360 );
321
322 projection_orientation_angles[0] = projection_orientation_angles[0] + ( 360 - angles[0] );
323
324 Math3D.YawPitchRollMatrix( projection_orientation_angles, mat0 );
325 Math3D.YawPitchRollMatrix( angles, mat1 );
326 Math3D.MatrixMultiply3( mat1, mat0, mat2 );
327
328 y_p_r = Math3D.MatrixToAngles( mat2 );
329 }
330 else
331 {
333
334 if ( y_p_r[0] > 180 )
335 {
336 y_p_r[0] = y_p_r[0] - 360;
337 }
338
339 if ( y_p_r[0] < -180 )
340 {
341 y_p_r[0] = y_p_r[0] + 360;
342 }
343 }
344
345 return SmoothProjectionMovement( y_p_r, timeslice );
346 }
347
348 vector SmoothProjectionMovement( vector y_p_r, float timeslice )
349 {
350 if ( m_y_p_r_previous )
351 {
352 if ( Math.AbsFloat( y_p_r[0] - m_y_p_r_previous[0] ) > 100 )
353 {
354 if ( y_p_r[0] > 0 )
355 {
356 m_y_p_r_previous[0] = m_y_p_r_previous[0] + 360;
357 }
358
359 if ( y_p_r[0] < 0 )
360 {
362 }
363 }
364
365 y_p_r[0] = Math.Lerp( m_y_p_r_previous[0], y_p_r[0], 15 * timeslice );
366 y_p_r[1] = Math.Lerp( m_y_p_r_previous[1], y_p_r[1], 15 * timeslice );
367 y_p_r[2] = Math.Lerp( m_y_p_r_previous[2], y_p_r[2], 15 * timeslice );
368 }
369
370 m_y_p_r_previous = y_p_r;
371
372 return y_p_r;
373 }
374
376 {
377 Class.CastTo(m_ProjectionTrigger, g_Game.CreateObjectEx("ProjectionTrigger", GetProjectionPosition(), SPAWN_FLAGS));
378
380 m_ProjectionTrigger.SetParentObject(this);
381 m_ProjectionTrigger.SetParentOwner(m_Player);
382
384 }
385
387 {
388 vector min_max[2];
389 GetProjectionCollisionBox( min_max );
390
393 m_ProjectionTrigger.SetExtents(min_max[0], min_max[1]);
394 }
395
396 #ifdef DIAG_DEVELOPER
397 void DebugText(string header, bool mustBeTrue = false, bool condition = true, string info = "")
398 {
399 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
400 {
401 int color = 0xFFFFFFFF;
402
403 if (mustBeTrue && !condition || !mustBeTrue && condition)
404 color = COLOR_RED;
405
406 string text = header + condition + info;
407 DbgUI.ColoredText(color, text);
408 }
409 }
410
411 protected float m_PitchOverride;
412 protected float m_RollOverride;
413 void DebugConfigValues()
414 {
415 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
416 {
417 m_PitchOverride = m_YawPitchRollLimit[1];
418 m_RollOverride = m_YawPitchRollLimit[2];
419
420 DbgUI.InputFloat("slopeTolerance override", m_SlopeTolerance);
421 DbgUI.SameLine();
422 DbgUI.InputFloat("pitch limit override", m_PitchOverride);
423 DbgUI.SameLine();
424 DbgUI.InputFloat("roll limit override", m_RollOverride);
425
426 m_YawPitchRollLimit[1] = m_PitchOverride;
427 m_YawPitchRollLimit[2] = m_RollOverride;
428 }
429 }
430 #endif
431
432 void EvaluateCollision(ItemBase action_item = null)
433 {
434 #ifdef DIAG_DEVELOPER
435 m_CollisionDetails = "";
436 #endif
437
438 if (!m_Player.CanPlaceItem(m_Projection))
439 {
440 #ifdef DIAG_DEVELOPER
441 m_CollisionDetails += "[Player]";
442 #endif
443 SetIsColliding(true);
444
445 }
447 {
448 SetIsColliding(true);
449 }
450 else if ( m_Projection.IsInherited( TrapSpawnBase ))
451 {
452 #ifdef DIAG_DEVELOPER
453 DebugText("Inherits from TrapSpawnBase, checking IsPlaceableAtposition", true);
454 #endif
455
456 TrapSpawnBase trapSpawnBase;
457 Class.CastTo(trapSpawnBase, m_Projection);
458 SetIsColliding(!trapSpawnBase.IsPlaceableAtPosition(m_Projection.GetPosition()));
459 }
460 else if (m_Projection.IsInherited(TrapBase))
461 {
462 #ifdef DIAG_DEVELOPER
463 DebugText("Inherits from TrapBase, checking IsPlaceableAtposition", true);
464 #endif
465 TrapBase trapBase;
466 Class.CastTo(trapBase, m_Projection);
467 SetIsColliding(!trapBase.IsPlaceableAtPosition(m_Projection.GetPosition()));
468 }
469 else
470 {
471 SetIsColliding(false);
472 }
473 }
474
476 {
478 return false;
479 if (GetGame().IsServer() && GetGame().IsMultiplayer())
480 return false;
481
482 //Some locations allow you to look up and attempt placing the hologram on the bottom side of a floor - most notably the floors of a watchtower
483 //This check also prevents some very unnatural placements
484
485 bool b1 = m_Projection.GetPosition()[1] > GetGame().GetCurrentCameraPosition()[1];
486 bool b2 = false;
487 #ifdef DIAG_DEVELOPER
488 vector from, to;
489 #endif
490 if (m_Projection.DoPlacingHeightCheck())
491 {
492 b2 = MiscGameplayFunctions.IsUnderRoofEx(m_Projection, GameConstants.ROOF_CHECK_RAYCAST_DIST, ObjIntersectFire);
493 #ifdef DIAG_DEVELOPER
494 MiscGameplayFunctions.IsUnderRoofFromToCalculation(m_Projection, from, to);
495 DrawArrow(from, to, !b2);
496 #endif
497 }
498
499 #ifdef DIAG_DEVELOPER
500 DebugText("IsClippingRoof: ", false, b1, " | (projection height) " + m_Projection.GetPosition()[1] + " > (camera height) " + GetGame().GetCurrentCameraPosition()[1]);
501 DebugText("IsClippingRoof: ", false, b2, " | (DoPlacingHeightCheck) " + m_Projection.DoPlacingHeightCheck() + " && (IsUnderRoof) " + MiscGameplayFunctions.IsUnderRoof(m_Projection) + " | from: " + from[1] + " | to: " + to[1]);
502 #endif
503
504 return b1 || b2;
505 }
506
508 {
510 return false;
511 vector projection_orientation = m_Projection.GetOrientation();
512 bool isTrue = Math.AbsFloat( projection_orientation[1] ) > m_YawPitchRollLimit[1] || Math.AbsFloat( projection_orientation[2] ) > m_YawPitchRollLimit[2];
513 #ifdef DIAG_DEVELOPER
514 DebugText("IsCollidingAngle: ", false, isTrue, " | (proj pitch) " + Math.AbsFloat( projection_orientation[1] ) + " > (pitch limit) " + m_YawPitchRollLimit[1] + " | (proj roll) " + Math.AbsFloat( projection_orientation[2] ) + " > (roll limit) " + m_YawPitchRollLimit[2]);
515 #endif
516
517 return isTrue;
518 }
519
520 #ifdef DIAG_DEVELOPER
521 protected Shape m_CollisionBox;
522 protected void DrawDebugCollisionBox( vector min_max[2], int color )
523 {
524 vector mat[4];
525 m_Projection.GetTransform( mat );
526 m_CollisionBox = Debug.DrawBox( min_max[0], min_max[1], color );
527 m_CollisionBox.SetMatrix( mat );
528 }
529
530 protected void DestroyDebugCollisionBox()
531 {
532 if ( m_CollisionBox )
533 {
534 m_CollisionBox.Destroy();
535 m_CollisionBox = NULL;
536 }
537 }
538 #endif
539
540 bool IsCollidingBBox(ItemBase action_item = null)
541 {
543 return false;
544
545 vector center;
546 vector relativeOffset; //we need to lift BBox, because it is calculated from the bottom of projection, and not from the middle
547 vector absoluteOffset = "0 0.05 0"; //we need to lift BBox even more, because it colliddes with house floors due to various reasons (probably geometry or float imperfections)
548 vector orientation = GetProjectionOrientation();
549 vector edgeLength;
550 vector minMax[2];
551 array<Object> excludedObjects = new array<Object>();
552 array<Object> collidedObjects = new array<Object>();
553
555 relativeOffset[1] = (minMax[1][1] - minMax[0][1]) * 0.5;
556 center = m_Projection.GetPosition() + relativeOffset + absoluteOffset;
557 edgeLength = GetCollisionBoxSize(minMax);
558 excludedObjects.Insert(m_Projection);
559 excludedObjects.Insert(m_Player);
560
561 if (action_item)
562 excludedObjects.Insert(action_item);
563
564 //add is construction check
565 // Base building objects behave in a way that causes this test to generate false positives
566 bool isTrue = GetGame().IsBoxCollidingGeometry(center, orientation, edgeLength, ObjIntersectFire, ObjIntersectGeom, excludedObjects, collidedObjects);
567 #ifdef DIAG_DEVELOPER
568 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
569 {
570 string text = "";
571 foreach (Object object: collidedObjects)
572 text += " | " + Object.GetDebugName(object);
573
574 DebugText("IsCollidingBBox: ", false, isTrue, text);
575
576 int color = 0x01FFFFFF;
577 if (isTrue)
578 color = 0x33F22613;
579
580 DrawDebugCollisionBox(minMax, color);
581 }
582 #endif
583
584 return isTrue;
585 }
586
588 {
589 //This function is not required to solve server-side fixes for clipping, saves calculations and potential false negatives
590 if (GetGame().IsServer() && GetGame().IsMultiplayer())
591 return true;
592
594 return true;
595
596
597
599 vector to_left_close_down = from_left_close + PLACEMENT_RC_END_OFFSET;
600
602 vector to_right_close_down = from_right_close + PLACEMENT_RC_END_OFFSET;
603
605 vector to_left_far_down = from_left_far + PLACEMENT_RC_END_OFFSET;
606
608 vector to_right_far_down = from_right_far + PLACEMENT_RC_END_OFFSET;
609
610 vector contact_pos_left_close;
611 vector contact_pos_right_close;
612 vector contact_pos_left_far;
613 vector contact_pos_right_far;
614 vector contact_dir_left_close;
615 vector contact_dir_right_close;
616 vector contact_dir_left_far;
617 vector contact_dir_right_far;
618 int contact_component_left_close;
619 int contact_component_right_close;
620 int contact_component_left_far;
621 int contact_component_right_far;
622 set<Object> results_left_close = new set<Object>;
623 set<Object> results_right_close = new set<Object>;
624 set<Object> results_left_far = new set<Object>;
625 set<Object> results_right_far = new set<Object>;
626 Object obj_left_close;
627 Object obj_right_close;
628 Object obj_left_far;
629 Object obj_right_far;
630
631 //Not sure what the intention here was before, but it boiled down to a very bloated version of what you see here right now
632 DayZPhysics.RaycastRV(from_left_close, to_left_close_down, contact_pos_left_close, contact_dir_left_close, contact_component_left_close, results_left_close, null, m_Projection, false, false, ObjIntersectFire);
633 if (results_left_close.Count() > 0)
634 obj_left_close = results_left_close[results_left_close.Count() - 1];
635
636 DayZPhysics.RaycastRV(from_right_close, to_right_close_down, contact_pos_right_close, contact_dir_right_close, contact_component_right_close, results_right_close, null, m_Projection, false, false, ObjIntersectFire);
637 if (results_right_close.Count() > 0)
638 obj_right_close = results_right_close[results_right_close.Count() - 1];
639
640 DayZPhysics.RaycastRV(from_left_far, to_left_far_down, contact_pos_left_far, contact_dir_left_far, contact_component_left_far, results_left_far, null, m_Projection, false, false, ObjIntersectFire);
641 if (results_left_far.Count() > 0)
642 obj_left_far = results_left_far[results_left_far.Count() - 1];
643
644 DayZPhysics.RaycastRV(from_right_far, to_right_far_down, contact_pos_right_far, contact_dir_right_far, contact_component_right_far, results_right_far, null, m_Projection, false, false, ObjIntersectFire);
645 if (results_right_far.Count() > 0)
646 obj_right_far = results_right_far[results_right_far.Count() - 1];
647
648 return IsBaseIntact(obj_left_close, obj_right_close, obj_left_far, obj_right_far ) && IsBaseStatic( obj_left_close ) && IsBaseFlat( contact_pos_left_close, contact_pos_right_close, contact_pos_left_far, contact_pos_right_far);
649 }
650
652 {
654 return false;
655
656 #ifdef DIAG_DEVELOPER
657 DebugText("IsCollidingGPlot: ", false, m_IsCollidingGPlot);
658 #endif
659
660 return m_IsCollidingGPlot;
661 }
662
664 {
665 vector origin = Vector(0, 0, 0);
666 bool isTrue = GetProjectionPosition() == origin;
667 #ifdef DIAG_DEVELOPER
668 DebugText("IsCollidingZeroPos: ", false, isTrue);
669 #endif
670
671 return isTrue;
672 }
673
676 {
677 ErrorEx("Deprecated check - do not use", ErrorExSeverity.WARNING);
678 return false;
679 }
680
681 //This function only takes one of the found objects since IsBaseIntact already verifies that all of them are either null or the same object
682 bool IsBaseStatic( Object objectToCheck )
683 {
684 //check if the object below hologram is dynamic object. Dynamic objects like barrels can be taken to hands
685 //and item which had been placed on top of them, would stay floating in the air
686 #ifdef DIAG_DEVELOPER
687 if (objectToCheck == null)
688 DebugText("IsBaseStatic(must be true): ", true, true, " | objectToCheck is null (this is good)");
689 else
690 DebugText("IsBaseStatic(must be true): ", true, IsObjectStatic(objectToCheck));
691 #endif
692 return objectToCheck == null || IsObjectStatic(objectToCheck);
693 }
694
696 {
697 return obj.IsBuilding() || obj.IsPlainObject() || (!m_Parent.IsInherited(KitBase) && obj.IsInherited(BaseBuildingBase) && (m_WatchtowerBlockedComponentNames.Find(obj.GetActionComponentName(m_ContactComponent, LOD.NAME_VIEW)) == -1));
698 }
699
700 bool IsBaseIntact( Object under_left_close, Object under_right_close, Object under_left_far, Object under_right_far )
701 {
702 bool isTrue = (under_left_close == under_right_close && under_right_close == under_left_far && under_left_far == under_right_far);
703 #ifdef DIAG_DEVELOPER
704 DebugText("IsBaseIntact(must be true and all equal): ", true, isTrue, " | ulc: " + Object.GetDebugName(under_left_close) + " | urc: " + Object.GetDebugName(under_right_close) + " | ulf: " + Object.GetDebugName(under_left_far) + " | urf: " + Object.GetDebugName(under_right_far));
705 if (!isTrue)
706 {
707 array<bool> conditions = new array<bool>();
708 conditions.Insert(under_left_close == null);
709 conditions.Insert(under_right_close == null);
710 conditions.Insert(under_left_far == null);
711 conditions.Insert(under_right_far == null);
712
713 int amountOfNull = 0;
714 if (!under_left_close)
715 ++amountOfNull;
716 if (!under_right_close)
717 ++amountOfNull;
718 if (!under_left_far)
719 ++amountOfNull;
720 if (!under_right_far)
721 ++amountOfNull;
722
723 if ( amountOfNull < 3 )
724 for ( int i = 0; i < conditions.Count(); ++i)
725 conditions[i] = !conditions[i];
726
727 DrawBaseSpheres(conditions);
728 }
729 #endif
730
731 return isTrue;
732 }
733
734 #ifdef DIAG_DEVELOPER
735 void DrawArrow(vector from, vector to, bool condition)
736 {
737 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
738 {
739 int color = 0xFFFFFFFF;
740 if (!condition)
741 color = COLOR_RED;
742
743 Debug.DrawArrow(from, to, 1, color, ShapeFlags.ONCE);
744 }
745 }
746
747 void DrawSphere(vector pos, bool condition)
748 {
749 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
750 {
751 int color = 0x01FFFFFF;
752 if (!condition)
753 color = 0x99F22613;
754
755 Debug.DrawSphere(pos, 1, color, ShapeFlags.ONCE|ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE);
756 }
757 }
758
759 void DrawBaseSpheres(array<bool> conditions)
760 {
761 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
762 {
763 array<vector> positions = new array<vector>();
764 positions.Insert(m_Projection.CoordToParent( GetLeftCloseProjectionVector() ));
765 positions.Insert(m_Projection.CoordToParent( GetRightCloseProjectionVector() ));
766 positions.Insert(m_Projection.CoordToParent( GetLeftFarProjectionVector() ));
767 positions.Insert(m_Projection.CoordToParent( GetRightFarProjectionVector() ));
768
769 for (int i = 0; i < positions.Count(); ++i)
770 DrawSphere(positions[i], conditions[i]);
771 }
772 }
773
774 void DrawDebugArrow(float start, float dist, int color = 0xFF1FFFFF)
775 {
776 if ( DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM) )
777 {
778 vector from = m_Player.GetPosition() + start * MiscGameplayFunctions.GetHeadingVector(m_Player);
779 vector to = m_Player.GetPosition() + dist * MiscGameplayFunctions.GetHeadingVector(m_Player);
780
781 Debug.DrawArrow(from, to, 0.5, 0xFF1FFFFF, ShapeFlags.ONCE|ShapeFlags.TRANSP);
782 }
783 }
784 #endif
785
786 bool IsBaseFlat( vector contact_pos_left_close, vector contact_pos_right_close, vector contact_pos_left_far, vector contact_pos_right_far )
787 {
788 vector projection_pos = GetProjectionPosition();
789 float slope_pos_left_close = Math.AbsFloat(projection_pos[1] - contact_pos_left_close[1]);
790 float slope_pos_right_close = Math.AbsFloat(projection_pos[1] - contact_pos_right_close[1]);
791 float slope_pos_left_far = Math.AbsFloat(projection_pos[1] - contact_pos_left_far[1]);
792 float slope_pos_right_far = Math.AbsFloat(projection_pos[1] - contact_pos_right_far[1]);
793
794 bool isTrue = slope_pos_left_close < m_SlopeTolerance && slope_pos_right_close < m_SlopeTolerance && slope_pos_left_far < m_SlopeTolerance && slope_pos_right_far < m_SlopeTolerance;
795 #ifdef DIAG_DEVELOPER
796 DebugText("IsBaseFlat(must be true): ", true, isTrue, " (slope < slopeTolerance) | slopeTolerance: " + m_SlopeTolerance + " | lc: " + slope_pos_left_close + " | rc: " + slope_pos_right_close + " | lf: " + slope_pos_left_far + " | rf: " + slope_pos_right_far);
797 DrawArrow(projection_pos, contact_pos_left_close, slope_pos_left_close < m_SlopeTolerance);
798 DrawArrow(projection_pos, contact_pos_right_close, slope_pos_right_close < m_SlopeTolerance);
799 DrawArrow(projection_pos, contact_pos_left_far, slope_pos_left_far < m_SlopeTolerance);
800 DrawArrow(projection_pos, contact_pos_right_far, slope_pos_right_far < m_SlopeTolerance);
801 #endif
802
803 return isTrue;
804 }
805
808 {
810 return true;
811
812 bool isTrue = m_Parent && m_Parent.CanBePlaced(m_Player, GetProjectionPosition());
813
814 #ifdef DIAG_DEVELOPER
815 DebugText("IsPlacementPermitted(must be true): ", true, isTrue, " (Note: ItemBase::CanBePlaced() return value)");
816 #endif
817 return isTrue;
818 }
819
822 {
824 return true;
825 if ( GetProjectionEntity() ) //simple height check
826 {
827 vector playerpos = m_Player.GetPosition();
828 vector projectionpos = GetProjectionPosition();
829 float delta1 = playerpos[1] - projectionpos[1];
830
832 {
833 #ifdef DIAG_DEVELOPER
834 DebugText("HeightPlacementCheck(must be true): ", true, false, " | Height difference between item and player is larger than " + DEFAULT_MAX_PLACEMENT_HEIGHT_DIFF);
835 #endif
836 return false;
837 }
838 }
839 #ifdef DIAG_DEVELOPER
840 DebugText("HeightPlacementCheck(must be true): ", true, true);
841 #endif
842 return true;
843 }
844
846 {
848 return false;
849 // Fast check middle of object
850 string type;
851 int liquid;
852 g_Game.SurfaceUnderObjectCorrectedLiquid(m_Projection, type, liquid);
853
854 if (liquid & (LIQUID_GROUP_WATER - LIQUID_SNOW))
855 {
856 #ifdef DIAG_DEVELOPER
857 DebugText("IsUnderwater: ", false, true, " | Surface under object is water");
858 #endif
859 return true;
860 }
861
862 // Check every corner of the object
863 vector left_close = m_Projection.CoordToParent( GetLeftCloseProjectionVector() );
864 vector right_close = m_Projection.CoordToParent( GetRightCloseProjectionVector() );
865 vector left_far = m_Projection.CoordToParent( GetLeftFarProjectionVector() );
866 vector right_far = m_Projection.CoordToParent( GetRightFarProjectionVector() );
867 float maxSea = g_Game.SurfaceGetSeaLevelMax() + 0.03;
868 bool belowMaxSea = left_close[1] < maxSea || right_close[1] < maxSea || left_far[1] < maxSea || right_far[1] < maxSea;
869
870 #ifdef DIAG_DEVELOPER
871 // I'd rather duplicate this on internal than introduce (even) more raycasts than needed on retail..
872 float lc = g_Game.GetWaterDepth(left_close);
873 float rc = g_Game.GetWaterDepth(right_close);
874 float lf = g_Game.GetWaterDepth(left_far);
875 float rf = g_Game.GetWaterDepth(right_far);
876 bool isTrue = (lc > 0 || rc > 0 || lf > 0 || rf > 0 || belowMaxSea);
877 DebugText("IsUnderwater: ", false, isTrue, " belowMaxSea: " + belowMaxSea + " | (all must be less than zero) | lc: " + lc + " | rc: " + rc + " | lf: " + lf + " | rf: " + rf);
878 //DebugText("Corner Height: ", false, true, " lc: " + left_close[1] + " | rc: " + right_close[1] + " | lf: " + left_far[1] + " | rf: " + right_far[1]);
879 if (isTrue)
880 {
881 array<bool> conditions = {lc <= 0, rc <= 0, lf <= 0, rf <= 0};
882 DrawBaseSpheres(conditions);
883 }
884 #endif
885
886 return (belowMaxSea || g_Game.GetWaterDepth(left_close) > 0 || g_Game.GetWaterDepth(right_close) > 0 || g_Game.GetWaterDepth(left_far) > 0 || g_Game.GetWaterDepth(right_far) > 0);
887 }
888
890 {
892 return false;
893 vector fromHeightOffset = "0 0.3 0";
894 vector toHeightOffset = "0 1 0";
895
896 vector from_left_close = m_Projection.CoordToParent( GetLeftCloseProjectionVector() ) + fromHeightOffset;
897 vector to_left_close_down = from_left_close + toHeightOffset;
898
899 vector from_right_close = m_Projection.CoordToParent( GetRightCloseProjectionVector() ) + fromHeightOffset;
900 vector to_right_close_down = from_right_close + toHeightOffset;
901
902 vector from_left_far = m_Projection.CoordToParent( GetLeftFarProjectionVector() ) + fromHeightOffset;
903 vector to_left_far_down = from_left_far + toHeightOffset;
904
905 vector from_right_far = m_Projection.CoordToParent( GetRightFarProjectionVector() ) + fromHeightOffset;
906 vector to_right_far_down = from_right_far + toHeightOffset;
907
908 vector contact_pos_left_close;
909 vector contact_pos_right_close;
910 vector contact_pos_left_far;
911 vector contact_pos_right_far;
912
913 vector contact_dir_left_close;
914 vector contact_dir_right_close;
915 vector contact_dir_left_far;
916 vector contact_dir_right_far;
917
918 int contact_component_left_close;
919 int contact_component_right_close;
920 int contact_component_left_far;
921 int contact_component_right_far;
922
923 #ifdef DIAG_DEVELOPER
924 // I'd rather duplicate this on internal than introduce (even) more raycasts than needed on retail..
925 set<Object> lcO = new set<Object>();
926 set<Object> rcO = new set<Object>();
927 set<Object> lfO = new set<Object>();
928 set<Object> rfO = new set<Object>();
929 bool lc = DayZPhysics.RaycastRV( from_left_close, to_left_close_down, contact_pos_left_close, contact_dir_left_close, contact_component_left_close, lcO, m_Projection, m_Projection, false, true, ObjIntersectFire );
930 bool rc = DayZPhysics.RaycastRV( from_right_close, to_right_close_down, contact_pos_right_close, contact_dir_right_close, contact_component_right_close, rcO, m_Projection, m_Projection, false, true, ObjIntersectFire );
931 bool lf = DayZPhysics.RaycastRV( from_left_far, to_left_far_down, contact_pos_left_far, contact_dir_left_far, contact_component_left_far, lfO, m_Projection, m_Projection, false, true, ObjIntersectFire );
932 bool rf = DayZPhysics.RaycastRV( from_right_far, to_right_far_down, contact_pos_right_far, contact_dir_right_far, contact_component_right_far, rfO, m_Projection, m_Projection, false, true, ObjIntersectFire );
933 bool isTrue = ( lc || rc || lf || rf );
934 string text = "";
935 if (isTrue)
936 {
937 if (lc)
938 text += " | lc";
939 if (rc)
940 text += " | rc";
941 if (lf)
942 text += " | lf";
943 if (rf)
944 text += " | rf";
945
946 if (lcO.Count() > 0)
947 text += " | lcO: " + lcO[0];
948 if (rcO.Count() > 0)
949 text += " | rcO: " + rcO[0];
950 if (lfO.Count() > 0)
951 text += " | lfO: " + lfO[0];
952 if (rfO.Count() > 0)
953 text += " | rfO: " + rfO[0];
954
955 array<bool> conditions = {!lc, !rc, !lf, !rf};
956 DrawBaseSpheres(conditions);
957 }
958 DebugText("IsInTerrain: ", false, isTrue, text);
959 #endif
960
961 if (DayZPhysics.RaycastRV( from_left_close, to_left_close_down, contact_pos_left_close, contact_dir_left_close, contact_component_left_close, NULL, m_Projection, m_Projection, false, true, ObjIntersectFire ))
962 return true;
963
964 if (DayZPhysics.RaycastRV( from_right_close, to_right_close_down, contact_pos_right_close, contact_dir_right_close, contact_component_right_close, NULL,m_Projection, m_Projection, false, true, ObjIntersectFire ))
965 return true;
966
967 if (DayZPhysics.RaycastRV( from_left_far, to_left_far_down, contact_pos_left_far, contact_dir_left_far, contact_component_left_far, NULL, m_Projection, m_Projection, false, true, ObjIntersectFire ))
968 return true;
969
970 if (DayZPhysics.RaycastRV( from_right_far, to_right_far_down, contact_pos_right_far, contact_dir_right_far, contact_component_right_far, NULL, m_Projection, m_Projection, false, true, ObjIntersectFire ))
971 return true;
972
973 return false;
974 }
975
977 {
978 //in range of its power source.
979 if (m_Player && m_Parent && m_Parent.HasEnergyManager() && m_Parent.GetCompEM().IsPlugged())
980 {
981 // Unplug the device when the player is too far from the power source.
982 m_Parent.GetCompEM().UpdatePlugState();
983
984 // Delete local hologram when plug is rippled out and advanced placement is active
985 if (GetGame().IsMultiplayer() && GetGame().IsClient())
986 {
987 if (!m_Parent.GetCompEM().IsPlugged())
988 m_Player.TogglePlacingLocal();
989 }
990 }
991 }
992
993 EntityAI PlaceEntity( EntityAI entity_for_placing )
994 {
995 //string-based comparison
996 if (entity_for_placing.IsInherited(TentBase) || entity_for_placing.IsBasebuildingKit() )
997 {
998 return entity_for_placing;
999 }
1000
1001 if (m_Projection.IsInherited(GardenPlotPlacing))
1002 {
1003 Class.CastTo(entity_for_placing, GetGame().CreateObjectEx( "GardenPlot", m_Projection.GetPosition(), ECE_OBJECT_SWAP ));
1004 return entity_for_placing;
1005 }
1006
1007 //inheritance comparison
1008 if( !GetProjectionEntity().IsKindOf( m_Parent.GetType() ))
1009 {
1010 Class.CastTo(entity_for_placing, GetGame().CreateObjectEx( m_Projection.GetType(), m_Projection.GetPosition(), ECE_OBJECT_SWAP ));
1011 }
1012
1013 return entity_for_placing;
1014 }
1015
1016 protected void GetProjectionCollisionBox( out vector min_max[2] )
1017 {
1018 if (!m_Projection.GetCollisionBox( min_max ) && m_Projection.MemoryPointExists("box_placing_min"))
1019 {
1020 min_max[0] = m_Projection.GetMemoryPointPos( "box_placing_min" );
1021 min_max[1] = m_Projection.GetMemoryPointPos( "box_placing_max" );
1022 //Debug.DrawSphere(m_Projection.ModelToWorld(min_max[0]) , 0.8,Colors.RED, ShapeFlags.ONCE);
1023 //Debug.DrawSphere(m_Projection.ModelToWorld(min_max[1]), 0.8,Colors.RED, ShapeFlags.ONCE);
1024 }
1025 }
1026
1027 protected vector GetCollisionBoxSize( vector min_max[2] )
1028 {
1029 vector box_size = Vector(1,1,1);
1030
1031 box_size[0] = min_max[1][0] - min_max[0][0];
1032 box_size[2] = min_max[1][2] - min_max[0][2];
1033 box_size[1] = min_max[1][1] - min_max[0][1];
1034
1035 return box_size;
1036 }
1037
1039 {
1040 vector min_max[2];
1041 GetProjectionCollisionBox( min_max );
1042
1043 return min_max[0];
1044 }
1045
1047 {
1048 vector min_max[2];
1049 GetProjectionCollisionBox( min_max );
1050 min_max[1][1] = min_max[0][1];
1051 min_max[1][2] = min_max[0][2];
1052
1053 return min_max[1];
1054 }
1055
1057 {
1058 vector min_max[2];
1059 GetProjectionCollisionBox( min_max );
1060 min_max[0][2] = min_max[1][2];
1061
1062 return min_max[0];
1063 }
1064
1066 {
1067 vector min_max[2];
1068 GetProjectionCollisionBox( min_max );
1069 min_max[1][1] = min_max[0][1];
1070
1071 return min_max[1];
1072 }
1073
1074 // Replaced by IsUnderwater, currently unused
1075 bool IsSurfaceWater( vector position )
1076 {
1077 CGame game = GetGame();
1078 return game.SurfaceIsSea( position[0], position[2] ) || game.SurfaceIsPond( position[0], position[2] );
1079 }
1080
1081 bool IsSurfaceSea( vector position )
1082 {
1083 CGame game = GetGame();
1084 return game.SurfaceIsSea( position[0], position[2] );
1085 }
1086
1088 {
1089 float minProjectionDistance;
1090 float maxProjectionDistance;
1092 vector minMax[2];
1093 float projectionRadius = GetProjectionRadius();
1094 float cameraToPlayerDistance = vector.Distance(GetGame().GetCurrentCameraPosition(), player.GetPosition());
1095
1096 if (projectionRadius < SMALL_PROJECTION_RADIUS) // objects with radius smaller than 1m
1097 {
1098 minProjectionDistance = SMALL_PROJECTION_RADIUS;
1099 maxProjectionDistance = SMALL_PROJECTION_RADIUS * 2;
1100 }
1101 else
1102 {
1103 minProjectionDistance = projectionRadius;
1104 maxProjectionDistance = projectionRadius * 2;
1105 maxProjectionDistance = Math.Clamp(maxProjectionDistance, SMALL_PROJECTION_RADIUS, LARGE_PROJECTION_DISTANCE_LIMIT);
1106 }
1107
1109 vector to = from + (GetGame().GetCurrentCameraDirection() * (maxProjectionDistance + cameraToPlayerDistance));
1110 vector contactPosition;
1111 set<Object> hitObjects = new set<Object>();
1112
1113 DayZPhysics.RaycastRV(from, to, contactPosition, m_ContactDir, m_ContactComponent, hitObjects, player, m_Projection, false, false, ObjIntersectFire);
1114
1115 bool contactHitProcessed = false;
1118 {
1119 if (hitObjects.Count() > 0)
1120 {
1121 if (hitObjects[0].IsInherited(Watchtower))
1122 {
1123 contactHitProcessed = true;
1124 contactPosition = CorrectForWatchtower(m_ContactComponent, contactPosition, player, hitObjects[0]);
1125 }
1126
1127 if (!contactHitProcessed && hitObjects[0].IsInherited(InventoryItem))
1128 contactPosition = hitObjects[0].GetPosition();
1129 }
1130 }
1131
1132 static const float raycastOriginOffsetOnFail = 0.25;
1133 static const float minDistFromStart = 0.01;
1134 // Camera isn't correctly positioned in some cases, leading to raycasts hitting the object directly behind the camera
1135 if ((hitObjects.Count() > 0) && (vector.DistanceSq(from, contactPosition) < minDistFromStart))
1136 {
1137 from = contactPosition + GetGame().GetCurrentCameraDirection() * raycastOriginOffsetOnFail;
1138 DayZPhysics.RaycastRV(from, to, contactPosition, m_ContactDir, m_ContactComponent, hitObjects, player, m_Projection, false, false, ObjIntersectFire);
1139 }
1140
1141 bool isFloating = SetHologramPosition(player.GetPosition(), minProjectionDistance, maxProjectionDistance, contactPosition);
1142 SetIsFloating(isFloating);
1143
1144 #ifdef DIAG_DEVELOPER
1145 DrawDebugArrow(minProjectionDistance, maxProjectionDistance);
1146 if (DiagMenu.GetBool(DiagMenuIDs.MISC_HOLOGRAM))
1147 {
1148 Debug.DrawSphere(GetProjectionPosition(), 0.1, 0x99FF0000, ShapeFlags.ONCE|ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE);
1149 }
1150 #endif
1151
1152 m_FromAdjusted = from;
1153
1154 return contactPosition;
1155 }
1156
1165 protected bool SetHologramPosition(vector startPosition, float minProjectionDistance, float maxProjectionDistance, inout vector contactPosition)
1166 {
1167 float playerToProjectionDistance = vector.Distance(startPosition, contactPosition);
1168 vector playerToProjection;
1169
1170 #ifdef DIAG_DEVELOPER
1171 DebugText("SetHologramPosition::startPosition: ", false, m_IsHidden, string.Format(" | %1", startPosition));
1172 DebugText("SetHologramPosition::contactPosition [in]: ", false, m_IsHidden, string.Format(" | %1", contactPosition));
1173 DebugText("SetHologramPosition::minProjectionDistance: ", false, m_IsHidden, string.Format(" | %1", minProjectionDistance));
1174 DebugText("SetHologramPosition::maxProjectionDistance: ", false, m_IsHidden, string.Format(" | %1", maxProjectionDistance));
1175 DebugText("SetHologramPosition::playerToProjectionDistance: ", false, m_IsHidden, string.Format(" | %1", playerToProjectionDistance));
1176 #endif
1177
1178 //hologram is at min distance from player
1179 if (playerToProjectionDistance <= minProjectionDistance)
1180 {
1181 playerToProjection = contactPosition - startPosition;
1182 playerToProjection.Normalize();
1183 //prevents the hologram to go underground/floor while hologram exceeds minProjectionDistance
1184 playerToProjection[1] = playerToProjection[1] + PROJECTION_TRANSITION_MIN;
1185
1186 contactPosition = startPosition + (playerToProjection * minProjectionDistance);
1187
1188 #ifdef DIAG_DEVELOPER
1189 DebugText("SetHologramPosition::contactPosition[out] (< minProjectDistance): ", false, m_IsHidden, string.Format(" | %1", contactPosition));
1190 #endif
1191
1192 return true;
1193 }
1194 //hologram is at max distance from player
1195 else if (playerToProjectionDistance >= maxProjectionDistance)
1196 {
1197 playerToProjection = contactPosition - startPosition;
1198 playerToProjection.Normalize();
1199 //prevents the hologram to go underground/floor while hologram exceeds maxProjectionDistance
1200 playerToProjection[1] = playerToProjection[1] + PROJECTION_TRANSITION_MAX;
1201
1202 contactPosition = startPosition + (playerToProjection * maxProjectionDistance);
1203
1204 #ifdef DIAG_DEVELOPER
1205 DebugText("SetHologramPosition::contactPosition[out] (< maxProjectionDistance): ", false, m_IsHidden, string.Format(" | %1", contactPosition));
1206 #endif
1207
1208 return true;
1209 }
1210
1211 return false;
1212 }
1213
1215 {
1216 return m_Parent.IsBasebuildingKit() || m_Parent.IsInherited(TentBase);
1217 }
1218
1219 vector CorrectForWatchtower(int contactComponent, vector contactPos, PlayerBase player, Object hitObject)
1220 {
1221 // Raycast has hit one of the trigger boxes that show construction prompts, so projection would be floating in the air without this correction
1222 if (m_WatchtowerIgnoreComponentNames.Find(hitObject.GetActionComponentName(contactComponent, LOD.NAME_VIEW)) != -1 )
1223 contactPos[1] = hitObject.GetActionComponentPosition(contactComponent, LOD.NAME_VIEW)[1];
1224
1225 return contactPos;
1226 }
1227
1228 //This function is currently unused
1230 {
1231 return m_Projection.IsInherited( TrapBase ) || m_Projection.IsInherited( TrapSpawnBase );
1232 }
1233
1235 {
1236 float diameter;
1237 float radius;
1238 vector diagonal;
1239 vector min_max[2];
1240
1241 GetProjectionCollisionBox( min_max );
1242 diagonal = GetCollisionBoxSize( min_max );
1243 diameter = diagonal.Length();
1244
1245 return diameter;
1246 }
1247
1249 {
1250 float diameter;
1251 float radius;
1252 vector diagonal;
1253 vector min_max[2];
1254
1255 GetProjectionCollisionBox( min_max );
1256 diagonal = GetCollisionBoxSize( min_max );
1257 diameter = diagonal.Length();
1258 radius = diameter / 2;
1259
1260 return radius;
1261 }
1262
1263 void SetUpdatePosition( bool state )
1264 {
1265 m_UpdatePosition = state;
1266 }
1267
1269 {
1270 return m_UpdatePosition;
1271 }
1272
1274 {
1275 return m_Parent;
1276 }
1277
1279 {
1280 m_Projection = projection;
1281 }
1282
1284 {
1285 return m_Projection;
1286 }
1287
1288 void SetIsFloating( bool is_floating )
1289 {
1290 m_IsFloating = is_floating;
1291 }
1292
1293 void SetIsColliding( bool is_colliding )
1294 {
1295 #ifdef DIAG_DEVELOPER
1296 DebugText("Is colliding: ", false, is_colliding, m_CollisionDetails);
1297 #endif
1298 m_IsColliding = is_colliding;
1299 }
1300
1301 void SetIsHidden( bool is_hidden )
1302 {
1303 m_IsHidden = is_hidden;
1304 }
1305
1306 void SetIsCollidingPlayer( bool is_colliding )
1307 {
1308 m_IsCollidingPlayer = is_colliding;
1309 }
1310
1311 void SetIsCollidingGPlot( bool is_colliding_gplot )
1312 {
1313 m_IsCollidingGPlot = is_colliding_gplot;
1314 }
1315
1317 {
1318 #ifdef DIAG_DEVELOPER
1319 DebugText("IsFloating: ", false, m_IsFloating);
1320 #endif
1321 return m_IsFloating;
1322 }
1323
1325 {
1326 return m_IsColliding;
1327 }
1328
1330 {
1331 #ifdef DIAG_DEVELOPER
1332 DebugText("IsHidden: ", false, m_IsHidden);
1333 #endif
1334 return m_IsHidden;
1335 }
1336
1338 {
1340 return false;
1341 #ifdef DIAG_DEVELOPER
1342 DebugText("IsCollidingPlayer: ", false, m_IsCollidingPlayer);
1343 #endif
1344 return m_IsCollidingPlayer;
1345 }
1346
1348 {
1349 m_Projection.SetPosition( position );
1350
1351 if (IsFloating())
1352 {
1353 m_Projection.SetPosition(SetOnGround(position));
1354 }
1355 }
1356
1358 {
1359 m_Projection.SetOrientation(orientation);
1360 }
1361
1363 {
1364 return m_Rotation;
1365 }
1366
1367 void AddProjectionRotation( float addition )
1368 {
1369 m_Rotation[0] = m_Rotation[0] + addition;
1370 }
1371
1372 void SubtractProjectionRotation( float subtraction )
1373 {
1374 m_Rotation[0] = m_Rotation[0] - subtraction;
1375 }
1376
1378 {
1379 vector from = position;
1380 vector ground;
1381 vector player_to_projection_vector;
1382 float projection_diameter = GetProjectionDiameter();
1383
1384 ground = Vector(0, -Math.Max(projection_diameter, SMALL_PROJECTION_GROUND), 0);
1385
1386 vector to = from + ground;
1387 vector contact_pos = to;
1388
1389 RaycastRVParams rayInput = new RaycastRVParams(from, to, m_Projection);
1390 rayInput.flags = CollisionFlags.ALLOBJECTS;
1392
1393 if (DayZPhysics.RaycastRVProxy(rayInput, results))
1394 {
1395 RaycastRVResult res;
1396 for (int i = 0; i < results.Count(); i++)
1397 {
1398 res = results.Get(i);
1399 if (res.entry || (!res.obj && !res.parent))
1400 {
1401 contact_pos = res.pos;
1402 break;
1403 }
1404 }
1405 }
1406
1407 //LOS check
1408 if (contact_pos != "0 0 0")
1409 {
1410 vector check_pos;
1411 vector check_dir;
1412 int check_component = -1;
1413 set<Object> hit_object = new set<Object>;
1414 to = contact_pos;
1415 to[1] = to[1] + 0.1;
1416 from = m_FromAdjusted;
1417
1418 if (DayZPhysics.RaycastRV(from, to, check_pos, check_dir, check_component, hit_object, null, m_Player, false, false, ObjIntersectFire))
1419 {
1420 if ((hit_object.Count() > 0)&& (!hit_object[0].IsInherited(Watchtower) || (hit_object[0].IsInherited(Watchtower) && (m_WatchtowerIgnoreComponentNames.Find(hit_object[0].GetActionComponentName(check_component, LOD.NAME_VIEW)) == -1))))
1421 {
1422 contact_pos = "0 0 0";
1423 }
1424 }
1425 }
1426
1427 HideWhenClose(contact_pos);
1428
1429 return contact_pos;
1430 }
1431
1433 {
1434 //if the hologram is too close to player when he looks to the sky, send the projection to away
1436
1437 if( cam_dir[1] > LOOKING_TO_SKY )
1438 {
1439 pos = "0 0 0";
1440 }
1441
1442 return pos;
1443 }
1444
1446 {
1447 if (m_Projection)
1448 return m_Projection.GetPosition();
1449
1450 return vector.Zero;
1451 }
1452
1454 {
1455 if (m_Projection)
1456 return m_Projection.GetOrientation();
1457
1458 return vector.Zero;
1459 }
1460
1462 {
1464 m_DefaultOrientation[1] = 0;
1465
1466 if (!GetParentEntity().PlacementCanBeRotated())
1467 {
1469 }
1470
1471 return m_DefaultOrientation;
1472 }
1473
1474 int GetHiddenSelection( string selection )
1475 {
1476 int idx = m_Projection.GetHiddenSelectionIndex(selection);
1477
1478 if ( idx != -1 )
1479 return idx;
1480 else
1481 return 0;
1482 }
1483
1484 // the function accepts string
1485 void SetSelectionToRefresh( string selection )
1486 {
1487 m_SelectionsToRefresh.Insert( selection );
1488 }
1489
1490 //overloaded function to accept array of strings
1492 {
1493 foreach (string s : selection)
1494 m_SelectionsToRefresh.Insert(s);
1495 }
1496
1498 {
1499 if (m_Projection)
1500 {
1501 static const string textureName = "#(argb,8,8,3)color(0.5,0.5,0.5,0.75,ca)";
1502
1503 int hidden_selection = 0;
1504 string selection_to_refresh;
1505 string config_material = string.Format("CfgVehicles %1 hologramMaterial", m_Projection.GetType());
1506 string hologram_material = GetGame().ConfigGetTextOut(config_material);
1507 string config_model = string.Format("CfgVehicles %1 hologramMaterialPath", m_Projection.GetType());
1508 string hologram_material_path = string.Format("%1\\%2%3", GetGame().ConfigGetTextOut(config_model), hologram_material, CorrectMaterialPathName());
1509
1510 for (int i = 0; i < m_SelectionsToRefresh.Count(); ++i)
1511 {
1512 selection_to_refresh = m_SelectionsToRefresh.Get(i);
1513 hidden_selection = GetHiddenSelection(selection_to_refresh);
1514 m_Projection.SetObjectTexture(hidden_selection, textureName);
1515 m_Projection.SetObjectMaterial(hidden_selection, hologram_material_path);
1516 }
1517 }
1518 }
1519
1520 // Returns correct string to append to material path name
1522 {
1523 if (IsColliding() || IsFloating())
1524 {
1526 }
1527 else if (m_Parent.HasEnergyManager())
1528 {
1529 ComponentEnergyManager comp_em = m_Parent.GetCompEM();
1530 string SEL_CORD_PLUGGED = m_Parent.GetCompEM().SEL_CORD_PLUGGED;
1531 string SEL_CORD_FOLDED = m_Parent.GetCompEM().SEL_CORD_FOLDED;
1532
1533 if (comp_em.IsPlugged() && comp_em.IsEnergySourceAtReach(GetProjectionPosition()))
1534 {
1535 m_Projection.SetAnimationPhase(SEL_CORD_PLUGGED, 0);
1536 m_Projection.SetAnimationPhase(SEL_CORD_FOLDED, 1);
1538 }
1539 else
1540 {
1541 m_Projection.SetAnimationPhase(SEL_CORD_PLUGGED, 1);
1542 m_Projection.SetAnimationPhase(SEL_CORD_FOLDED, 0);
1543 }
1544 }
1545
1547 }
1548
1550 {
1551 if (m_Player.IsJumpInProgress())
1552 return true;
1553 if (m_Player.IsSwimming())
1554 return true;
1555 if (m_Player.IsClimbingLadder())
1556 return true;
1557 if (m_Player.IsRaised())
1558 return true;
1559 if (m_Player.IsClimbing())
1560 return true;
1561 if (m_Player.IsRestrained())
1562 return true;
1563 if (m_Player.IsUnconscious())
1564 return true;
1565
1566 return false;
1567 }
1568};
1569
1570class ProjectionTrigger extends Trigger
1571{
1572 protected int m_TriggerUpdateMs;
1575
1576 override void OnEnter( Object obj )
1577 {
1578 //Print("OnEnter");
1579 if ( m_ParentObj )
1580 {
1581 m_ParentObj.SetIsCollidingPlayer( true );
1582 m_TriggerUpdateMs = 50;
1583 }
1584 }
1585
1586 override void OnLeave( Object obj )
1587 {
1588 //Print("OnLeave");
1589 if ( m_ParentObj )
1590 {
1591 m_ParentObj.SetIsCollidingPlayer( false );
1592 }
1593 }
1594
1595 override protected void UpdateInsiders(int timeout)
1596 {
1597 super.UpdateInsiders(m_TriggerUpdateMs);
1598 }
1599
1600 void SetParentObject( Hologram projection )
1601 {
1602 m_ParentObj = projection;
1603 }
1604
1606 {
1607 m_Player = player;
1608 }
1609}
eBleedingSourceType GetType()
Определения BleedingSource.c:63
const int ECE_OBJECT_SWAP
Определения CentralEconomy.c:38
const int ECE_LOCAL
Определения CentralEconomy.c:24
const int ECE_PLACE_ON_SURFACE
Определения CentralEconomy.c:37
const int ECE_TRACE
Определения CentralEconomy.c:10
const int ECE_CREATEPHYSICS
Определения CentralEconomy.c:16
void DrawDebugCollisionBox(vector min_max[2], int color)
Определения Construction.c:1170
Shape m_CollisionBox
Определения Construction.c:19
void DestroyDebugCollisionBox()
Определения Construction.c:1181
void DeployableContainer_Base()
Определения Container_Base.c:36
DayZGame g_Game
Определения DayZGame.c:3868
DiagMenuIDs
Определения EDiagMenuIDs.c:2
void Debug()
Определения UniversalTemperatureSource.c:349
Определения Fence.c:2
proto bool ConfigGetChildName(string path, int index, out string name)
Get name of subclass in config class on path.
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)
proto native vector ConfigGetVector(string path)
Get vector value from config on path.
proto native float ConfigGetFloat(string path)
Get float value from config on path.
proto native bool SurfaceIsSea(float x, float z)
string ConfigGetTextOut(string path)
Get string value from config on path.
Определения Game.c:463
proto native vector SurfaceGetNormal(float x, float z)
proto native int ConfigGetInt(string path)
Get int value from config on path.
proto native bool SurfaceIsPond(float x, float z)
proto native vector GetCurrentCameraPosition()
proto native vector GetCurrentCameraDirection()
proto native void ObjectDelete(Object obj)
Определения DayZGame.c:890
static bool GetDisableIsInTerrainCheck()
Определения CfgGameplayHandler.c:287
static bool GetDisableIsClippingRoofCheck()
Определения CfgGameplayHandler.c:277
static bool GetDisableIsUnderwaterCheck()
Определения CfgGameplayHandler.c:292
static bool GetDisableIsCollidingBBoxCheck()
Определения CfgGameplayHandler.c:267
static bool GetDisableHeightPlacementCheck()
Определения CfgGameplayHandler.c:297
static bool GetDisableIsPlacementPermittedCheck()
Определения CfgGameplayHandler.c:302
static bool GetDisableIsCollidingPlayerCheck()
Определения CfgGameplayHandler.c:272
static bool GetDisableIsCollidingGPlotCheck()
Определения CfgGameplayHandler.c:312
static bool GetDisableIsCollidingAngleCheck()
Определения CfgGameplayHandler.c:307
static bool GetDisableIsBaseViableCheck()
Определения CfgGameplayHandler.c:282
Super root of all classes in Enforce script.
Определения EnScript.c:11
bool IsEnergySourceAtReach(vector from_position, float add_tolerance=0, vector override_source_position="-1 -1 -1")
Energy manager: Returns true if this device's virtual power cord can reach its energy source at the g...
Определения ComponentEnergyManager.c:1031
bool IsPlugged()
Energy manager: Returns true if this device is plugged into some other device (even if they are OFF o...
Определения ComponentEnergyManager.c:887
static proto bool RaycastRV(vector begPos, vector endPos, out vector contactPos, out vector contactDir, out int contactComponent, set< Object > results=NULL, Object with=NULL, Object ignore=NULL, bool sorted=false, bool ground_only=false, int iType=ObjIntersectView, float radius=0.0, CollisionFlags flags=CollisionFlags.NEARESTCONTACT)
Raycasts world by given parameters.
static proto bool RaycastRVProxy(notnull RaycastRVParams in, out notnull array< ref RaycastRVResult > results, array< Object > excluded=null)
Определения DayZPhysics.c:124
Определения DbgUI.c:60
static Shape DrawBox(vector pos1, vector pos2, int color=0x1fff7f7f)
Определения Debug.c:286
static Shape DrawSphere(vector pos, float size=1, int color=0x1fff7f7f, ShapeFlags flags=ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE)
Определения Debug.c:319
static Shape DrawArrow(vector from, vector to, float size=0.5, int color=0xFFFFFFFF, int flags=0)
Определения Debug.c:404
Определения Debug.c:2
Определения EnDebug.c:233
Определения Building.c:6
Определения constants.c:659
bool m_IsFloating
Определения Hologram.c:31
vector m_DefaultOrientation
Определения Hologram.c:35
const string ANIMATION_PLACING
Определения Hologram.c:40
vector GetCollisionBoxSize(vector min_max[2])
Определения Hologram.c:1027
string CorrectMaterialPathName()
Определения Hologram.c:1521
void SetProjectionEntity(EntityAI projection)
Определения Hologram.c:1278
bool IsBaseIntact(Object under_left_close, Object under_right_close, Object under_left_far, Object under_right_far)
Определения Hologram.c:700
void SetAnimations()
Определения Hologram.c:178
string GetProjectionName(ItemBase item)
Определения Hologram.c:222
const string SELECTION_PLACING
Определения Hologram.c:42
bool m_IsHidden
Определения Hologram.c:33
const float LARGE_PROJECTION_DISTANCE_LIMIT
Deprecated.
Определения Hologram.c:48
void SetSelectionToRefresh(array< string > selection)
Определения Hologram.c:1491
bool IsCollidingZeroPos()
Определения Hologram.c:663
vector m_ContactDir
Определения Hologram.c:38
void SetSelectionToRefresh(string selection)
Определения Hologram.c:1485
void SetIsCollidingGPlot(bool is_colliding_gplot)
Определения Hologram.c:1311
const string SUFFIX_MATERIAL_DEPLOYABLE
Определения Hologram.c:14
bool IsInTerrain()
Определения Hologram.c:889
vector GetLeftFarProjectionVector()
Определения Hologram.c:1056
EntityAI m_Projection
Определения Hologram.c:22
const float PROJECTION_TRANSITION_MAX
Определения Hologram.c:50
bool GetUpdatePosition()
Определения Hologram.c:1268
void EvaluateCollision(ItemBase action_item=null)
Определения Hologram.c:432
vector m_YawPitchRollLimit
Определения Hologram.c:56
void SetUpdatePosition(bool state)
Определения Hologram.c:1263
bool HeightPlacementCheck()
Checks height relative to player's position.
Определения Hologram.c:821
EntityAI GetParentEntity()
Определения Hologram.c:1273
const float SMALL_PROJECTION_RADIUS
Определения Hologram.c:45
void CheckPowerSource()
Определения Hologram.c:976
vector m_y_p_r_previous
Определения Hologram.c:37
void Hologram(PlayerBase player, vector pos, ItemBase item)
Определения Hologram.c:68
void SetProjectionOrientation(vector orientation)
Определения Hologram.c:1357
void AddProjectionRotation(float addition)
Определения Hologram.c:1367
ItemBase m_Parent
Определения Hologram.c:21
vector HideWhenClose(vector pos)
Определения Hologram.c:1432
void CreateTrigger()
Определения Hologram.c:375
float m_SlopeTolerance
Определения Hologram.c:54
int m_ContactComponent
Определения Hologram.c:57
vector SetOnGround(vector position)
Определения Hologram.c:1377
bool IsObjectStatic(Object obj)
Определения Hologram.c:695
void ~Hologram()
Определения Hologram.c:158
const vector PLACEMENT_RC_START_OFFSET
Определения Hologram.c:18
void RefreshVisual()
Определения Hologram.c:1497
bool IsUnderwater()
Определения Hologram.c:845
bool IsCollidingAngle()
Определения Hologram.c:507
void UpdateHologram(float timeslice)
Определения Hologram.c:256
ref array< string > m_WatchtowerBlockedComponentNames
Определения Hologram.c:66
vector GetRightFarProjectionVector()
Определения Hologram.c:1065
void SetIsHidden(bool is_hidden)
Определения Hologram.c:1301
string m_ProjectionTypename
Определения Hologram.c:25
vector m_Rotation
Определения Hologram.c:36
const vector PLACEMENT_RC_END_OFFSET
Определения Hologram.c:19
ref set< string > m_SelectionsToRefresh
Определения Hologram.c:59
bool IsCollidingGPlot()
Определения Hologram.c:651
PlayerBase m_Player
Определения Hologram.c:23
const float DISTANCE_SMALL_PROJECTION
Определения Hologram.c:47
void RefreshTrigger()
Определения Hologram.c:386
bool IsPlacementPermitted()
Checks if the item can be legally placed (usually checked by action as well)
Определения Hologram.c:807
bool IsCollidingBBox(ItemBase action_item=null)
Определения Hologram.c:540
bool IsColliding()
Определения Hologram.c:1324
static bool DoesHaveProjection(ItemBase item)
DEPRECATED.
Определения Hologram.c:250
vector SmoothProjectionMovement(vector y_p_r, float timeslice)
Определения Hologram.c:348
bool m_UpdatePosition
Определения Hologram.c:32
bool IsSurfaceWater(vector position)
Определения Hologram.c:1075
vector m_FromAdjusted
Определения Hologram.c:39
bool IsBaseViable()
Определения Hologram.c:587
bool m_AlignToTerrain
Определения Hologram.c:55
bool SetHologramPosition(vector startPosition, float minProjectionDistance, float maxProjectionDistance, inout vector contactPosition)
Sets hologram position based on player and projection distance.
Определения Hologram.c:1165
vector GetLeftCloseProjectionVector()
Определения Hologram.c:1038
void SetIsColliding(bool is_colliding)
Определения Hologram.c:1293
vector GetProjectionOrientation()
Определения Hologram.c:1453
bool IsSurfaceSea(vector position)
Определения Hologram.c:1081
void SubtractProjectionRotation(float subtraction)
Определения Hologram.c:1372
vector GetRightCloseProjectionVector()
Определения Hologram.c:1046
int GetHiddenSelection(string selection)
Определения Hologram.c:1474
bool IsCollidingPlayer()
Определения Hologram.c:1337
const string SUFFIX_MATERIAL_UNDEPLOYABLE
Определения Hologram.c:15
bool m_IsColliding
Определения Hologram.c:27
vector AlignProjectionOnTerrain(float timeslice)
Определения Hologram.c:293
vector GetProjectionEntityPosition(PlayerBase player)
Определения Hologram.c:1087
ProjectionTrigger m_ProjectionTrigger
Определения Hologram.c:24
bool IsFenceOrWatchtowerKit()
Определения Hologram.c:1214
EntityAI GetProjectionEntity()
Определения Hologram.c:1283
bool IsProjectionTrap()
Определения Hologram.c:1229
static const float DEFAULT_MAX_PLACEMENT_HEIGHT_DIFF
Определения Hologram.c:52
bool IsBaseFlat(vector contact_pos_left_close, vector contact_pos_right_close, vector contact_pos_left_far, vector contact_pos_right_far)
Определения Hologram.c:786
void SetIsCollidingPlayer(bool is_colliding)
Определения Hologram.c:1306
void SetIsFloating(bool is_floating)
Определения Hologram.c:1288
const float SMALL_PROJECTION_GROUND
Определения Hologram.c:46
vector CorrectForWatchtower(int contactComponent, vector contactPos, PlayerBase player, Object hitObject)
Определения Hologram.c:1219
float GetProjectionRadius()
Определения Hologram.c:1248
vector GetProjectionRotation()
Определения Hologram.c:1362
bool m_IsCollidingGPlot
Определения Hologram.c:28
bool IsClippingRoof()
Определения Hologram.c:475
bool IsBehindObstacle()
DEPRECATED.
Определения Hologram.c:675
const int SPAWN_FLAGS
Определения Hologram.c:6
void GetProjectionCollisionBox(out vector min_max[2])
Определения Hologram.c:1016
float GetProjectionDiameter()
Определения Hologram.c:1234
const float LOOKING_TO_SKY
Определения Hologram.c:51
string ProjectionBasedOnParent()
Определения Hologram.c:217
ref array< string > m_WatchtowerIgnoreComponentNames
Определения Hologram.c:63
void UpdateSelections()
Определения Hologram.c:198
bool m_IsCollidingPlayer
Определения Hologram.c:30
vector GetProjectionPosition()
Определения Hologram.c:1445
bool m_IsSlope
Определения Hologram.c:29
bool IsHidden()
Определения Hologram.c:1329
void SetProjectionPosition(vector position)
Определения Hologram.c:1347
vector GetDefaultOrientation()
Определения Hologram.c:1461
const float PROJECTION_TRANSITION_MIN
Определения Hologram.c:49
const string SELECTION_INVENTORY
Определения Hologram.c:43
const string ANIMATION_INVENTORY
Определения Hologram.c:41
EntityAI PlaceEntity(EntityAI entity_for_placing)
Определения Hologram.c:993
bool IsFloating()
Определения Hologram.c:1316
bool IsBaseStatic(Object objectToCheck)
Определения Hologram.c:682
const string SUFFIX_MATERIAL_POWERED
Определения Hologram.c:16
bool IsRestrictedFromAdvancedPlacing()
Определения Hologram.c:1549
Определения Hologram.c:2
Определения ItemBase.c:15
override bool IsBasebuildingKit()
Определения KitBase.c:5
override bool CanMakeGardenplot()
Определения FieldShovel.c:3
override bool IsDeployable()
Определения BaseBuildingBase.c:341
Определения InventoryItem.c:731
Определения FenceKit.c:2
static const string NAME_VIEW
Определения gameplay.c:207
LOD class.
Определения gameplay.c:204
Определения EnMath3D.c:28
Определения EnMath.c:7
Определения ObjectTyped.c:2
Определения PlayerBaseClient.c:2
CollisionFlags flags
Определения DayZPhysics.c:63
Определения DayZPhysics.c:50
Object obj
object,that we collide with (NULL if none), If hierLevel > 0 object is the proxy object
Определения DayZPhysics.c:100
bool entry
is false if begining point was TriggerInsider
Определения DayZPhysics.c:111
vector pos
position of collision (in world coord)
Определения DayZPhysics.c:103
Object parent
if hierLevel > 0 most parent of the proxy object
Определения DayZPhysics.c:101
Определения DayZPhysics.c:99
Определения CarTent.c:2
Определения Trap_Bear.c:2
override bool IsPlaceableAtPosition(vector position)
Определения Trap_FishNet.c:37
Определения Trap_FishNet.c:2
override void OnLeave(Object obj)
Определения Hologram.c:1586
override void OnEnter(Object obj)
Определения Hologram.c:1576
void SetParentOwner(PlayerBase player)
Определения Hologram.c:1605
void Trigger()
ctor
Определения Trigger.c:53
void UpdateInsiders(int timeout)
Определения Hologram.c:1595
Hologram m_ParentObj
Определения Hologram.c:1573
PlayerBase m_Player
Определения Hologram.c:1574
void SetParentObject(Hologram projection)
Определения Hologram.c:1600
int m_TriggerUpdateMs
Определения Hologram.c:1572
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
static proto native float DistanceSq(vector v1, vector v2)
Returns the square distance between tips of two 3D vectors.
proto native float Length()
Returns length of vector (magnitude)
static const vector Zero
Определения EnConvert.c:110
proto float Normalize()
Normalizes vector. Returns length.
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
proto vector VectorToAngles()
Converts vector to spherical coordinates with radius = 1.
Определения EnConvert.c:106
proto native CGame GetGame()
const int COLOR_RED
Определения constants.c:64
ErrorExSeverity
Определения EnDebug.c:62
enum ShapeType ErrorEx
CollisionFlags
Определения EnDebug.c:141
ShapeFlags
Определения EnDebug.c:126
static proto native void ColoredText(int color, string label)
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
const float ROOF_CHECK_RAYCAST_DIST
Определения constants.c:1009
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
const int LIQUID_GROUP_WATER
Определения constants.c:555
const int LIQUID_SNOW
Определения constants.c:547
static proto vector MatrixToAngles(vector mat[3])
Returns angles of rotation matrix.
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
static proto void YawPitchRollMatrix(vector ang, out vector mat[3])
Creates rotation matrix from angles.
static proto void MatrixMultiply3(vector mat0[3], vector mat1[3], out vector res[3])
Transforms rotation matrix.
static proto float Max(float x, float y)
Returns bigger of two given values.
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.
static proto float AbsFloat(float f)
Returns absolute value.
static proto string ToString(void var, bool type=false, bool name=false, bool quotes=true)
Return string representation of variable.
static proto string Format(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
Gets n-th character from string.