172 if (new_item_type !=
string.
Empty)
173 Error(
"MoveEquipAndDestroyRootLambda expects new_item_type to be empty");
178 super.RemoveNetworkObjectInfo();
183 super.UndoRemoveNetworkObjectInfo();
190 super.CopyOldPropertiesToNew(old_item, new_item);
197 super.CreateNetworkObjectInfo(new_item);
213class MiscGameplayFunctions
216 static float Truncate(
float value,
int decimals = 2)
218 int multiplier =
Math.Pow(10,decimals);
219 return Math.Clamp(
Math.Floor(value * multiplier),
float.LOWEST,
float.MAX) / multiplier;
222 static string TruncateToS(
float value,
int decimals = 2)
224 return Truncate(value, decimals).ToString();
227 static vector TruncateVec(vector value,
int decimals = 2)
229 int multiplier = Math.Pow(10,decimals);
230 float v1 = Math.Clamp(Math.Floor(value[0] * multiplier),
float.LOWEST,
float.MAX) / multiplier;
231 float v2 = Math.Clamp(Math.Floor(value[1] * multiplier),
float.LOWEST,
float.MAX) / multiplier;
232 float v3 = Math.Clamp(Math.Floor(value[2] * multiplier),
float.LOWEST,
float.MAX) / multiplier;
236 static string TruncateVecToS(vector value,
int decimals = 2,
string delimiter =
" ")
238 return MiscGameplayFunctions.TruncateToS(value[0],decimals) + delimiter + MiscGameplayFunctions.TruncateToS(value[1],decimals) +delimiter + MiscGameplayFunctions.TruncateToS(value[2],decimals);
243 return string.Format(
"#(argb,8,8,3)color(%1,CO)",
string.Format(
"%1,%2,%3,%4", r, g, b, a));
247 static string ValueToBar(
float value,
string bar =
"[----------]",
string mark =
"x")
249 int length = bar.Length() - 2;
250 float index = Math.Lerp(0,length, value);
251 index = Math.Round(index);
252 index = Math.Clamp(index,0,length);
254 return InsertAtPos(bar,mark,index);
258 static string InsertAtPos(
string base,
string insert,
int pos)
260 int length_first = pos+1;
261 int length_base = base.Length();
262 int length_second = length_base - length_first;
263 string first = base.Substring(0,length_first);
264 string second = base.Substring(pos+1,length_second);
265 return first + insert + second;
269 static void TransferItemProperties(
EntityAI source, notnull
EntityAI target,
bool transfer_agents =
true,
bool transfer_variables =
true,
bool transfer_health =
true,
bool exclude_quantity =
false)
273 if (transfer_agents && target_ib)
274 target_ib.TransferAgents(source.GetAgents());
276 if (transfer_variables)
277 MiscGameplayFunctions.TransferEntityVariables(source, target, exclude_quantity);
283 TransferEntityHealth(source,target,{
"Health"});
288 static void TransferEntityVariables(
EntityAI source,
EntityAI target,
bool exclude_quantity =
false)
290 if (exclude_quantity)
292 int maskOriginal = source.m_VariablesMask;
294 target.TransferVariablesFloat(source.GetVariablesFloat());
295 source.m_VariablesMask = maskOriginal;
299 target.TransferVariablesFloat(source.GetVariablesFloat());
302 if (source.IsMagazine() && target.IsMagazine())
304 Magazine source_mag = Magazine.Cast(source);
305 Magazine target_mag = Magazine.Cast(target);
307 target_mag.ServerSetAmmoCount(source_mag.GetAmmoCount());
310 if (source.IsWeapon() && target.IsWeapon())
312 Weapon_Base source_wpn = Weapon_Base.Cast(source);
313 Weapon_Base target_wpn = Weapon_Base.Cast(target);
315 target_wpn.CopyWeaponStateFrom(source_wpn);
318 if (source.HasEnergyManager() && target.HasEnergyManager())
320 ComponentEnergyManager ems = source.GetCompEM();
321 ComponentEnergyManager emt = target.GetCompEM();
329 Edible_Base source_edb = Edible_Base.Cast(source);
330 Edible_Base target_edb = Edible_Base.Cast(target);
331 if (Class.CastTo(source_edb,source) && Class.CastTo(target_edb,target))
339 static void TransferItemVariables(
ItemBase source,
ItemBase target,
bool exclude_quantity =
false)
341 TransferEntityVariables(source,target,exclude_quantity);
348 array<EntityAI> children =
new array<EntityAI>;
350 int count = children.Count();
351 for (
int i = 0; i < count; ++i)
356 InventoryLocation child_src =
new InventoryLocation;
357 child.GetInventory().GetCurrentInventoryLocation( child_src );
359 InventoryLocation child_dst =
new InventoryLocation;
360 child_dst.Copy( child_src );
361 child_dst.SetParent( targetItem );
365 if (GameInventory.LocationCanAddEntity(child_dst))
368 targetItem.GetInventory().TakeToDst(
InventoryMode.LOCAL, child_src, child_dst);
377 player.LocalDropEntity(child);
378 g_Game.RemoteObjectTreeCreate(child);
386 static void TransferEntityHealth(
EntityAI source,
EntityAI target, array<string> healthTypes = null,
bool transferZoneDamage =
true)
388 array<string> HPTypes =
new array<string>;
389 if (!healthTypes || healthTypes.Count() == 0)
390 HPTypes.Insert(
"Health");
392 HPTypes.Copy(healthTypes);
394 if (transferZoneDamage)
398 source.GetDamageZones(zonesSrc);
399 target.GetDamageZones(zonesTgt);
401 foreach (
string zone : zonesSrc)
403 if (zonesTgt.Find(zone) == -1)
406 foreach (
string health : HPTypes)
408 target.SetHealth01(zone,health,source.GetHealth01(zone,health));
413 foreach (
string gHealth : HPTypes)
415 target.SetHealth01(
"",gHealth,source.GetHealth01(
"",gHealth));
419 static void UnlimitedAmmoDebugCheck(Weapon_Base weapon)
426 magazine = weapon.GetMagazine(weapon.GetCurrentMuzzle());
430 if (magazine.GetAmmoCount() <= 5)
432 magazine.ServerSetAmmoMax();
438 magazine = weapon.GetMagazine(weapon.GetCurrentMuzzle());
442 if (magazine.GetAmmoCount() <= 5)
444 magazine.LocalSetAmmoMax();
454 static void TurnItemIntoItem (notnull
ItemBase old_item,
string new_item_type, notnull PlayerBase player)
456 TurnItemIntoItemEx(player,
new TurnItemIntoItemLambda(old_item, new_item_type, player));
459 static void TurnItemIntoItemEx (notnull PlayerBase player, ReplaceItemWithNewLambdaBase lambda)
461 player.ServerReplaceItemWithNew(lambda);
464 static void TurnItemInHandsIntoItem (notnull
ItemBase old_item,
string new_item_type, notnull PlayerBase player)
466 TurnItemInHandsIntoItemEx(player,
new TurnItemIntoItemLambda(old_item, new_item_type, player));
469 static void TurnItemInHandsIntoItemEx (notnull PlayerBase player, ReplaceItemWithNewLambdaBase lambda)
471 player.ServerReplaceItemInHandsWithNew(lambda);
475 static array<ItemBase> CreateItemBasePiles(
string item_name, vector ground_position,
float quantity,
float health,
bool floaty_spawn =
false)
477 array<ItemBase> item_piles;
478 float max_stack_size;
481 item_piles =
new array<ItemBase>;
482 max_stack_size =
g_Game.ConfigGetInt(
"cfgVehicles " + item_name +
" varStackMax");
483 if( max_stack_size < 1)
484 max_stack_size =
g_Game.ConfigGetInt(
"cfgVehicles " + item_name +
" varQuantityMax");
485 if( max_stack_size < 1)
488 int full_piles_count = Math.Floor(quantity/max_stack_size);
489 int rest = quantity - (full_piles_count*max_stack_size);
491 for (
int i = 0; i < full_piles_count; ++i)
497 pile.SetQuantity(max_stack_size);
498 pile.SetHealth(health);
499 item_piles.Insert(pile);
508 pile.SetQuantity(rest);
509 pile.SetHealth(health);
510 item_piles.Insert(pile);
516 static array<ItemBase> CreateItemBasePilesDispersed(
string item_name, vector starPos, vector targetPos,
float radius,
float quantity,
float health,
Object ignoreObjectCollison)
518 array<ItemBase> item_piles;
519 float max_stack_size;
522 item_piles =
new array<ItemBase>;
523 max_stack_size =
g_Game.ConfigGetInt(
"cfgVehicles " + item_name +
" varStackMax");
524 if( max_stack_size < 1)
525 max_stack_size =
g_Game.ConfigGetInt(
"cfgVehicles " + item_name +
" varQuantityMax");
526 if( max_stack_size < 1)
529 int full_piles_count = Math.Floor(quantity/max_stack_size);
530 int rest = quantity - (full_piles_count*max_stack_size);
531 vector randomizedPos;
533 for (
int i = 0; i < full_piles_count; ++i)
535 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
537 pile.SetQuantity(max_stack_size);
538 pile.SetHealth(health);
539 item_piles.Insert(pile);
544 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
546 pile.SetQuantity(rest);
547 pile.SetHealth(health);
548 item_piles.Insert(pile);
553 static array<Magazine> CreateMagazinePiles(
string item_name, vector ground_position,
float quantity,
float health )
555 array<Magazine> items;
559 items =
new array<Magazine>;
560 stack_size =
g_Game.ConfigGetInt(
"cfgMagazines " + item_name +
" count");
562 int piles_count = Math.Floor(quantity/stack_size);
563 int rest = quantity - (piles_count*stack_size);
565 for (
int i = 0; i < piles_count; ++i)
568 pile.ServerSetAmmoCount(stack_size);
574 pile.ServerSetAmmoCount(rest);
581 static array<Magazine> CreateMagazinePilesDispersed(
string item_name, vector starPos, vector targetPos,
float radius,
float quantity,
float health,
Object ignoreObjectCollison)
583 array<Magazine> items;
587 items =
new array<Magazine>;
588 stack_size =
g_Game.ConfigGetInt(
"cfgMagazines " + item_name +
" count");
590 int piles_count = Math.Floor(quantity/stack_size);
591 int rest = quantity - (piles_count*stack_size);
592 vector randomizedPos;
594 for (
int i = 0; i < piles_count; ++i)
596 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
598 pile.ServerSetAmmoCount(stack_size);
604 randomizedPos = MiscGameplayFunctions.GetRandomizedPositionVerified(starPos,targetPos,radius,ignoreObjectCollison);
606 pile.ServerSetAmmoCount(rest);
612 static array<Magazine> CreateMagazinePilesFromBullet(
string bullet_type, vector ground_position,
float quantity,
float health )
614 array<Magazine> items;
615 items =
new array<Magazine>;
619 if (!
g_Game.ConfigGetText(
"cfgAmmo " + bullet_type +
" spawnPileType", item_name))
622 stack_size =
g_Game.ConfigGetInt(
"cfgMagazines " + item_name +
" count");
626 int piles_count = Math.Floor(quantity/stack_size);
627 int rest = quantity - (piles_count*stack_size);
629 for (
int i = 0; i < piles_count; ++i)
632 pile.ServerSetAmmoCount(stack_size);
639 pile.ServerSetAmmoCount(rest);
647 static array<Magazine> CreateMagazinePilesFromBulletDispersed(
string bullet_type, vector starPos, vector targetPos,
float radius,
float quantity,
float health,
Object ignoreObjectCollison)
649 array<Magazine> items =
new array<Magazine>;
652 if (!
g_Game.ConfigGetText(
"cfgAmmo " + bullet_type +
" spawnPileType", item_name))
655 items = CreateMagazinePilesDispersed(item_name,starPos,targetPos,radius,quantity,health,ignoreObjectCollison);
659 static int GetHealthLevelForAmmo(
string class_name,
float health)
661 float health_normalized = health / 100;
663 CachedObjectsArrays.ARRAY_FLOAT.Clear();
664 g_Game.ConfigGetFloatArray(config_path, CachedObjectsArrays.ARRAY_FLOAT);
665 for(
int i = 0; i < CachedObjectsArrays.ARRAY_FLOAT.Count(); ++i)
667 if( health_normalized >= CachedObjectsArrays.ARRAY_FLOAT.Get(i) )
675 static float GetTypeMaxGlobalHealth(
string class_name,
string health_type =
"Health")
692 cfg_path = cfg_path +
" "+
class_name+
" DamageSystem GlobalHealth " + health_type +
" hitpoints";
693 max_health =
g_Game.ConfigGetFloat(cfg_path);
698 static bool GetProjectedCursorPos3d (out vector position, Weapon_Base weapon)
700 vector usti_hlavne_position = weapon.GetSelectionPositionMS(
"usti hlavne" );
701 vector konec_hlavne_position = weapon.GetSelectionPositionMS(
"konec hlavne" );
702 vector end_point = weapon.ModelToWorld(usti_hlavne_position);
703 vector begin_point = weapon.ModelToWorld(konec_hlavne_position);
705 int contact_component;
707 vector aim_point = end_point - begin_point;
709 aim_point = aim_point + end_point;
711 if (DayZPhysics.RaycastRV(begin_point, aim_point, position, contact_dir, contact_component, null, null, null,
false,
false, ObjIntersectFire))
716 static void GetHeadBonePos(notnull PlayerBase player, out vector pos)
719 int headBoneIdx = player.GetBoneIndexByName(
"Head");
720 if ( headBoneIdx == -1 )
721 { pos = player.GetPosition()[1] + 1.6; }
723 { pos = player.GetBonePositionWS(headBoneIdx); }
726 static vector GetHeadingVector(notnull PlayerBase player)
728 vector dir = vector.Zero;
729 float headingAngle = GetHeadingAngle(player);
730 dir[0] = Math.Cos(headingAngle + Math.PI_HALF);
731 dir[2] = Math.Sin(headingAngle + Math.PI_HALF);
733 return dir.Normalized();
736 static float GetHeadingAngle(notnull DayZPlayerImplement player)
738 HumanInputController hic = player.GetInputController();
739 float headingAngle = hic.GetHeadingAngle();
744 static float GetEnergyMetabolicSpeed(
int movement_speed)
747 switch (movement_speed)
750 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_WALK;
753 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_JOG;
756 speed = PlayerConstants.METABOLIC_SPEED_ENERGY_SPRINT;
763 speed += PlayerConstants.METABOLIC_SPEED_ENERGY_BASAL;
767 static float GetWaterMetabolicSpeed(
int movement_speed)
770 switch (movement_speed)
773 speed = PlayerConstants.METABOLIC_SPEED_WATER_WALK;
776 speed = PlayerConstants.METABOLIC_SPEED_WATER_JOG;
779 speed = PlayerConstants.METABOLIC_SPEED_WATER_SPRINT;
786 speed += PlayerConstants.METABOLIC_SPEED_WATER_BASAL;
790 static string ObtainRestrainItemTargetClassname(notnull
EntityAI entity)
792 return entity.ConfigGetString(
"OnRestrainChange");
795 static void TransformRestrainItem(
EntityAI current_item,
EntityAI tool, PlayerBase player_source, PlayerBase player_target,
bool destroy =
false)
802 type = tool.ConfigGetBool(
"RestrainUnlockType");
804 string new_item_name = current_item.ConfigGetString(
"OnRestrainChange");
806 if ( new_item_name !=
"" )
810 if (player_target.IsAlive())
811 MiscGameplayFunctions.TurnItemIntoItemEx(player_target,
new ReplaceAndDestroyLambdaEx(current_item, new_item_name, player_target, type));
813 MiscGameplayFunctions.TurnItemIntoItemEx(player_source,
new DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(current_item, new_item_name, player_target, type));
817 MiscGameplayFunctions.TurnItemIntoItemEx(player_target,
new ReplaceAndDestroyLambdaEx(current_item, new_item_name, player_target, type));
822 Error(
"current_item:" +current_item+
", tool:" +tool +
". No value for 'OnRestrainChange' config parameter");
826 static bool IsValueInRange(
float value,
float from,
float to)
828 return (value >= from) && (value <= to);
832 static bool IsPlayerOrientedTowardPos(notnull DayZPlayerImplement player, vector target_pos,
float cone_angle)
836 vector player_dir = player.GetDirection();
837 vector to_target_dir = target_pos - player.GetPosition();
840 to_target_dir[1] = 0;
842 player_dir.Normalize();
843 to_target_dir.Normalize();
845 float cos_fi = vector.Dot(player_dir, to_target_dir);
846 vector cross = player_dir * to_target_dir;
848 int dir = Math.Acos(cos_fi) * Math.RAD2DEG;
854 if( (dir <= cone_angle && dir >= -cone_angle) || Math.AbsFloat(dir) == 90 )
863 static string SanitizeString(
string input)
865 int max_length = 512;
866 string output = input;
868 output = output.Substring(0,Math.Clamp(max_length,0,output.Length()));
873 static bool ComplexBuildCollideCheckClient( PlayerBase player, ActionTarget target,
ItemBase item,
string partName =
"" )
878 static bool ComplexBuildCollideCheckClient( PlayerBase player, ActionTarget target,
ItemBase item,
int constraction_index )
883 Construction construction = base_building.GetConstruction();
884 if (construction && BuildCondition( player, target, item,
false, constraction_index ))
886 ConstructionActionData construction_action_data = player.GetConstructionActionData();
897 if (base_building.PerformRoofCheckForBase(partName,player,boo) && boo)
899 if ( player.IsPlacingLocal() || player.IsPlacingServer() )
908 return !construction.IsColliding( partName );
915 static bool BuildCondition( PlayerBase player, ActionTarget target,
ItemBase item,
bool camera_check )
920 static bool BuildCondition( PlayerBase player, ActionTarget target,
ItemBase item,
bool camera_check,
int constraction_index )
922 Object targetObject = target.GetObject();
923 if ( targetObject && targetObject.CanUseConstruction() )
926 ConstructionActionData construction_action_data = player.GetConstructionActionData();
927 construction_action_data.
SetTarget( targetObject );
929 ConstructionPart constrution_part;
948 if ( constrution_part )
951 bool position_check = ( base_building.MustBeBuiltFromOutside() && !base_building.
IsPlayerInside(player, constrution_part.GetMainPartName()) ) || ( !base_building.MustBeBuiltFromOutside() && base_building.
IsPlayerInside(player, constrution_part.GetMainPartName()) );
952 if ( position_check && !player.GetInputController().CameraIsFreeLook() )
959 return !base_building.
IsFacingCamera( constrution_part.GetMainPartName() );
971 static void IsUnderRoofFromToCalculation(
EntityAI entity, out vector from, out vector to,
float height = GameConstants.ROOF_CHECK_RAYCAST_DIST)
974 entity.GetCollisionBox(minMax);
976 vector size =
Vector(0,0,0);
978 float from_override = entity.HeightStartCheckOverride();
979 if (from_override > 0.0)
981 size[1] = from_override;
985 size[1] = minMax[1][1] - minMax[0][1];
988 from = entity.GetPosition() + size;
989 if ( entity.HeightCheckOverride() > 0 )
991 to = entity.GetPosition() +
Vector(0, entity.HeightCheckOverride(), 0);
995 vector ceiling =
"0 0 0";
1001 static bool IsUnderRoof(
EntityAI entity,
float height = GameConstants.ROOF_CHECK_RAYCAST_DIST)
1003 return IsUnderRoofEx(entity, height, ObjIntersectIFire);
1006 static bool IsUnderRoofEx(
EntityAI entity,
float height = GameConstants.ROOF_CHECK_RAYCAST_DIST,
int geometry = ObjIntersectView)
1011 IsUnderRoofFromToCalculation(entity, from, to, height);
1015 int contact_component;
1017 return DayZPhysics.RaycastRV(from, to, contact_pos, contact_dir, contact_component, NULL, NULL, entity,
false,
false, geometry,0.25);
1021 static vector GetSteamPosition(
EntityAI parent )
1023 vector particle_pos;
1024 float steam_offset = 0;
1028 particle_pos = parent.GetPosition();
1030 if ( parent.IsInherited( PortableGasStove ) )
1046 else if ( fireplace.IsFireplaceIndoor() )
1048 steam_offset = 0.45;
1057 particle_pos[1] = particle_pos[1] + steam_offset;
1059 return particle_pos;
1062 static vector GetRandomizedPosition(vector targetPos,
float radius)
1064 int angle = Math.RandomIntInclusive(1,360);
1065 float usedRadius = Math.RandomFloat01() * radius;
1066 vector randomPos =
Vector(targetPos[0] + (Math.Cos(angle) * usedRadius), targetPos[1], targetPos[2] + (Math.Sin(angle) * usedRadius));
1071 static vector GetRandomizedPositionVerified(vector startPos, vector targetPos,
float radius,
Object ignore = null)
1073 vector ret = GetRandomizedPosition(targetPos,radius);
1074 RaycastRVParams params =
new RaycastRVParams(startPos,ret,ignore);
1075 params.type = ObjIntersectIFire;
1076 array<ref RaycastRVResult> results =
new array<ref RaycastRVResult>;
1077 array<Object> excluded =
new array<Object>;
1078 if (DayZPhysics.RaycastRVProxy(params,results,excluded))
1080 ret = results[0].pos;
1081 ret[1] = targetPos[1];
1086 static vector GetRandomizedPositionVerifiedPlayer(Man player,
float distance,
float radius,
Object ignore)
1089 MiscGameplayFunctions.GetHeadBonePos(PlayerBase.Cast(player),startPos);
1090 vector targetPos = player.GetPosition() + (player.GetDirection() * distance);
1091 return GetRandomizedPositionVerified(startPos,targetPos,radius,ignore);
1094 static void DropAllItemsInInventoryInBounds(
ItemBase ib, vector halfExtents)
1098 array<EntityAI> items =
new array<EntityAI>;
1099 GameInventory ibInventory = ib.GetInventory();
1102 vector direction = ib.GetDirection();
1103 float dot = vector.Dot(direction, vector.Forward);
1105 float angle = Math.Acos(dot);
1106 if (direction[0] < 0)
1109 float cos = Math.Cos(angle);
1110 float sin = Math.Sin(angle);
1113 int count = items.Count();
1114 for (
int i = 0; i < count; ++i )
1116 item = items.Get(i);
1122 static void ThrowAllItemsInInventory(notnull
EntityAI parent,
int flags)
1124 vector position = parent.GetPosition();
1125 vector orientation = parent.GetOrientation();
1126 vector rotation_matrix[3];
1130 parent.GetCollisionBox(minmax);
1132 Math3D.YawPitchRollMatrix( orientation, rotation_matrix );
1133 Math3D.MatrixToQuat( rotation_matrix, direction );
1136 array<EntityAI> ents =
new array<EntityAI>;
1139 GameInventory parentInventory = parent.GetInventory();
1141 for (i = 0; i < count; ++i)
1147 CargoBase parentCargo = parentInventory.
GetCargo();
1148 count = parentCargo.GetItemCount();
1149 for (i = 0; i < count; ++i)
1151 ents.Insert(parentCargo.GetItem(i));
1157 randomPos =
Vector(position[0] + Math.RandomFloat(minmax[0][0], minmax[1][0]),
1158 position[1] + Math.RandomFloat(minmax[0][1], minmax[1][1]),
1159 position[2] + Math.RandomFloat(minmax[0][2], minmax[1][2]));
1164 static void ThrowEntityFromInventory(notnull
EntityAI entity, vector position,
float direction[4], vector force,
int flags)
1167 if ( !
g_Game.IsMultiplayer() )
1171 GameInventory entityInventory = entity.GetInventory();
1172 if (CastTo(entityIB, entity))
1174 InventoryLocation dst =
new InventoryLocation;
1175 dst.SetGroundEx(entity, position, direction);
1179 for (
int l = 0; l < entityIB.GetQuantity(); ++l)
1185 MiscGameplayFunctions.TransferItemProperties(entityIB, new_item);
1186 entityIB.AddQuantity( -1 );
1187 new_item.SetQuantity( 1 );
1188 new_item.ThrowPhysically(null, force,
false);
1194 float stackable = entityIB.GetTargetQuantityMax();
1195 if ( !(stackable == 0 || stackable >= entityIB.GetQuantity()) )
1197 while (entityIB.GetQuantity() > stackable)
1199 InventoryLocation spltDst =
new InventoryLocation;
1200 position[1] = position[1] + 0.1;
1201 spltDst.SetGroundEx(entity, position, direction);
1203 ItemBase splitItem = entityIB.SplitIntoStackMaxToInventoryLocationEx( spltDst );
1204 splitItem.ThrowPhysically(null, force,
false);
1208 InventoryLocation src =
new InventoryLocation;
1211 entityInventory.
TakeToDst(invMode, src, dst);
1212 entityIB.ThrowPhysically(null, force,
false);
1217 entityInventory.
DropEntity(invMode, entity.GetHierarchyRoot(), entity);
1222 static float GetCurrentItemHeatIsolation(
ItemBase pItem )
1227 float heatIsolation = pItem.GetHeatIsolation();
1228 float itemHealthLabel = pItem.GetHealthLevel();
1229 float itemWetness = pItem.GetWet();
1232 if ( itemWetness >= GameConstants.STATE_DRY && itemWetness < GameConstants.STATE_DAMP )
1234 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_DRY;
1236 else if ( itemWetness >= GameConstants.STATE_DAMP && itemWetness < GameConstants.STATE_WET )
1238 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_DAMP;
1240 else if ( itemWetness >= GameConstants.STATE_WET && itemWetness < GameConstants.STATE_SOAKING_WET )
1242 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_WET;
1244 else if ( itemWetness >= GameConstants.STATE_SOAKING_WET && itemWetness < GameConstants.STATE_DRENCHED )
1246 wetFactor = GameConstants.ENVIRO_ISOLATION_WETFACTOR_SOAKED;
1248 else if ( itemWetness >= GameConstants.STATE_DRENCHED )
1250 return GameConstants.ENVIRO_ISOLATION_WETFACTOR_DRENCHED;
1254 switch (itemHealthLabel)
1256 case GameConstants.STATE_PRISTINE:
1257 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_PRISTINE;
1260 case GameConstants.STATE_WORN:
1261 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_WORN;
1264 case GameConstants.STATE_DAMAGED:
1265 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_DAMAGED;
1268 case GameConstants.STATE_BADLY_DAMAGED:
1269 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_B_DAMAGED;
1272 case GameConstants.STATE_RUINED:
1273 healthFactor = GameConstants.ENVIRO_ISOLATION_HEALTHFACTOR_RUINED;
1278 heatIsolation *= healthFactor;
1279 heatIsolation *= wetFactor;
1281 return heatIsolation;
1284 static void FilterObstructingObjects(array<Object> potentiallyObstructingObjects, out array<Object> obstructingObjects)
1286 if (!obstructingObjects)
1287 obstructingObjects =
new array<Object>;
1289 for (
int i = 0; i < potentiallyObstructingObjects.Count(); ++i )
1291 Object obj = potentiallyObstructingObjects[i];
1292 if ( obj && ( obj.CanObstruct() || obj.CanProxyObstruct() ) )
1293 obstructingObjects.Insert(obj);
1297 static bool CanIgnoreDistanceCheck(
Object obj)
1299 return obj.IsTransport() || obj.CanUseConstruction();
1303 static void FilterObstructedObjectsByGrouping(vector origin,
float range,
float distanceDelta, array<Object> objects, array<Object> obstructingObjects, out array<Object> filteredObjects,
bool doDistanceCheck =
false,
bool checkIfDistanceCanBeIgnored =
false,
float maxDist = 0)
1305 array<Object> vicinityObjects=
new array<Object>;
1306 vicinityObjects.Copy(objects);
1311 int mCount = vicinityObjects.Count();
1313 if (!filteredObjects)
1314 filteredObjects =
new array<Object>();
1317 if ( doDistanceCheck )
1319 for ( i = vicinityObjects.Count() - 1; i >= 0; --i )
1321 Object obj = vicinityObjects[i];
1322 if ( obj && !CanIgnoreDistanceCheck( obj ) && vector.DistanceSq(origin, obj.GetPosition()) > maxDist * maxDist )
1323 vicinityObjects.Remove(i);
1328 array<Object> sortedObstructingObjects =
new array<Object>();
1329 array<float> distanceHelper =
new array<float>();
1330 array<float> distanceHelperUnsorted =
new array<float>();
1331 float distance, dist1, dist2;
1333 for ( i = 0; i < obstructingObjects.Count(); ++i )
1335 distance = vector.DistanceSq(obstructingObjects[i].GetWorldPosition(), origin);
1336 distanceHelper.Insert(distance);
1339 distanceHelperUnsorted.Copy(distanceHelper);
1340 distanceHelper.Sort();
1342 for ( i = distanceHelper.Count() - 1; i >= 0; --i )
1343 sortedObstructingObjects.Insert(obstructingObjects[distanceHelperUnsorted.Find(distanceHelper[i])]);
1345 array<ref array<Object>> tempGroups =
new array<ref array<Object>>();
1346 array<ref array<Object>> objectGroups =
new array<ref array<Object>>();
1347 array<Object> group;
1349 float cos = Math.Cos(90);
1350 float sin = Math.Sin(90);
1353 for ( i = 0; i < sortedObstructingObjects.Count(); ++i )
1355 Object obstrObj = sortedObstructingObjects[i];
1356 vector worldPos = obstrObj.GetWorldPosition();
1359 if ( obstrObj.GetCollisionBox(minMax) )
1363 max = max * (obstrObj.GetOrientation() * range);
1365 vector center, dx, dy, dz, half;
1366 center = (min + max) * 0.5;
1367 dz = obstrObj.GetOrientation();
1368 dx = vector.RotateAroundZero(dz, vector.Up, cos, sin);
1369 dy = vector.RotateAroundZero(dz, vector.Aside, cos, sin);
1370 half = (max - min) * 0.5;
1371 half =
Vector(Math.AbsFloat(half[0]), Math.AbsFloat(half[1]), Math.AbsFloat(half[2]));
1373 group =
new array<Object>();
1376 for ( j = vicinityObjects.Count() - 1; j >= 0; --j )
1378 Object vicObj = vicinityObjects[j];
1381 vector d = vicObj.GetWorldPosition() - worldPos + center;
1382 if ( Math.AbsFloat(vector.Dot(d, dx)) <= half[0] && Math.AbsFloat(vector.Dot(d, dy)) <= half[1] && Math.AbsFloat(vector.Dot(d, dz)) <= half[2] )
1384 group.Insert(vicObj);
1385 vicinityObjects.Remove(j);
1390 if ( group.Count() > 0 )
1391 tempGroups.Insert(group);
1396 for ( i = 0; i < tempGroups.Count(); ++i )
1397 SplitArrayIntoGroupsByDistance(tempGroups[i], objectGroups, distanceDelta);
1400 SplitArrayIntoGroupsByDistance(vicinityObjects, objectGroups, distanceDelta);
1404 foreach (array<Object> objectGroup : objectGroups)
1406 foreach (
Object filteredObject : objectGroup)
1408 if (!IsObjectObstructedEx(filteredObject, cache))
1409 filteredObjects.Insert(filteredObject);
1417 static void SplitArrayIntoGroupsByDistance(array<Object> objects, array<ref array<Object>> objectGroups,
float squaredDistanceDelta)
1419 array<Object> group;
1420 for (
int i = 0; i < objects.Count(); )
1422 Object obj1 = objects[i];
1425 group =
new array<Object>;
1427 for (
int j = objects.Count() - 1; j > i; --j )
1429 Object obj2 = objects[j];
1432 vector start = obj1.GetWorldPosition();
1433 vector end = obj2.GetWorldPosition();
1435 float distance = vector.DistanceSq(start, end);
1436 if ( distance < squaredDistanceDelta )
1443 objectGroups.Insert(group);
1451 static bool IsObjectObstructed(
Object object,
bool doDistanceCheck =
false, vector distanceCheckPos =
"0 0 0",
float maxDist = 0)
1454 MiscGameplayFunctions.GetHeadBonePos(PlayerBase.Cast(
g_Game.GetPlayer()), rayStart);
1457 return IsObjectObstructedEx(
object, cache, doDistanceCheck, distanceCheckPos, maxDist);
1460 static bool IsObjectObstructedEx(
Object object,
IsObjectObstructedCache cache,
bool doDistanceCheck =
false, vector distanceCheckPos =
"0 0 0",
float maxDist = 0)
1465 PlayerBase player = PlayerBase.Cast(
g_Game.GetPlayer());
1466 if (doDistanceCheck && vector.DistanceSq(player.GetPosition(), distanceCheckPos) > maxDist * maxDist)
1469 cache.ObjectCenterPos =
object.GetCenter();
1471 return IsObjectObstructedFilterEx(
object, cache, player);
1476 if (
object.CanProxyObstruct())
1478 RaycastRVParams rayInput =
new RaycastRVParams(cache.RaycastStart, cache.ObjectCenterPos, player);
1479 DayZPhysics.RaycastRVProxy(rayInput, cache.HitProxyObjects);
1480 if (cache.HitProxyObjects)
1482 if (cache.HitProxyObjects.Count() > 0)
1484 if (cache.HitProxyObjects[0].hierLevel > 0)
1487 if (!cache.HitProxyObjects[0].parent.IsMan())
1489 if (cache.HitProxyObjects[0].parent)
1492 GameInventory proxyInventory = proxyParent.GetInventory();
1493 if (proxyInventory && proxyInventory.
GetCargo())
1506 for (
int m = 0; m < cache.HitObjects.Count(); ++m)
1508 Object hit_object = cache.HitObjects.Get(m);
1510 if ( hit_object.CanObstruct() )
1535 RaycastRVParams rayInput =
new RaycastRVParams(cache.RaycastStart, cache.ObjectCenterPos, player);
1537 if (geometryTypeOverride != -1)
1538 rayInput.type = geometryTypeOverride;
1539 DayZPhysics.RaycastRVProxy(rayInput, cache.HitProxyObjects);
1543 if (cache.HitProxyObjects)
1545 count = cache.HitProxyObjects.Count();
1547 for (i = 0; i < count; ++i)
1549 if (cache.HitProxyObjects[i].hierLevel > 0)
1551 parent = cache.HitProxyObjects[i].parent;
1552 if (parent && !parent.IsMan() && parent.CanProxyObstruct())
1554 if (parent !=
object || (parent ==
object &&
object.CanProxyObstructSelf()))
1562 int geometry = ObjIntersectFire;
1563 if (geometryTypeOverride != -1)
1564 geometry = geometryTypeOverride;
1565 DayZPhysics.RaycastRV(cache.RaycastStart, cache.ObjectCenterPos, cache.ObjectContactPos, cache.ObjectContactDir, cache.ContactComponent, cache.HitObjects,
object,
g_Game.GetPlayer(),
false,
false, geometry, 0.0,
CollisionFlags.ALLOBJECTS);
1566 count = cache.HitObjects.Count();
1567 for (i = 0; i < count; ++i)
1569 if (cache.HitObjects[i].CanObstruct())
1577 static void DealEvinronmentAdjustedDmg(
ItemBase item, PlayerBase player,
float baseDamage)
1581 float adjustedDamage;
1583 g_Game.SurfaceUnderObject(player, surfaceType, liquidType);
1584 float modifierSurface = Surface.GetParamFloat(surfaceType,
"toolDamage");
1585 if (modifierSurface == 0)
1586 modifierSurface = 1;
1588 if (player.GetInColdArea())
1589 adjustedDamage = baseDamage * (modifierSurface +
g_Game.GetMission().GetWorldData().GetColdAreaToolDamageModifier());
1591 adjustedDamage = baseDamage * modifierSurface;
1593 DealAbsoluteDmg(item, adjustedDamage);
1597 static void DealAbsoluteDmg(
ItemBase item,
float dmg)
1599 item.DecreaseHealth(dmg,
false);
1603 static float Normalize(
int val,
int maxVal)
1607 Debug.LogError(
"Division by 0 is not allowed");
1611 return val / maxVal;
1614 static float Bobbing(
float period,
float amplitude,
float elapsedTime)
1620 elapsedTime /= period;
1623 cycle += elapsedTime;
1624 cycle = FModulus(cycle, 360);
1625 cycle = Math.Sin(cycle) * amplitude;
1631 static float FModulus(
float x,
float y)
1633 return Math.ModFloat(
x,
y);
1636 static void RemoveSplint( PlayerBase player )
1638 EntityAI entity = player.GetInventory().CreateInInventory(
"Splint");
1640 entity = player.SpawnEntityOnGroundOnCursorDir(
"Splint", 0.5);
1644 Class.CastTo(attachment, player.GetItemOnSlot(
"Splint_Right"));
1645 if ( attachment && attachment.GetType() ==
"Splint_Applied" )
1649 MiscGameplayFunctions.TransferItemProperties(attachment,new_item);
1654 if (new_item.GetHealthLevel() < 4)
1656 int newDmgLevel = new_item.GetHealthLevel() + 1;
1658 float max = new_item.GetMaxHealth(
"",
"");
1660 switch ( newDmgLevel )
1662 case GameConstants.STATE_BADLY_DAMAGED:
1663 new_item.SetHealth(
"",
"", max * GameConstants.DAMAGE_BADLY_DAMAGED_VALUE );
1666 case GameConstants.STATE_DAMAGED:
1667 new_item.SetHealth(
"",
"", max * GameConstants.DAMAGE_DAMAGED_VALUE );
1670 case GameConstants.STATE_WORN:
1671 new_item.SetHealth(
"",
"", max * GameConstants.DAMAGE_WORN_VALUE );
1674 case GameConstants.STATE_RUINED:
1675 new_item.SetHealth(
"",
"", max * GameConstants.DAMAGE_RUINED_VALUE );
1685 attachment.Delete();
1690 static void TeleportCheck(notnull PlayerBase player, notnull array<ref array<float>> safe_positions)
1692 if( player.GetSimulationTimeStamp() < 20 && !player.IsPersistentFlag(
PersistentFlag.AREA_PRESENCE) )
1697 vector player_pos = player.GetPosition();
1698 vector closest_safe_pos = MiscGameplayFunctions.GetClosestSafePos(player_pos, safe_positions);
1700 if (player_pos!=closest_safe_pos)
1702 closest_safe_pos[1] =
g_Game.SurfaceY(closest_safe_pos[0], closest_safe_pos[2]);
1704 player.SetPosition( closest_safe_pos );
1706 g_Game.RPCSingleParam(player,
ERPCs.RPC_WARNING_TELEPORT, null,
true, player.GetIdentity());
1708 PluginAdminLog adminLog = PluginAdminLog.Cast(
GetPlugin(PluginAdminLog));
1710 adminLog.PlayerTeleportedLog(player,player_pos,closest_safe_pos,
"Unwillingly spawning in contaminated area.");
1717 static vector GetClosestSafePos(vector to_pos, notnull array<ref array<float>> positions)
1719 vector closest_pos = to_pos;
1720 float smallest_dist =
float.MAX;
1721 foreach( array<float> pos:positions)
1723 vector vpos =
"0 0 0";
1728 float dist = vector.DistanceSq(to_pos, vpos);
1729 if ( dist < smallest_dist)
1731 smallest_dist = dist;
1739 static bool TeleportPlayerToSafeLocation3D(notnull PlayerBase player, vector safePos)
1741 vector playerPos = player.GetPosition();
1742 if (playerPos != safePos)
1744 player.SetPosition(safePos);
1745 g_Game.RPCSingleParam(player,
ERPCs.RPC_WARNING_TELEPORT, null,
true, player.GetIdentity());
1753 static void GenerateAINoiseAtPosition(vector position,
float lifeTime,
NoiseParams noiseParams)
1757 NoiseSystem noise =
g_Game.GetNoiseSystem();
1760 noise.AddNoiseTarget(position, lifeTime, noiseParams, NoiseAIEvaluate.GetNoiseReduction(
g_Game.GetWeather()));
1767 float minValue = 0.0;
1768 for (
int i = 0; i < pArray.Count(); ++i)
1770 if (minValue == 0 || pArray.Get(i) < minValue)
1772 minValue = pArray.Get(i);
1781 float maxValue = 0.0;
1782 for (
int i = 0; i < pArray.Count(); ++i)
1784 if (maxValue == 0 || pArray.Get(i) > maxValue)
1786 maxValue = pArray.Get(i);
1793 static string GetItemDisplayName(
string type)
1795 return g_Game.ConfigGetTextOut(
"CfgVehicles " + type +
" displayName");
1798 static bool IsComponentInSelection(array<Selection> pSelection,
string pCompName)
1800 if (pSelection.Count() == 0 || pCompName.Length() == 0)
1805 for (
int i = 0; i < pSelection.Count(); ++i)
1807 pCompName.ToLower();
1808 if (pSelection[i] && pSelection[i].
GetName() == pCompName)
1819 if (!MiscGameplayFunctions.IsComponentInSelection(pSelection, pCompName))
1824 for (
int i = 0; i < pSelection.Count(); ++i)
1826 pCompName.ToLower();
1827 if (pSelection[i] && pSelection[i].
GetName() == pCompName)
1836 static void RemoveAllAttachedChildrenByTypename(notnull
EntityAI parent, array<typename> listOfTypenames)
1838 if (listOfTypenames.Count() > 0)
1843 Object childToRemove = child;
1844 child =
Object.Cast(child.GetSibling());
1846 if (childToRemove.IsAnyInherited(listOfTypenames))
1848 vector pos = parent.GetPosition();
1849 parent.RemoveChild(childToRemove,
false);
1852 Math3D.MatrixIdentity4(m4);
1854 childToRemove.SetTransform(m4);
1855 childToRemove.PlaceOnSurface();
1861 static void DeleteAttachedChildrenByTypename(notnull
EntityAI parent, array<typename> listOfTypenames)
1863 if (listOfTypenames.Count() > 0)
1868 Object childToRemove = child;
1869 child =
Object.Cast(child.GetSibling());
1871 if (childToRemove.IsAnyInherited(listOfTypenames))
1873 parent.RemoveChild(childToRemove,
false);
1874 childToRemove.Delete();
1881 static void GetAttachedChildren(IEntity parent, array<IEntity> outputObjects)
1886 outputObjects.Insert(child);
1891 static void SoakItemInsideParentContainingLiquidAboveThreshold(notnull
ItemBase item, notnull
ItemBase parent,
float liquidQuantityThresholdPercentage = 0.05)
1895 if (parent.GetLiquidType() != 0 && parent.GetQuantityNormalized() > liquidQuantityThresholdPercentage && !parent.GetIsFrozen())
1900 static float GetCombinedSnowfallWindValue()
1904 g_Game.GetWeather().GetWindMagnitude().GetLimits(windMin, windMax);
1905 float snowfall =
g_Game.GetWeather().GetSnowfall().GetActual();
1906 float value = snowfall +
g_Game.GetWeather().GetWindMagnitude().GetActual() / windMax;
1912class DestroyItemInCorpsesHandsAndCreateNewOnGndLambda : ReplaceAndDestroyLambda
1915 void DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(
EntityAI old_item,
string new_item_type,
PlayerBase player,
bool destroy =
false)
1920 old_item.GetTransform(mtx);
1922 player.GetTransform(mtx);
1923 gnd.SetGround(NULL, mtx);
1924 OverrideNewLocation(gnd);
1929 super.RemoveOldItemFromLocation();
1930 m_Player.GetHumanInventory().OnEntityInHandsDestroyed(m_OldLocation);