DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
ActionSkinning.c
Go to the documentation of this file.
1/*
2Example of skinning config which should be inside animal's base class:
3class Skinning
4{
5 // All classes in this scope are parsed, so they can have any name.
6 class ObtainedSteaks
7 {
8 item = "DeerSteakMeat"; // item to spawn
9 count = 10; // How many items to spawn
10 transferToolDamageCoef = 1; // Optional: How much tool's damage is transfered to item's damage.
11
12 // Make sure to have only 1 of the following quantity paramenter
13 quantity = 100; // Optional: Set item's quantity
14 quantityCoef = 1; // Optional: Set item's quantity (in coefficient)
15 quantityMinMax[] = {100, 200}; // Optional: Set item's quantity within min/max values
16 quantityMinMaxCoef[] = {0, 1}; // Optional: Set item's quantity (in coefficient) within min/max values
17 };
18};
19*/
20
22{
23 override void CreateActionComponent()
24 {
26 }
27};
28
30{
32 {
35
36 m_CommandUID = DayZPlayerConstants.CMD_ACTIONFB_ANIMALSKINNING;
37 m_StanceMask = DayZPlayerConstants.STANCEMASK_CROUCH;
38 m_FullBody = true;
39 m_Text = "#skin";
40 }
41
43 {
46 }
47
48 override bool ActionCondition( PlayerBase player, ActionTarget target, ItemBase item )
49 {
50 Object targetObject = target.GetObject();
51 if ( targetObject != NULL )
52 {
53 if ( targetObject.CanBeSkinned() && !targetObject.IsAlive() )
54 {
55 EntityAI target_EAI;
56 Class.CastTo(target_EAI, targetObject );
57
58 if (!GetGame().IsServer()) // Temporal hackfix for skinning not working in multiplayer. Waiting for DAYZ-28269 to be resolved.
59 return true;
60
61 if ( target_EAI.CanBeSkinnedWith(item) )
62 {
63 return true;
64 }
65 }
66 }
67
68 return false;
69 }
70
71 // Spawns the loot according to the Skinning class in the dead agent's config
72 override void OnFinishProgressServer( ActionData action_data )
73 {
74 Object targetObject = action_data.m_Target.GetObject();
75
76 // Prepare to read config variables
77 string item_to_spawn;
78 string cfg_skinning_organ_class;
79
80 // Mark the body as skinned to forbid another skinning action on it
81 EntityAI body;
82 Class.CastTo(body, targetObject );
83 vector body_pos = body.GetPosition();
84 body.SetAsSkinned();
85
86 if (body.IsInherited(PlayerBase))
87 {
88 // This section drops all clothes (and attachments) from the dead player before deleting their body
89 PlayerBase body_PB = PlayerBase.Cast(body);
90
91 if (body_PB.IsRestrained() && body_PB.GetHumanInventory().GetEntityInHands())
92 {
93 MiscGameplayFunctions.TransformRestrainItem(body_PB.GetHumanInventory().GetEntityInHands(), null, action_data.m_Player, body_PB);
94 /*
95 EntityAI item_in_hands = action_data.m_MainItem;
96 body_PB.SetRestrained(false);
97 string new_item_name = MiscGameplayFunctions.ObtainRestrainItemTargetClassname(item_in_hands);
98 MiscGameplayFunctions.TurnItemInHandsIntoItemEx(body_PB, new UnrestrainSelfPlayer(item_in_hands, new_item_name));
99 */
100 }
101 //Remove splint if target is wearing one
102 if (body_PB.IsWearingSplint())
103 {
104 EntityAI entity = action_data.m_Player.SpawnEntityOnGroundOnCursorDir("Splint", 0.5);
105 EntityAI attachment;
106 ItemBase new_item = ItemBase.Cast(entity);
107 Class.CastTo(attachment, body_PB.GetItemOnSlot("Splint_Right"));
108 if ( attachment && attachment.GetType() == "Splint_Applied" )
109 {
110 if (new_item)
111 {
112 MiscGameplayFunctions.TransferItemProperties(attachment,new_item);
113
114 if (GetGame().IsServer())
115 {
116 //Lower health level of splint after use
117 if (new_item.GetHealthLevel() < 4)
118 {
119 int newDmgLevel = new_item.GetHealthLevel() + 1;
120
121 float max = new_item.GetMaxHealth("","");
122
123 switch ( newDmgLevel )
124 {
126 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_BADLY_DAMAGED_VALUE );
127 break;
128
130 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_DAMAGED_VALUE );
131 break;
132
134 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_WORN_VALUE );
135 break;
136
138 new_item.SetHealth( "", "", max * GameConstants.DAMAGE_RUINED_VALUE );
139 break;
140
141 default:
142 break;
143 }
144 }
145 }
146 }
147 attachment.Delete();
148 }
149 }
150
151 /*
152 DropEquipAndDestroyRootLambda lambda(body_PB, "", action_data.m_Player);
153 action_data.m_Player.ServerReplaceItemWithNew(lambda);
154 */
155 int deadBodyLifetime;
156 if ( GetCEApi() )
157 {
158 deadBodyLifetime = GetCEApi().GetCEGlobalInt( "CleanupLifetimeDeadPlayer" );
159 if ( deadBodyLifetime <= 0 )
160 {
161 deadBodyLifetime = 3600;
162 }
163 }
164 array<EntityAI> children = new array<EntityAI>;
165 body_PB.GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, children);
166 int count = children.Count();
167 for (int i = 0; i < count; ++i)
168 {
169 EntityAI child = children.Get(i);
170 if ( child )
171 {
172 body_PB.GetInventory().DropEntity(InventoryMode.SERVER, body_PB, child);
173 child.SetLifetime( deadBodyLifetime );
174 }
175 }
176 }
177
178 DropArrows(body);
179 GetGame().ObjectDelete(body); // Temporal deletion of the body
180
181 // clutter cutter removed due to issues with audio it causes when players steps on it.
182 //Object cutter = GetGame().CreateObject( "ClutterCutter2x2", body_pos, false ); // clutter cutter to free space on ground for organs.
183
184 // Get config path to the animal
185 string cfg_animal_class_path = "cfgVehicles " + body.GetType() + " " + "Skinning ";
186
187 // Getting item type from the config
188 int child_count = g_Game.ConfigGetChildrenCount( cfg_animal_class_path );
189
190 // Parsing of the 'Skinning' class in the config of the dead body
191 for ( int i1 = 0; i1 < child_count; i1++ )
192 {
193 // To make configuration as convenient as possible, all classes are parsed and parameters are read
194 g_Game.ConfigGetChildName(cfg_animal_class_path, i1, cfg_skinning_organ_class); // out cfg_skinning_organ_class
195 cfg_skinning_organ_class = cfg_animal_class_path + cfg_skinning_organ_class + " ";
196 g_Game.ConfigGetText(cfg_skinning_organ_class + "item", item_to_spawn); // out item_to_spawn
197
198 if ( item_to_spawn != "" ) // Makes sure to ignore incompatible parameters in the Skinning class of the agent
199 {
200 // Spawning items in action_data.m_Player's inventory
201 int item_count = g_Game.ConfigGetInt( cfg_skinning_organ_class + "count" );
202
203 array<string> itemZones = new array<string>;
204 array<float> itemCount = new array<float>;
205 float zoneDmg = 0;
206
207 GetGame().ConfigGetTextArray( cfg_skinning_organ_class + "itemZones", itemZones);
208 GetGame().ConfigGetFloatArray( cfg_skinning_organ_class + "countByZone", itemCount);
209
210 if ( itemCount.Count() > 0 )
211 {
212 item_count = 0;
213 for ( int z = 0; z < itemZones.Count(); z++ )
214 {
215 zoneDmg = targetObject.GetHealth01(itemZones[z], "Health");
216 zoneDmg *= itemCount[z]; //just re-using variable
217 item_count += Math.Floor( zoneDmg ) ;
218 }
219 }
220
221 for ( int i2 = 0; i2 < item_count; i2++ )
222 {
223 ItemBase spawn_result = CreateOrgan( action_data.m_Player, body_pos, item_to_spawn, cfg_skinning_organ_class, action_data.m_MainItem );
224
225 //Damage pelts based on the average values on itemZones
226 //It only works if the "quantityCoef" in the config is more than 0
227 float qtCoeff = GetGame().ConfigGetFloat( cfg_skinning_organ_class + "quantityCoef");
228 if(qtCoeff > 0)
229 {
230 float avgDmgZones = 0;
231 for(int c2 = 0; c2 < itemZones.Count(); c2++ )
232 {
233 avgDmgZones += targetObject.GetHealth01(itemZones[c2], "Health");
234 }
235
236 avgDmgZones = avgDmgZones/itemZones.Count(); // Evaluate the average Health
237
238 if(spawn_result)
239 spawn_result.SetHealth01("","", avgDmgZones);
240 }
241
242
243
244 // handle fat/guts from human bodies
245 if ( ( item_to_spawn == "Lard" ) || ( item_to_spawn == "Guts" ) )
246 {
247 if ( body.IsKindOf( "SurvivorBase" ) )
248 {
249 spawn_result.InsertAgent(eAgents.BRAIN, 1);
250 }
251 }
252 }
253
254 /*action_data.m_MainItem.DecreaseHealth("","",UADamageApplied.SKINNING); // wear out tool
255 Print(action_data.m_MainItem.GetHealth01());*/
256 }
257 }
258
259 MiscGameplayFunctions.DealAbsoluteDmg(action_data.m_MainItem, UADamageApplied.SKINNING);
260
261 PluginLifespan module_lifespan = PluginLifespan.Cast( GetPlugin( PluginLifespan ) );
262 module_lifespan.UpdateBloodyHandsVisibility( action_data.m_Player, true );
263
264 action_data.m_Player.GetSoftSkillsManager().AddSpecialty( m_SpecialtyWeight );
265 }
266
268 {
269 return body_pos + Vector(Math.RandomFloat01() - 0.5, 0, Math.RandomFloat01() - 0.5);
270 }
271
272 private void DropArrows(EntityAI body)
273 {
274 ArrowManagerBase arrowManager = body.GetArrowManager();
275 if (arrowManager)
276 {
277 vector bodyPos = body.GetPosition();
278 int count = arrowManager.GetArrowsCount();
279 for (int i = count - 1; i >= 0; i--)
280 {
281 EntityAI arrow = arrowManager.GetArrow(i);
282 body.RemoveChild(arrow);
283
284 vector m4[4];
286
287 vector pos = GetRandomPos(bodyPos);
288 m4[3] = pos;
289
290 arrow.PlaceOnSurfaceRotated(m4, pos);
291
292 arrow.SetTransform(m4);
293 arrow.PlaceOnSurface();
294 }
295 }
296 }
297
298 // Spawns an organ defined in the given config
299 ItemBase CreateOrgan( PlayerBase player, vector body_pos, string item_to_spawn, string cfg_skinning_organ_class, ItemBase tool)
300 {
301 // Create item from config
302 ItemBase added_item;
303 vector pos_rnd = GetRandomPos(body_pos);
304 Class.CastTo(added_item, GetGame().CreateObjectEx( item_to_spawn, pos_rnd, ECE_PLACE_ON_SURFACE ) );
305
306 // Check if skinning is configured for this body
307 if (!added_item)
308 return NULL;
309
310 // Set randomized position
311 added_item.PlaceOnSurface();
312
313 // Set item's quantity from config, if it's defined there.
314 float item_quantity = 0;
315 array<float> quant_min_max = new array<float>;
316 array<float> quant_min_max_coef = new array<float>;
317
318 GetGame().ConfigGetFloatArray( cfg_skinning_organ_class + "quantityMinMax", quant_min_max);
319 GetGame().ConfigGetFloatArray( cfg_skinning_organ_class + "quantityMinMaxCoef", quant_min_max_coef);
320
321
322 // Read config for quantity value
323 if (quant_min_max.Count() > 0)
324 {
325 float soft_skill_manipulated_value = ( quant_min_max.Get(0)+ quant_min_max.Get(1) ) / 2;
326 float min_quantity = player.GetSoftSkillsManager().AddSpecialtyBonus( soft_skill_manipulated_value, this.GetSpecialtyWeight() );
327 item_quantity = Math.RandomFloat(min_quantity, quant_min_max.Get(1));
328 }
329
330 if (quant_min_max_coef.Count() > 0)
331 {
332 float coef = Math.RandomFloat(quant_min_max_coef.Get(0), quant_min_max_coef.Get(1));
333 item_quantity = added_item.GetQuantityMax() * coef;
334 }
335
336 if ( GetGame().ConfigGetFloat( cfg_skinning_organ_class + "quantity" ) > 0 )
337 item_quantity = g_Game.ConfigGetFloat( cfg_skinning_organ_class + "quantity" );
338
339 if ( GetGame().ConfigGetFloat( cfg_skinning_organ_class + "quantityCoef" ) > 0 )
340 {
341 float coef2 = g_Game.ConfigGetFloat( cfg_skinning_organ_class + "quantityCoef" );
342 item_quantity = added_item.GetQuantityMax() * coef2;
343 }
344
345 if ( item_quantity > 0 )
346 {
347 item_quantity = Math.Round(item_quantity);
348 added_item.SetQuantity( item_quantity, false );
349 }
350
351 // Transfer tool's damage to the item's condition
352 float item_apply_tool_damage_coef = GetGame().ConfigGetFloat( cfg_skinning_organ_class + "transferToolDamageCoef" );
353
354 if ( item_apply_tool_damage_coef > 0 )
355 {
356 float tool_dmg_coef = 1 - tool.GetHealth01();
357 float organ_dmg_coef = tool_dmg_coef * item_apply_tool_damage_coef;
358 added_item.DecreaseHealthCoef( organ_dmg_coef );
359 }
360
361 added_item.InsertAgent(eAgents.SALMONELLA, 1);
362 return added_item;
363 }
364
365 override void OnFinishProgressClient( ActionData action_data )
366 {
367 super.OnFinishProgressClient( action_data );
368
369 if ( action_data.m_Target )
370 {
371 Object target_obj = action_data.m_Target.GetObject();
372
373 if ( target_obj.IsKindOf( "Animal_CapreolusCapreolus" ) || target_obj.IsKindOf( "Animal_CapreolusCapreolusF" ) || target_obj.IsKindOf( "Animal_CervusElaphus" ) || target_obj.IsKindOf( "Animal_CervusElaphusF" ) )
374 {
376 }
377 }
378 }
379};
InventoryMode
Definition Inventory.c:20
float GetSpecialtyWeight()
protected float m_SpecialtyWeight
Definition ActionBase.c:68
ref CCIBase m_ConditionItem
Definition ActionBase.c:55
ref CCTBase m_ConditionTarget
Definition ActionBase.c:56
protected string m_Text
Definition ActionBase.c:49
protected bool m_FullBody
Definition ActionBase.c:52
protected int m_StanceMask
Definition ActionBase.c:53
class ActionTargets ActionTarget
proto native CEApi GetCEApi()
Get the CE API.
const int ECE_PLACE_ON_SURFACE
DayZGame g_Game
Definition DayZGame.c:3654
eAgents
Definition EAgents.c:3
void PluginLifespan()
PluginBase GetPlugin(typename plugin_type)
protected ActionData m_ActionData
ItemBase m_MainItem
Definition ActionBase.c:28
PlayerBase m_Player
Definition ActionBase.c:33
ref CABase m_ActionComponent
Definition ActionBase.c:30
ref ActionTarget m_Target
Definition ActionBase.c:32
override void CreateActionComponent()
override void OnFinishProgressServer(ActionData action_data)
private void DropArrows(EntityAI body)
override void CreateConditionComponents()
vector GetRandomPos(vector body_pos)
override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item)
override void OnFinishProgressClient(ActionData action_data)
ItemBase CreateOrgan(PlayerBase player, vector body_pos, string item_to_spawn, string cfg_skinning_organ_class, ItemBase tool)
EntityAI GetArrow(int index)
proto native void ObjectDelete(Object obj)
proto native void ConfigGetFloatArray(string path, out TFloatArray values)
Get array of floats from config on path.
proto native float ConfigGetFloat(string path)
Get float value from config on path.
proto native void ConfigGetTextArray(string path, out TStringArray values)
Get array of strings from config on path.
AnalyticsManagerClient GetAnalyticsClient()
Definition Game.c:1412
Super root of all classes in Enforce script.
Definition EnScript.c:11
Definition EnMath.c:7
const float SKINNING
const float PRECISE_MEDIUM
const float SKIN
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
DayZPlayerConstants
defined in C++
Definition dayzplayer.c:602
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Definition gameplay.c:6
proto native CGame GetGame()
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
const float DAMAGE_RUINED_VALUE
Definition constants.c:758
const float DAMAGE_DAMAGED_VALUE
Definition constants.c:756
const float DAMAGE_BADLY_DAMAGED_VALUE
Definition constants.c:757
const float DAMAGE_WORN_VALUE
Definition constants.c:755
const int STATE_RUINED
Definition constants.c:742
const int STATE_BADLY_DAMAGED
Definition constants.c:743
const int STATE_DAMAGED
Definition constants.c:744
const int STATE_WORN
Definition constants.c:745
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
static void MatrixIdentity4(out vector mat[4])
Creates identity matrix.
Definition EnMath3D.c:233
static proto float Round(float f)
Returns mathematical round of value.
static proto float RandomFloat(float min, float max)
Returns a random float number between and min[inclusive] and max[exclusive].
static float RandomFloat01()
Returns a random float number between and min [inclusive] and max [inclusive].
Definition EnMath.c:106
static proto float Floor(float f)
Returns floor of value.