Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
actionskinning.c
Go to the documentation of this file.
1 /*
2 Example of skinning config which should be inside animal's base class:
3 class 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  {
25  m_ActionData.m_ActionComponent = new CAContinuousTime(UATimeSpent.SKIN);
26  }
27 }
28 
30 {
32  {
33  m_CallbackClass = ActionSkinningCB;
34  m_SpecialtyWeight = UASoftSkillsWeight.PRECISE_MEDIUM;
35 
36  m_CommandUID = DayZPlayerConstants.CMD_ACTIONFB_ANIMALSKINNING;
37  m_StanceMask = DayZPlayerConstants.STANCEMASK_CROUCH;
38  m_FullBody = true;
39  m_Text = "#skin";
40  }
41 
42  override void CreateConditionComponents()
43  {
46  }
47 
48  override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item)
49  {
50  Object targetObject = target.GetObject();
51 
52  if (targetObject.CanBeSkinned() && !targetObject.IsAlive())
53  {
54  EntityAI target_EAI;
55  if (Class.CastTo(target_EAI, targetObject) && target_EAI.CanBeSkinnedWith(item))
56  return true;
57  }
58 
59  return false;
60  }
61 
62  // Spawns the loot according to the Skinning class in the dead agent's config
63  override void OnFinishProgressServer(ActionData action_data)
64  {
65  super.OnFinishProgressServer(action_data);
66 
67  Object targetObject = action_data.m_Target.GetObject();
68 
69  // Mark the body as skinned to forbid another skinning action on it
70  EntityAI body = EntityAI.Cast(targetObject);
71  body.SetAsSkinned();
72 
73  MiscGameplayFunctions.RemoveAllAttachedChildrenByTypename(body, {Bolt_Base});
74 
75  HandlePlayerBody(action_data);
76  SpawnItems(action_data);
77 
78  if (body)
79  {
80  GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Call(GetGame().ObjectDelete,body);
81  }
82 
83  MiscGameplayFunctions.DealAbsoluteDmg(action_data.m_MainItem, UADamageApplied.SKINNING);
84 
85  PluginLifespan moduleLifespan = PluginLifespan.Cast(GetPlugin(PluginLifespan));
86  moduleLifespan.UpdateBloodyHandsVisibility(action_data.m_Player, true);
87  action_data.m_Player.GetSoftSkillsManager().AddSpecialty(m_SpecialtyWeight);
88  }
89 
91  {
92  return body_pos + Vector(Math.RandomFloat01() - 0.5, 0, Math.RandomFloat01() - 0.5);
93  }
94 
95  // Spawns an organ defined in the given config
96  ItemBase CreateOrgan(PlayerBase player, vector body_pos, string item_to_spawn, string cfg_skinning_organ_class, ItemBase tool)
97  {
98  // Create item from config
99  ItemBase added_item;
100  vector pos_rnd = GetRandomPos(body_pos);
101  Class.CastTo(added_item, GetGame().CreateObjectEx(item_to_spawn, pos_rnd, ECE_PLACE_ON_SURFACE));
102 
103  // Check if skinning is configured for this body
104  if (!added_item)
105  return null;
106 
107  // Set randomized position
108  added_item.PlaceOnSurface();
109 
110  // Set item's quantity from config, if it's defined there.
111  float item_quantity = 0;
112  array<float> quant_min_max = new array<float>;
113  array<float> quant_min_max_coef = new array<float>;
114 
115  GetGame().ConfigGetFloatArray(cfg_skinning_organ_class + "quantityMinMax", quant_min_max);
116  GetGame().ConfigGetFloatArray(cfg_skinning_organ_class + "quantityMinMaxCoef", quant_min_max_coef);
117 
118 
119  // Read config for quantity value
120  if (quant_min_max.Count() > 0)
121  {
122  float soft_skill_manipulated_value = (quant_min_max.Get(0)+ quant_min_max.Get(1)) / 2;
123  float min_quantity = player.GetSoftSkillsManager().AddSpecialtyBonus(soft_skill_manipulated_value, this.GetSpecialtyWeight());
124  item_quantity = Math.RandomFloat(min_quantity, quant_min_max.Get(1));
125  }
126 
127  if (quant_min_max_coef.Count() > 0)
128  {
129  float coef = Math.RandomFloat(quant_min_max_coef.Get(0), quant_min_max_coef.Get(1));
130  item_quantity = added_item.GetQuantityMax() * coef;
131  }
132 
133  if (GetGame().ConfigGetFloat(cfg_skinning_organ_class + "quantity") > 0)
134  item_quantity = g_Game.ConfigGetFloat(cfg_skinning_organ_class + "quantity");
135 
136  if (GetGame().ConfigGetFloat(cfg_skinning_organ_class + "quantityCoef") > 0)
137  {
138  float coef2 = g_Game.ConfigGetFloat(cfg_skinning_organ_class + "quantityCoef");
139  item_quantity = added_item.GetQuantityMax() * coef2;
140  }
141 
142  if (item_quantity > 0)
143  {
144  item_quantity = Math.Round(item_quantity);
145  added_item.SetQuantity(item_quantity, false);
146  }
147 
148  // Transfer tool's damage to the item's condition
149  float item_apply_tool_damage_coef = GetGame().ConfigGetFloat(cfg_skinning_organ_class + "transferToolDamageCoef");
150 
151  if (item_apply_tool_damage_coef > 0)
152  {
153  float tool_dmg_coef = 1 - tool.GetHealth01();
154  float organ_dmg_coef = tool_dmg_coef * item_apply_tool_damage_coef;
155  added_item.DecreaseHealthCoef(organ_dmg_coef);
156  }
157 
158  added_item.InsertAgent(eAgents.SALMONELLA, 1);
159  return added_item;
160  }
161 
162  override void OnFinishProgressClient(ActionData action_data)
163  {
164  super.OnFinishProgressClient(action_data);
165 
166  if (action_data.m_Target)
167  {
168  Object target_obj = action_data.m_Target.GetObject();
169 
170  if (target_obj.IsKindOf("Animal_CapreolusCapreolus") || target_obj.IsKindOf("Animal_CapreolusCapreolusF") || target_obj.IsKindOf("Animal_CervusElaphus") || target_obj.IsKindOf("Animal_CervusElaphusF"))
171  {
172  GetGame().GetAnalyticsClient().OnActionFinishedGutDeer();
173  }
174  }
175  }
176 
178  void HandlePlayerBody(ActionData action_data)
179  {
180  PlayerBase body;
181  if (Class.CastTo(body,action_data.m_Target.GetObject()))
182  {
183  if (body.IsRestrained() && body.GetHumanInventory().GetEntityInHands())
184  MiscGameplayFunctions.TransformRestrainItem(body.GetHumanInventory().GetEntityInHands(), null, action_data.m_Player, body);
185 
186  //Remove splint if target is wearing one
187  if (body.IsWearingSplint())
188  {
189  EntityAI entity = action_data.m_Player.SpawnEntityOnGroundOnCursorDir("Splint", 0.5);
190  ItemBase newItem = ItemBase.Cast(entity);
191  EntityAI attachment = body.GetItemOnSlot("Splint_Right");
192  if (attachment && attachment.GetType() == "Splint_Applied")
193  {
194  if (newItem)
195  {
196  MiscGameplayFunctions.TransferItemProperties(attachment, newItem);
197  //Lower health level of splint after use
198  if (newItem.GetHealthLevel() < 4)
199  {
200  int newDmgLevel = newItem.GetHealthLevel() + 1;
201  float max = newItem.GetMaxHealth("", "");
202 
203  switch (newDmgLevel)
204  {
205  case GameConstants.STATE_BADLY_DAMAGED:
206  newItem.SetHealth("", "", max * GameConstants.DAMAGE_BADLY_DAMAGED_VALUE);
207  break;
208 
209  case GameConstants.STATE_DAMAGED:
210  newItem.SetHealth("", "", max * GameConstants.DAMAGE_DAMAGED_VALUE);
211  break;
212 
213  case GameConstants.STATE_WORN:
214  newItem.SetHealth("", "", max * GameConstants.DAMAGE_WORN_VALUE);
215  break;
216 
217  case GameConstants.STATE_RUINED:
218  newItem.SetHealth("", "", max * GameConstants.DAMAGE_RUINED_VALUE);
219  break;
220 
221  default:
222  break;
223  }
224  }
225  }
226 
227  attachment.Delete();
228  }
229  }
230 
231  int deadBodyLifetime;
232  if (GetCEApi())
233  {
234  deadBodyLifetime = GetCEApi().GetCEGlobalInt("CleanupLifetimeDeadPlayer");
235  if (deadBodyLifetime <= 0)
236  deadBodyLifetime = 3600;
237  }
238 
239  DropInventoryItems(body,deadBodyLifetime);
240  }
241  }
242 
243  void DropInventoryItems(PlayerBase body, float newLifetime)
244  {
245  array<EntityAI> children = new array<EntityAI>;
246  body.GetInventory().EnumerateInventory(InventoryTraversalType.LEVELORDER, children);
247  foreach (EntityAI child : children)
248  {
249  if (child)
250  {
251  child.SetLifetime(newLifetime);
252  body.GetInventory().DropEntity(InventoryMode.SERVER, body, child);
253  }
254  }
255  }
256 
257  void SpawnItems(ActionData action_data)
258  {
259  EntityAI body = EntityAI.Cast(action_data.m_Target.GetObject());
260 
261  // Get config path to the animal
262  string cfg_animal_class_path = "cfgVehicles " + body.GetType() + " " + "Skinning ";
263  vector bodyPosition = body.GetPosition();
264 
265  // Getting item type from the config
266  int child_count = g_Game.ConfigGetChildrenCount(cfg_animal_class_path);
267 
268  string item_to_spawn;
269  string cfg_skinning_organ_class;
270  // Parsing of the 'Skinning' class in the config of the dead body
271  for (int i1 = 0; i1 < child_count; i1++)
272  {
273  // To make configuration as convenient as possible, all classes are parsed and parameters are read
274  g_Game.ConfigGetChildName(cfg_animal_class_path, i1, cfg_skinning_organ_class); // out cfg_skinning_organ_class
275  cfg_skinning_organ_class = cfg_animal_class_path + cfg_skinning_organ_class + " ";
276  g_Game.ConfigGetText(cfg_skinning_organ_class + "item", item_to_spawn); // out item_to_spawn
277 
278  if (item_to_spawn != "") // Makes sure to ignore incompatible parameters in the Skinning class of the agent
279  {
280  // Spawning items in action_data.m_Player's inventory
281  int item_count = g_Game.ConfigGetInt(cfg_skinning_organ_class + "count");
282 
283  array<string> itemZones = new array<string>;
284  array<float> itemCount = new array<float>;
285  float zoneDmg = 0;
286 
287  GetGame().ConfigGetTextArray(cfg_skinning_organ_class + "itemZones", itemZones);
288  GetGame().ConfigGetFloatArray(cfg_skinning_organ_class + "countByZone", itemCount);
289 
290  if (itemCount.Count() > 0)
291  {
292  item_count = 0;
293  for (int z = 0; z < itemZones.Count(); z++)
294  {
295  zoneDmg = body.GetHealth01(itemZones[z], "Health");
296  zoneDmg *= itemCount[z]; //just re-using variable
297  item_count += Math.Floor(zoneDmg);
298  }
299  }
300 
301  for (int i2 = 0; i2 < item_count; i2++)
302  {
303  ItemBase spawn_result = CreateOrgan(action_data.m_Player, bodyPosition, item_to_spawn, cfg_skinning_organ_class, action_data.m_MainItem);
304 
305  //Damage pelts based on the average values on itemZones
306  //It only works if the "quantityCoef" in the config is more than 0
307  float qtCoeff = GetGame().ConfigGetFloat(cfg_skinning_organ_class + "quantityCoef");
308  if (qtCoeff > 0)
309  {
310  float avgDmgZones = 0;
311  for (int c2 = 0; c2 < itemZones.Count(); c2++)
312  {
313  avgDmgZones += body.GetHealth01(itemZones[c2], "Health");
314  }
315 
316  avgDmgZones = avgDmgZones/itemZones.Count(); // Evaluate the average Health
317 
318  if (spawn_result)
319  spawn_result.SetHealth01("","", avgDmgZones);
320  }
321 
322  // handle fat/guts from human bodies
323  if ((item_to_spawn == "Lard") || (item_to_spawn == "Guts"))
324  {
325  if (body.IsKindOf("SurvivorBase"))
326  {
327  spawn_result.InsertAgent(eAgents.BRAIN, 1);
328  }
329  }
330  }
331  }
332  }
333  }
334 }
ItemBase
Definition: inventoryitem.c:730
GetGame
proto native CGame GetGame()
CALL_CATEGORY_SYSTEM
const int CALL_CATEGORY_SYSTEM
Definition: tools.c:8
SpawnItems
void SpawnItems(ActionData action_data)
Definition: actionskinning.c:257
GetSpecialtyWeight
float GetSpecialtyWeight()
Definition: actionbase.c:1044
ActionCondition
override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item)
Definition: actionskinning.c:48
UADamageApplied
Definition: actionconstants.c:130
CAContinuousTime
Definition: cacontinuoustime.c:1
GetRandomPos
vector GetRandomPos(vector body_pos)
Definition: actionskinning.c:90
UASoftSkillsWeight
Definition: actionconstants.c:118
ActionSkinning
ActionSkinningCB ActionContinuousBaseCB ActionSkinning()
Definition: actionskinning.c:31
ECE_PLACE_ON_SURFACE
const int ECE_PLACE_ON_SURFACE
Definition: centraleconomy.c:37
DropInventoryItems
void DropInventoryItems(PlayerBase body, float newLifetime)
Definition: actionskinning.c:243
ActionSkinningCB
Definition: actionskinning.c:21
GetPlugin
PluginBase GetPlugin(typename plugin_type)
Definition: pluginmanager.c:316
OnFinishProgressServer
override void OnFinishProgressServer(ActionData action_data)
Definition: actionskinning.c:63
CCTCursorNoRuinCheck
Definition: cctcursornoruincheck.c:1
m_FullBody
protected bool m_FullBody
Definition: actionbase.c:52
PlayerBase
Definition: playerbaseclient.c:1
eAgents
eAgents
Definition: eagents.c:2
vector
Definition: enconvert.c:105
ActionTarget
class ActionTargets ActionTarget
ActionData
Definition: actionbase.c:20
InventoryMode
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
Definition: inventory.c:21
PluginLifespan
void PluginLifespan()
Definition: pluginlifespan.c:45
DayZPlayerConstants
DayZPlayerConstants
defined in C++
Definition: dayzplayer.c:601
CreateOrgan
ItemBase CreateOrgan(PlayerBase player, vector body_pos, string item_to_spawn, string cfg_skinning_organ_class, ItemBase tool)
Definition: actionskinning.c:96
g_Game
DayZGame g_Game
Definition: dayzgame.c:3727
Object
Definition: objecttyped.c:1
UATimeSpent
Definition: actionconstants.c:26
ActionContinuousBaseCB
Definition: actioncontinuousbase.c:1
Bolt_Base
Definition: ammunitionpiles.c:90
array< float >
HandlePlayerBody
void HandlePlayerBody(ActionData action_data)
This section drops all clothes (and attachments) from the dead player before deleting their body.
Definition: actionskinning.c:178
m_Text
protected string m_Text
Definition: actionbase.c:49
GameConstants
Definition: constants.c:612
InventoryTraversalType
InventoryTraversalType
tree traversal type, for more see http://en.wikipedia.org/wiki/Tree_traversal
Definition: gameplay.c:5
m_ConditionItem
ref CCIBase m_ConditionItem
Definition: actionbase.c:55
ActionContinuousBase
Definition: actioncontinuousbase.c:132
CCINonRuined
Definition: ccinonruined.c:1
Math
Definition: enmath.c:6
m_ConditionTarget
ref CCTBase m_ConditionTarget
Definition: actionbase.c:56
Class
Super root of all classes in Enforce script.
Definition: enscript.c:10
m_SpecialtyWeight
protected float m_SpecialtyWeight
Definition: actionbase.c:68
m_StanceMask
protected int m_StanceMask
Definition: actionbase.c:53
Vector
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
EntityAI
Definition: building.c:5
OnFinishProgressClient
override void OnFinishProgressClient(ActionData action_data)
Definition: actionskinning.c:162
CreateConditionComponents
override void CreateConditionComponents()
Definition: actionskinning.c:42
GetCEApi
proto native CEApi GetCEApi()
Get the CE API.