OpenClonk
C4ObjectCommand.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Logic for C4Object: Commands */
19 
20 #include "C4Include.h"
22 #include "object/C4Object.h"
23 
24 #include "object/C4Command.h"
25 #include "object/C4Def.h"
26 #include "object/C4ObjectCom.h"
27 
28 
30 {
31  C4Command *pNext;
32  while (Command)
33  {
34  pNext=Command->Next;
35  if (!Command->iExec)
36  delete Command;
37  else
38  Command->iExec = 2;
39  Command=pNext;
40  }
41 }
42 
44 {
45  C4Command *pCom,*pNext;
46  for (pCom=Command; pCom; pCom=pNext)
47  {
48  // Last one to clear
49  if (pCom==pUntil) pNext=nullptr;
50  // Next one to clear after this
51  else pNext=pCom->Next;
52  Command=pCom->Next;
53  if (!pCom->iExec)
54  delete pCom;
55  else
56  pCom->iExec = 2;
57  }
58 }
59 
60 bool C4Object::AddCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int32_t iTy,
61  int32_t iUpdateInterval, C4Object *pTarget2,
62  bool fInitEvaluation, C4Value iData, bool fAppend,
63  int32_t iRetries, C4String *szText, int32_t iBaseMode)
64 {
65  // Command stack size safety
66  const int32_t MaxCommandStack = 35;
67  C4Command *pCom,*pLast; int32_t iCommands;
68  for (pCom=Command,iCommands=0; pCom; pCom=pCom->Next,iCommands++) {}
69  if (iCommands>=MaxCommandStack) return false;
70  // Valid command safety
71  if (!Inside(iCommand,C4CMD_First,C4CMD_Last)) return false;
72  // Allocate and set new command
73  if (!(pCom=new C4Command)) return false;
74  pCom->Set(iCommand,this,pTarget,iTx,iTy,pTarget2,iData,
75  iUpdateInterval,!fInitEvaluation,iRetries,szText,iBaseMode);
76  // Append to bottom of stack
77  if (fAppend)
78  {
79  for (pLast=Command; pLast && pLast->Next; pLast=pLast->Next) {}
80  if (pLast) pLast->Next=pCom;
81  else Command=pCom;
82  }
83  // Add to top of command stack
84  else
85  {
86  pCom->Next=Command;
87  Command=pCom;
88  }
89  // Success
90  return true;
91 }
92 
93 void C4Object::SetCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int32_t iTy,
94  C4Object *pTarget2, bool fControl, C4Value iData,
95  int32_t iRetries, C4String *szText)
96 {
97  // Clear stack
98  ClearCommands();
99  // Close menu
100  if (fControl)
101  if (!CloseMenu(false)) return;
102  // Script overload
103  if (fControl)
105  pTarget,
106  iTx,
107  iTy,
108  pTarget2,
109  iData)))
110  return;
111  // Inside vehicle control overload
112  if (Contained)
114  {
117  pTarget,
118  iTx,
119  iTy,
120  pTarget2,
121  iData,
122  this)))
123  return;
124  }
125  // Outside vehicle control overload
126  if (GetProcedure()==DFA_PUSH)
128  {
131  pTarget,
132  iTx,
133  iTy,
134  pTarget2,
135  iData)))
136  return;
137  }
138  // Add new command
139  AddCommand(iCommand,pTarget,iTx,iTy,0,pTarget2,true,iData,false,iRetries,szText,C4CMD_Mode_Base);
140 }
141 
142 C4Command *C4Object::FindCommand(int32_t iCommandType) const
143 {
144  // seek all commands
145  for (C4Command *pCom = Command; pCom; pCom=pCom->Next)
146  if (pCom->Command == iCommandType) return pCom;
147  // nothing found
148  return nullptr;
149 }
150 
152 {
153  // Execute first command
154  if (Command) Command->Execute();
155  // Command finished: engine call
156  if (Command && Command->Finished)
158  // Clear finished commands
160  // Done
161  return true;
162 }
163 
164 bool C4Object::PutAwayUnusedObject(C4Object *pToMakeRoomForObject) // Called by GetTryEnter
165 {
166  // get unused object
167  C4Object *pUnusedObject;
168  C4AulFunc *pFnObj2Drop = GetFunc(PSF_GetObject2Drop);
169  if (pFnObj2Drop)
170  pUnusedObject = pFnObj2Drop->Exec(this, &C4AulParSet(pToMakeRoomForObject)).getObj();
171  else
172  {
173  // is there any unused object to put away?
174  if (!Contents.GetLastObject()) return false;
175  // defaultly, it's the last object in the list
176  // (contents list cannot have invalid status-objects)
177  pUnusedObject = Contents.GetLastObject();
178  }
179  // no object to put away? fail
180  if (!pUnusedObject) return false;
181  // grabbing something?
182  bool fPushing = (GetProcedure()==DFA_PUSH);
183  if (fPushing)
184  // try to put it in there
185  if (ObjectComPut(this, Action.Target, pUnusedObject))
186  return true;
187  // in container? put in there
188  if (Contained)
189  {
190  // try to put it in directly
191  // note that this works too, if an object is grabbed inside the container
192  if (ObjectComPut(this, Contained, pUnusedObject))
193  return true;
194  // now putting didn't work - drop it outside
195  AddCommand(C4CMD_Drop, pUnusedObject);
197  return true;
198  }
199  else
200  // if uncontained, simply try to drop it
201  // if this doesn't work, it won't ever
202  return !!ObjectComDrop(this, pUnusedObject);
203 }
const char * CommandName(int32_t iCommand)
Definition: C4Command.cpp:46
@ C4CMD_Drop
Definition: C4Command.h:40
@ C4CMD_Exit
Definition: C4Command.h:32
const int32_t C4CMD_Mode_Base
Definition: C4Command.h:60
const int32_t C4CMD_Last
Definition: C4Command.h:57
const int32_t C4CMD_First
Definition: C4Command.h:56
const int32_t C4D_VehicleControl_Outside
Definition: C4Def.h:77
const int32_t C4D_VehicleControl_Inside
Definition: C4Def.h:78
#define PSF_ControlCommand
Definition: C4GameScript.h:70
#define PSF_GetObject2Drop
Definition: C4GameScript.h:87
#define PSF_ControlCommandFinished
Definition: C4GameScript.h:71
bool ObjectComPut(C4Object *cObj, C4Object *pTarget, C4Object *pThing)
bool ObjectComDrop(C4Object *cObj, C4Object *pThing)
@ DFA_PUSH
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43
C4ObjectPtr Target
Definition: C4Object.h:87
C4Value Exec(C4PropList *p=nullptr, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4AulFunc.h:72
C4Value Data
Definition: C4Command.h:85
int32_t Finished
Definition: C4Command.h:87
C4Value Tx
Definition: C4Command.h:82
C4ObjectPtr Target
Definition: C4Command.h:84
int32_t iExec
Definition: C4Command.h:91
void Set(int32_t iCommand, C4Object *pObj, C4Object *pTarget, C4Value iTx, int32_t iTy, C4Object *pTarget2, C4Value iData, int32_t iUpdateInterval, bool fEvaluated, int32_t iRetries, C4String *szText, int32_t iBaseMode)
Definition: C4Command.cpp:1810
C4ObjectPtr Target2
Definition: C4Command.h:84
void Execute()
Definition: C4Command.cpp:1295
int32_t Ty
Definition: C4Command.h:83
int32_t Command
Definition: C4Command.h:81
C4Command * Next
Definition: C4Command.h:90
int32_t VehicleControl
Definition: C4Def.h:133
void ClearCommand(C4Command *pUntil)
bool PutAwayUnusedObject(C4Object *pToMakeRoomForObject)
bool AddCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int32_t iTy=0, int32_t iUpdateInterval=0, C4Object *pTarget2=nullptr, bool fInitEvaluation=true, C4Value iData=C4VNull, bool fAppend=false, int32_t iRetries=0, C4String *szText=nullptr, int32_t iBaseMode=0)
void SetCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int32_t iTy=0, C4Object *pTarget2=nullptr, bool fControl=false, C4Value iData=C4VNull, int32_t iRetries=0, C4String *szText=nullptr)
void ClearCommands()
int32_t GetProcedure() const
C4Command * Command
Definition: C4Object.h:165
int32_t Controller
Definition: C4Object.h:109
bool ExecuteCommand()
bool CloseMenu(bool fForce)
C4Command * FindCommand(int32_t iCommandType) const
C4NotifyingObjectList Contents
Definition: C4Object.h:151
C4ObjectPtr Contained
Definition: C4Object.h:142
C4Action Action
Definition: C4Object.h:145
C4Def * Def
Definition: C4Object.h:141
C4Object * GetLastObject() const
Definition: C4ObjectList.h:142
C4AulFunc * GetFunc(C4PropertyName k) const
Definition: C4PropList.h:109
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:114
C4Object * getObj() const
Definition: C4Value.cpp:68