Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
replaceitemwithnewlambdabase.c
Go to the documentation of this file.
1 
5 {
6  EntityAI m_OldItem;
7  string m_NewItemType;
8  protected ref InventoryLocation m_OldLocation;
9  protected ref InventoryLocation m_NewLocation;
10  protected bool m_RemoveFromLocationPassed = false;
11  private bool m_RemoveNetworkObjectInfoPassed = false;
12 
13  void ReplaceItemWithNewLambdaBase(EntityAI old_item, string new_item_type)
14  {
15  m_OldItem = old_item;
16  m_NewItemType = new_item_type;
17  }
18 
19  void OverrideNewLocation(InventoryLocation newLocation)
20  {
21  m_NewLocation = newLocation;
22  }
23 
24  void VerifyItemTypeBySlotType() {}
25 
26  protected bool WantCreateNewEntity()
27  {
28  return m_NewLocation && m_NewItemType != string.Empty;
29  }
30 
31  protected bool CanExecuteLambda()
32  {
33  if (m_OldItem)
34  if (GameInventory.LocationCanRemoveEntity(m_OldLocation))
35  //if (WantCreateNewEntity() GameInventory.LocationTestAddEntityType(m_NewItemType, true, true, false, true))
36  return true;
37  return false;
38  }
39 
43  protected bool PrepareLocations()
44  {
45  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step A) Prepare inventory locations, old_item=" + m_OldItem);
46  m_OldLocation = new InventoryLocation;
47  if (m_OldItem.GetInventory().GetCurrentInventoryLocation(m_OldLocation)) // A.1) store old location
48  {
49  if (m_NewLocation == null)
50  {
51  m_NewLocation = new InventoryLocation;
52  m_NewLocation.CopyLocationFrom(m_OldLocation, true); // A.2) prepare new location from old
53 
54  //setting proper location type for ground pos
55  if (!m_NewLocation.GetParent())
56  {
57  vector m4[4];
58  Math3D.MatrixIdentity4(m4);
59  m4[3] = m_NewLocation.GetPos();
60  string path = "" + CFG_VEHICLESPATH + " " + m_NewItemType + " inherit_rotation";
61  bool keep_rotation = GetGame().ConfigIsExisting(path) && GetGame().ConfigGetInt(path) > 0;
62 
63  if (m_OldLocation.GetType() == InventoryLocationType.GROUND && keep_rotation)
64  {
65  float dir[4];
66  m_OldLocation.GetDir(dir);
67  m_NewLocation.SetGroundEx(null,m_NewLocation.GetPos(),dir);
68  }
69  else
70  {
71  m_NewLocation.SetGround(null,m4);
72  }
73  }
74  }
75  return true;
76  }
77  else
78  Error("[inv] ReplaceItemWithNewLambdaBase Step A.1) failed to get old_item inventory location");
79  return false;
80  }
81 
86  protected void RemoveOldItemFromLocation()
87  {
88  if (!GameInventory.LocationRemoveEntity(m_OldLocation)) // B) remove entity from old inventory location (making it free for new item)
89  {
90  Error("[inv] ReplaceItemWithNewLambdaBase Step B) failed to remove old_item rom current inventory location");
91  m_RemoveFromLocationPassed = false;
92  }
93  Print("[inv] ReplaceItemWithNewLambdaBase Step B) remove OK, loc=" + InventoryLocation.DumpToStringNullSafe(m_OldLocation));
94  m_RemoveFromLocationPassed = true;
95  }
96  protected void UndoRemoveOldItemFromLocation()
97  {
98  if (!GameInventory.LocationAddEntity(m_OldLocation)) // B) undo
99  Error("[inv] ReplaceItemWithNewLambdaBase Step B) failed to undo remove");
100  Print("[inv] ReplaceItemWithNewLambdaBase Step B) undo remove OK, loc=" + InventoryLocation.DumpToStringNullSafe(m_OldLocation));
101  }
102 
107  protected void RemoveNetworkObjectInfo()
108  {
109  GetGame().RemoteObjectTreeDelete(m_OldItem); // C) this forces server to send DeleteObject Message to client. This is needed for preserving the appearance of network operations on client (so that DeleteObject(old) arrives before CreateVehicle(new)). @NOTE: this does not delete the object on server, only it's network representation.
110  // @NOTE: the item is not deleted right now on server, but rather after copying the properties in Step E)
111  m_RemoveNetworkObjectInfoPassed = true;
112  }
113  protected void UndoRemoveNetworkObjectInfo()
114  {
115  GetGame().RemoteObjectTreeCreate(m_OldItem);
116  }
117 
123  protected EntityAI CreateNewEntity()
124  {
125  if (WantCreateNewEntity())
126  {
127  VerifyItemTypeBySlotType();
128  EntityAI new_item;
129 
130  switch (m_NewLocation.GetType())
131  {
132  case InventoryLocationType.GROUND:
133  new_item = EntityAI.Cast(GetGame().CreateObjectEx(m_NewItemType,m_NewLocation.GetPos(),ECE_PLACE_ON_SURFACE|ECE_LOCAL));
134  string path = "" + CFG_VEHICLESPATH + " " + m_NewItemType + " inherit_rotation";
135  bool keep_rotation = GetGame().ConfigIsExisting(path) && GetGame().ConfigGetInt(path) > 0;
136  if (keep_rotation)
137  {
138  new_item.SetOrientation(m_OldItem.GetOrientation()); //this one actually works...debug InventoryLocation
139  }
140  break;
141  case InventoryLocationType.ATTACHMENT:
142  // forces rawlocation in C++ to make location Valid
143  m_NewLocation.SetAttachment(m_NewLocation.GetParent(), null, m_NewLocation.GetSlot());
144  new_item = GameInventory.LocationCreateEntity(m_NewLocation, m_NewItemType, ECE_OBJECT_SWAP, RF_NONE);
145  break;
146  default:
147  new_item = GameInventory.LocationCreateLocalEntity(m_NewLocation, m_NewItemType, ECE_OBJECT_SWAP, RF_NONE);
148  break;
149  }
150 
151  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step D) Created new new_item=" + new_item);
152  if (new_item)
153  {
154  return new_item;
155  }
156  else
157  {
158  return null;
159 
160  /*InventoryLocation backupLocation = new InventoryLocation;
161  vector mtx[4];
162  Math3D.MatrixIdentity4(mtx);
163  mtx[3] = m_OldItem.GetPosition();
164  backupLocation.SetGround(null, mtx);
165  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step D) plan B - creating=" + m_NewItemType + " at bkp loc=" + backupLocation.DumpToString() + ", but failed");
166  new_item = GameInventory.LocationCreateLocalEntity(backupLocation, m_NewItemType,ECE_OBJECT_SWAP,RF_NONE); // create LOCAL new one on ground
167  if (!new_item)
168  {
169  Error("[inv] ReplaceItemWithNewLambdaBase Step D) plan B - wanted to create=" + m_NewItemType + " at bkp loc=" + backupLocation.DumpToString() + ", but failed");
170  return null;
171  }
172  return new_item;*/
173  }
174  }
175 
176  // user did not asked for new entity
177  return null;
178  }
179 
185  void CopyOldPropertiesToNew(notnull EntityAI old_item, EntityAI new_item)
186  {
187  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step E) Copying props " + old_item + " --> " + new_item);
188  }
189 
193  protected void DeleteOldEntity()
194  {
195  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step F) delete old item=" + m_OldItem);
196  m_OldItem.DeleteSafe();
197  }
198 
204  protected void CreateNetworkObjectInfo(EntityAI new_item)
205  {
206  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step G) CreateNetworkObjectInfo =" + new_item);
207  if (new_item)
208  GetGame().RemoteObjectTreeCreate(new_item); // G) this forces server to send CreateVehicle Message to client. This is needed for preserving the appearance of network operations on client (so that DeleteObject(old) arrives before CreateVehicle(new)). @NOTE: this does not delete the object on server, only it's network representation.
209  }
210 
216  protected void OnSuccess(EntityAI new_item)
217  {
218  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[inv] ReplaceItemWithNewLambdaBase Step H) OnSuccess=" + new_item);
219  }
220 
226  protected void OnAbort()
227  {
228  Print("Error [inv] ReplaceItemWithNewLambdaBase OnAbort");
229  }
230 
231  void Execute(HumanInventoryWithFSM fsm_to_notify = null)
232  {
233  int t = GetGame().GetTime();
234  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[syncinv] t=" + t + " lambda.Execute start ");
235 
236  // A) init
237  bool prepared = PrepareLocations();
238 
239  if (prepared && CanExecuteLambda())
240  {
241  // B) rm old (and delete on client)
242  RemoveOldItemFromLocation();
243  if (!m_RemoveFromLocationPassed)
244  {
245  Error("[inv] ReplaceItemWithNewLambdaBase Step B) ABORT - failed while rm old item from loc=" + InventoryLocation.DumpToStringNullSafe(m_OldLocation));
246 
247  if (fsm_to_notify)
248  fsm_to_notify.ProcessHandAbortEvent(new HandEventHumanCommandActionAborted(fsm_to_notify.GetManOwner()));
249  OnAbort();
250  return;
251  }
252 
253  // C) rm NetworkObjectInfo from old item (+ send delete object tree to clients)
254  RemoveNetworkObjectInfo();
255 
256  // D) mk new in place of old
257  EntityAI new_item = CreateNewEntity();
258  if (WantCreateNewEntity() && new_item == null)
259  {
260  //Error("[inv] ReplaceItemWithNewLambdaBase Step D) ABORT - wanted to create=" + m_NewItemType + " at loc=" + m_NewLocation.DumpToString() + ", but failed");
261  Print("Error [inv] ReplaceItemWithNewLambdaBase Step D) ABORT - wanted to create=" + m_NewItemType + " at loc=" + InventoryLocation.DumpToStringNullSafe(m_NewLocation) + ", but failed");
262  if (m_RemoveFromLocationPassed)
263  UndoRemoveOldItemFromLocation();
264  if (m_RemoveNetworkObjectInfoPassed)
265  UndoRemoveNetworkObjectInfo();
266 
267  OnAbort();
268  if (fsm_to_notify)
269  fsm_to_notify.ProcessHandAbortEvent(new HandEventHumanCommandActionAborted(fsm_to_notify.GetManOwner()));
270  return;
271  }
272 
273  // E) cpy props
274  CopyOldPropertiesToNew(m_OldItem, new_item);
275 
276  // F) del old
277  DeleteOldEntity();
278 
279  // G) mk new NetworkObjectInfo
280  CreateNetworkObjectInfo(new_item);
281 
282  // H) notification
283  OnSuccess(new_item);
284  }
285  else
286  {
287  Print("[syncinv] warning, lambda cannot be executed, skipping!");
288  if (fsm_to_notify)
289  fsm_to_notify.ProcessHandAbortEvent(new HandEventHumanCommandActionAborted(fsm_to_notify.GetManOwner()));
290  OnAbort();
291  return;
292  }
293  int te = GetGame().GetTime();
294  int dt = te - t;
295  if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[syncinv] te=" + te + " lambda.Execute end, exec time=" + dt);
296  }
297 
298  string DumpToString()
299  {
300  string s = "{ old=" + m_OldItem + " newType=" + m_NewItemType + "}";
301  return s;
302  }
303 };
304 
305 
307 {
308 };
GetGame
proto native CGame GetGame()
Error
void Error(string err)
Messagebox with error message.
Definition: endebug.c:90
LogManager
Definition: debug.c:734
Print
proto void Print(void var)
Prints content of variable to console/log.
InventoryLocation
InventoryLocation.
Definition: inventorylocation.c:27
ECE_PLACE_ON_SURFACE
const int ECE_PLACE_ON_SURFACE
Definition: centraleconomy.c:37
RF_NONE
const int RF_NONE
Definition: centraleconomy.c:45
ECE_OBJECT_SWAP
const int ECE_OBJECT_SWAP
Definition: centraleconomy.c:38
HumanInventoryWithFSM
HumanInventory... with FSM (synchronous, no anims)
Definition: humaninventorywithfsm.c:5
vector
Definition: enconvert.c:105
CFG_VEHICLESPATH
const string CFG_VEHICLESPATH
Definition: constants.c:209
InventoryLocationType
InventoryLocationType
types of Inventory Location
Definition: inventorylocation.c:3
hndDebugPrint
void hndDebugPrint(string s)
Definition: handfsm.c:1
ECE_LOCAL
const int ECE_LOCAL
Definition: centraleconomy.c:24
ReplaceItemWithNewLambdaBase
base class for transformation operations (creating one item from another)
Definition: replaceitemwithnewlambdabase.c:4
EntityAI
Definition: building.c:5
Math3D
Definition: enmath3d.c:27
GameInventory
script counterpart to engine's class Inventory
Definition: inventory.c:78
path
string path
Definition: optionselectormultistate.c:135
ItemInventory
Definition: replaceitemwithnewlambdabase.c:306