OpenClonk
C4Command Class Reference

#include <C4Command.h>

Collaboration diagram for C4Command:
[legend]

Public Member Functions

 C4Command ()
 
 ~C4Command ()
 
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)
 
void Clear ()
 
void Execute ()
 
void ClearPointers (C4Object *pObj)
 
void Default ()
 
void Denumerate (C4ValueNumbers *)
 
void CompileFunc (StdCompiler *pComp, C4ValueNumbers *)
 

Public Attributes

C4ObjectcObj
 
int32_t Command
 
C4Value Tx
 
int32_t Ty
 
C4ObjectPtr Target
 
C4ObjectPtr Target2
 
C4Value Data
 
int32_t UpdateInterval
 
int32_t Evaluated
 
int32_t PathChecked
 
int32_t Finished
 
int32_t Failures
 
int32_t Retries
 
int32_t Permit
 
C4StringText
 
C4CommandNext
 
int32_t iExec
 
int32_t BaseMode
 

Protected Member Functions

void Call ()
 
void Home ()
 
void Retry ()
 
void Fail (const char *szFailMessage=nullptr)
 
void Acquire ()
 
void Sell ()
 
void Buy ()
 
void Attack ()
 
void Transfer ()
 
void Finish (bool fSuccess=false, const char *szFailMessage=nullptr)
 
void Follow ()
 
void MoveTo ()
 
void Enter ()
 
void Exit ()
 
void Grab ()
 
void UnGrab ()
 
void Throw ()
 
void Jump ()
 
void Wait ()
 
void Take ()
 
void Take2 ()
 
bool GetTryEnter ()
 
void Get ()
 
void Put ()
 
void Drop ()
 
void Dig ()
 
void Activate ()
 
void PushTo ()
 
int32_t CallFailed ()
 
bool JumpControl ()
 
bool FlightControl ()
 
bool InitEvaluation ()
 
int32_t GetExpGain ()
 

Detailed Description

Definition at line 74 of file C4Command.h.

Constructor & Destructor Documentation

◆ C4Command()

C4Command::C4Command ( )

Definition at line 197 of file C4Command.cpp.

198 {
199  Default();
200 }
void Default()
Definition: C4Command.cpp:207

References Default().

Here is the call graph for this function:

◆ ~C4Command()

C4Command::~C4Command ( )

Definition at line 202 of file C4Command.cpp.

203 {
204  Clear();
205 }
void Clear()
Definition: C4Command.cpp:1456

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ Acquire()

void C4Command::Acquire ( )
protected

Definition at line 1655 of file C4Command.cpp.

1656 {
1657 
1658  // No type to acquire specified: fail
1659  if (!Data) { Finish(); return; }
1660 
1661  // Target material in inventory: done
1662  if (cObj->Contents.Find(Data.getDef()))
1663  { Finish(true); return; }
1664 
1665  // script overload
1666  int32_t scriptresult = cObj->Call(PSF_ControlCommandAcquire, &C4AulParSet(Target, Tx, Ty, Target2, Data)).getInt ();
1667 
1668  // script call might have deleted object
1669  if (!cObj->Status) return;
1670  if (1 == scriptresult) return;
1671  if (2 == scriptresult)
1672  { Finish(true); return; }
1673  if (3 == scriptresult)
1674  { Finish(); return; }
1675 
1676  // Find available material
1677  C4Object *pMaterial=nullptr;
1678  // Next closest
1679  while ((pMaterial = Game.FindObject(Data.getDef(),cObj->GetX(),cObj->GetY(),-1,-1,OCF_Available,pMaterial)))
1680  // Object is not in container to be ignored
1681  if (!Target2 || pMaterial->Contained!=Target2)
1682  // Object is near enough
1683  if (Inside(cObj->GetX()-pMaterial->GetX(),-Tx._getInt(),+Tx._getInt()))
1684  if (Inside(cObj->GetY()-pMaterial->GetY(),-Ty,+Ty))
1685  // Must be complete
1686  if (pMaterial->OCF & OCF_FullCon)
1687  // Doesn't burn
1688  if (!pMaterial->GetOnFire())
1689  // We found one
1690  break;
1691 
1692  // Available material found: get material
1693  if (pMaterial)
1694  { cObj->AddCommand(C4CMD_Get,pMaterial,0,0,40); return; }
1695 
1696  // No available material found: buy material
1697  // This command will fail immediately if buying at bases is not possible
1698  // - but the command should be created anyway because it might be overloaded
1699  cObj->AddCommand(C4CMD_Buy,nullptr,0,0,100,nullptr,true,Data,false,0,nullptr,C4CMD_Mode_Sub);
1700 
1701 }
@ C4CMD_Get
Definition: C4Command.h:38
@ C4CMD_Buy
Definition: C4Command.h:46
const int32_t C4CMD_Mode_Sub
Definition: C4Command.h:62
const uint32_t OCF_Available
Definition: C4Constants.h:101
const uint32_t OCF_FullCon
Definition: C4Constants.h:85
#define PSF_ControlCommandAcquire
Definition: C4GameScript.h:163
C4Game Game
Definition: C4Globals.cpp:52
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43
C4Value Data
Definition: C4Command.h:85
void Finish(bool fSuccess=false, const char *szFailMessage=nullptr)
Definition: C4Command.cpp:1374
C4Value Tx
Definition: C4Command.h:82
C4ObjectPtr Target
Definition: C4Command.h:84
C4ObjectPtr Target2
Definition: C4Command.h:84
C4Object * cObj
Definition: C4Command.h:80
int32_t Ty
Definition: C4Command.h:83
C4Object * FindObject(C4Def *def, int32_t x=0, int32_t y=0, int32_t wdt=0, int32_t hgt=0, DWORD ocf=OCF_All, C4Object *find_next=nullptr)
Definition: C4Game.cpp:1456
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)
int32_t GetX() const
Definition: C4Object.h:285
uint32_t OCF
Definition: C4Object.h:132
bool GetOnFire() const
Definition: C4Object.h:302
int32_t GetY() const
Definition: C4Object.h:286
C4NotifyingObjectList Contents
Definition: C4Object.h:151
C4ObjectPtr Contained
Definition: C4Object.h:142
C4Object * Find(C4Def *def, int owner=ANY_OWNER, DWORD dwOCF=OCF_All)
int32_t Status
Definition: C4PropList.h:173
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:114
int32_t getInt() const
Definition: C4Value.h:112
int32_t _getInt() const
Definition: C4Value.h:122
C4Def * getDef() const
Definition: C4Value.cpp:78

References C4Value::_getInt(), C4Object::AddCommand(), C4CMD_Buy, C4CMD_Get, C4CMD_Mode_Sub, C4PropList::Call(), cObj, C4Object::Contained, C4Object::Contents, Data, C4ObjectList::Find(), C4Game::FindObject(), Finish(), Game, C4Value::getDef(), C4Value::getInt(), C4Object::GetOnFire(), C4Object::GetX(), C4Object::GetY(), Inside(), C4Object::OCF, OCF_Available, OCF_FullCon, PSF_ControlCommandAcquire, C4PropList::Status, Target, Target2, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Activate()

void C4Command::Activate ( )
protected

Definition at line 1105 of file C4Command.cpp.

1106 {
1107 
1108  // Container specified, but no Target & no type: open activate menu for container
1109  if (Target2 && !Target && !Data)
1110  {
1112  Finish(true);
1113  return;
1114  }
1115 
1116  // Target object specified & outside: success
1117  if (Target)
1118  if (!Target->Contained)
1119  { Finish(true); return; }
1120 
1121  // No container specified: determine container by target object
1122  if (!Target2)
1123  if (Target)
1125 
1126  // No container specified: fail
1127  if (!Target2) { Finish(); return; }
1128 
1129  // Digging: stop
1131 
1132  // In container
1133  if (cObj->Contained==Target2)
1134  {
1135  for (Tx.SetInt(Data ? std::max<int32_t>(Tx._getInt(),1) : 1); Tx._getInt(); --Tx)
1136  {
1137  // If not specified get object from target contents by type
1138  // Find first object requested id that has no command exit yet
1139  if (!Target)
1140  for (C4Object *pObj : Target2->Contents)
1141  if (pObj->Status && (pObj->Def==Data.getDef()))
1142  if (!pObj->Command || (pObj->Command->Command!=C4CMD_Exit))
1143  { Target=pObj; break; }
1144  // No target
1145  if (!Target) { Finish(); return; }
1146 
1147  // Thing in own container (target2)
1148  if (Target->Contained!=Target2) { Finish(); return; }
1149 
1150  // Activate object to exit
1153  Target = nullptr;
1154  }
1155 
1156  Finish(true); return;
1157  }
1158 
1159  // Leave own container
1160  if (cObj->Contained)
1161  { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
1162 
1163  // Target container has entrance: enter
1164  if (Target2->OCF & OCF_Entrance)
1165  { cObj->AddCommand(C4CMD_Enter,Target2,0,0,50); return; }
1166 
1167  // Can't get to target due to target container: fail
1168  Finish();
1169 
1170 }
@ C4CMD_Enter
Definition: C4Command.h:31
@ C4CMD_Exit
Definition: C4Command.h:32
const uint32_t OCF_Entrance
Definition: C4Constants.h:90
bool ObjectComStop(C4Object *cObj)
@ C4MN_Activate
Definition: C4ObjectMenu.h:33
@ DFA_DIG
int32_t Command
Definition: C4Command.h:81
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)
int32_t GetProcedure() const
C4Command * Command
Definition: C4Object.h:165
bool ActivateMenu(int32_t iMenu, int32_t iMenuSelect=0, int32_t iMenuData=0, int32_t iMenuPosition=0, C4Object *pTarget=nullptr)
int32_t Controller
Definition: C4Object.h:109
C4Def * Def
Definition: C4Object.h:141
void SetInt(int32_t i)
Definition: C4Value.h:136

References C4Value::_getInt(), C4Object::ActivateMenu(), C4Object::AddCommand(), C4CMD_Enter, C4CMD_Exit, C4MN_Activate, cObj, Command, C4Object::Command, C4Object::Contained, C4Object::Contents, C4Object::Controller, Data, C4Object::Def, DFA_DIG, Finish(), C4Value::getDef(), C4Object::GetProcedure(), ObjectComStop(), C4Object::OCF, OCF_Entrance, C4Object::SetCommand(), C4Value::SetInt(), C4PropList::Status, Target, Target2, and Tx.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Attack()

void C4Command::Attack ( )
protected

Definition at line 1600 of file C4Command.cpp.

1601 {
1602 
1603  // No target: failure
1604  if (!Target) { Finish(); return; }
1605 
1606  // Target is crew member
1607  if (Target->OCF & OCF_CrewMember)
1608  {
1609 
1610  // Throw projectile at target
1611  for (C4Object *pProjectile : cObj->Contents)
1612  if (pProjectile->Def->Projectile)
1613  {
1614  // Add throw command
1615  cObj->AddCommand(C4CMD_Throw,pProjectile,Target->GetX(),Target->GetY(),2);
1616  return;
1617  }
1618 
1619  // Follow containment
1620  if (cObj->Contained!=Target->Contained)
1621  {
1622  // Exit
1623  if (cObj->Contained) cObj->AddCommand(C4CMD_Exit,nullptr,0,0,10);
1624  // Enter
1625  else cObj->AddCommand(C4CMD_Enter,Target->Contained,0,0,10);
1626  return;
1627  }
1628 
1629  // Move to target
1630  cObj->AddCommand(C4CMD_MoveTo,nullptr,Target->GetX(),Target->GetY(),10);
1631  return;
1632 
1633  }
1634 
1635  // For now, attack crew members only
1636  else
1637  {
1638  // Success, target might be no crew member due to that is has been killed
1639  Finish(true);
1640  return;
1641  }
1642 
1643 }
@ C4CMD_MoveTo
Definition: C4Command.h:30
@ C4CMD_Throw
Definition: C4Command.h:34
const uint32_t OCF_CrewMember
Definition: C4Constants.h:97
int32_t Projectile
Definition: C4Def.h:131

References C4Object::AddCommand(), C4CMD_Enter, C4CMD_Exit, C4CMD_MoveTo, C4CMD_Throw, cObj, C4Object::Contained, C4Object::Contents, C4Object::Def, Finish(), C4Object::GetX(), C4Object::GetY(), C4Object::OCF, OCF_CrewMember, C4Def::Projectile, and Target.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Buy()

void C4Command::Buy ( )
protected

Definition at line 1645 of file C4Command.cpp.

1646 {
1647  Finish();
1648 }

References Finish().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Call()

void C4Command::Call ( )
protected

Definition at line 1833 of file C4Command.cpp.

1834 {
1835  // No function name: fail
1836  if (!Text || !Text->GetCStr() || !Text->GetCStr()[0]) { Finish(); return; }
1837  // No target object: fail
1838  if (!Target) { Finish(); return; }
1839  // Done: success
1840  Finish(true);
1841  // Object call FIXME:use c4string-api
1843  // Extreme caution notice: the script call might do just about anything
1844  // including clearing all commands (including this) i.e. through a call
1845  // to SetCommand. Thus, we must not do anything in this command anymore
1846  // after the script call (even the Finish has to be called before).
1847  // The Finish call being misled to the freshly created Build command (by
1848  // chance, the this-pointer was simply crap at the time) was reason for
1849  // the latest sync losses in 4.62.
1850 }
C4String * Text
Definition: C4Command.h:89
const char * GetCStr() const
Definition: C4StringTable.h:49

References C4PropList::Call(), cObj, Finish(), C4String::GetCStr(), Target, Target2, Text, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CallFailed()

int32_t C4Command::CallFailed ( )
protected

Definition at line 1918 of file C4Command.cpp.

1919 {
1920  // No function name or no target object: cannot call fail-function
1921  if (!Text || !Text->GetCStr() || !Text->GetCStr()[0] || !Target) return 0;
1922  // Compose fail-function name
1923  char szFunctionFailed[1024+1]; sprintf(szFunctionFailed,"~%sFailed",Text->GetCStr());
1924  // Call failed-function
1925  return Target->Call(szFunctionFailed,&C4AulParSet(cObj, Tx, Ty, Target2))._getInt();
1926  // Extreme caution notice: the script call might do just about anything
1927  // including clearing all commands (including this) i.e. through a call
1928  // to SetCommand. Thus, we must not do anything in this command anymore
1929  // after the script call.
1930 }
#define sprintf
Definition: Standard.h:162

References C4Value::_getInt(), C4PropList::Call(), cObj, C4String::GetCStr(), sprintf, Target, Target2, Text, Tx, and Ty.

Referenced by Fail().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void C4Command::Clear ( )

Definition at line 1456 of file C4Command.cpp.

1457 {
1459  cObj=nullptr;
1460  Evaluated=false;
1461  PathChecked=false;
1462  Tx=C4VNull;
1463  Ty=0;
1464  Target=Target2=nullptr;
1465  UpdateInterval=0;
1466  if (Text) Text->DecRef();
1467  Text=nullptr;
1469 }
@ C4CMD_None
Definition: C4Command.h:28
const int32_t C4CMD_Mode_SilentSub
Definition: C4Command.h:59
const C4Value C4VNull
Definition: C4Value.cpp:30
int32_t Evaluated
Definition: C4Command.h:87
int32_t UpdateInterval
Definition: C4Command.h:86
int32_t PathChecked
Definition: C4Command.h:87
int32_t BaseMode
Definition: C4Command.h:92
void DecRef()
Definition: C4StringTable.h:28

References BaseMode, C4CMD_Mode_SilentSub, C4CMD_None, C4VNull, cObj, Command, C4RefCnt::DecRef(), Evaluated, PathChecked, Target, Target2, Text, Tx, Ty, and UpdateInterval.

Referenced by Set(), and ~C4Command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearPointers()

void C4Command::ClearPointers ( C4Object pObj)

Definition at line 1288 of file C4Command.cpp.

1289 {
1290  if (cObj==pObj) cObj=nullptr;
1291  if (Target==pObj) Target=nullptr;
1292  if (Target2==pObj) Target2=nullptr;
1293 }

References cObj, Target, and Target2.

Referenced by C4Object::ClearPointers().

Here is the caller graph for this function:

◆ CompileFunc()

void C4Command::CompileFunc ( StdCompiler pComp,
C4ValueNumbers numbers 
)

Definition at line 1852 of file C4Command.cpp.

1853 {
1854  // Version
1855  int32_t iVersion = 0;
1856  if (pComp->Separator(StdCompiler::SEP_DOLLAR))
1857  {
1858  iVersion = 1;
1859  pComp->Value(mkIntPackAdapt(iVersion));
1861  }
1862  else
1863  pComp->NoSeparator();
1864  // Command name
1865  pComp->Value(mkEnumAdaptT<uint8_t>(Command, EnumAdaptCommandEntries));
1867  // Target X/Y
1868  pComp->Value(mkParAdapt(Tx, numbers)); pComp->Separator(StdCompiler::SEP_SEP);
1870  // Target
1871  pComp->Value(Target); pComp->Separator(StdCompiler::SEP_SEP);
1872  pComp->Value(Target2); pComp->Separator(StdCompiler::SEP_SEP);
1873  // Data
1874  pComp->Value(mkParAdapt(Data, numbers)); pComp->Separator(StdCompiler::SEP_SEP);
1875  // Update interval
1877  // Flags
1881  // Retries
1885  // Base mode
1886  if (iVersion > 0)
1887  {
1889  }
1890  // Text
1891  StdStrBuf TextBuf;
1892  if (pComp->isSerializer())
1893  {
1894  if (Text)
1895  TextBuf.Ref(Text->GetData());
1896  else
1897  TextBuf.Ref("0");
1898  }
1899  pComp->Value(mkParAdapt(TextBuf, StdCompiler::RCT_All));
1900  if (pComp->isDeserializer())
1901  {
1902  if (Text)
1903  Text->DecRef();
1904  if (TextBuf == "0")
1905  { Text = nullptr; }
1906  else
1907  { Text = Strings.RegString(TextBuf); Text->IncRef(); }
1908  }
1909 }
StdEnumAdapt< int32_t >::Entry EnumAdaptCommandEntries[C4CMD_Last - C4CMD_First+2]
Definition: C4Command.cpp:44
C4StringTable Strings
Definition: C4Globals.cpp:42
StdIntPackAdapt< T > mkIntPackAdapt(T &rVal)
Definition: StdAdaptors.h:791
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
int32_t Failures
Definition: C4Command.h:88
int32_t Finished
Definition: C4Command.h:87
int32_t Retries
Definition: C4Command.h:88
int32_t Permit
Definition: C4Command.h:88
void IncRef()
Definition: C4StringTable.h:27
StdStrBuf GetData() const
Definition: C4StringTable.h:50
C4String * RegString(StdStrBuf String)
virtual bool Separator(Sep eSep=SEP_SEP)
Definition: StdCompiler.h:119
virtual void NoSeparator()
Definition: StdCompiler.h:120
void Value(const T &rStruct)
Definition: StdCompiler.h:161
bool isSerializer()
Definition: StdCompiler.h:54
virtual bool isDeserializer()
Definition: StdCompiler.h:53
void Ref(const char *pnData)
Definition: StdBuf.h:455

References BaseMode, Command, Data, C4RefCnt::DecRef(), EnumAdaptCommandEntries, Evaluated, Failures, Finished, C4String::GetData(), C4RefCnt::IncRef(), StdCompiler::isDeserializer(), StdCompiler::isSerializer(), mkIntPackAdapt(), mkParAdapt(), StdCompiler::NoSeparator(), PathChecked, Permit, StdCompiler::RCT_All, StdStrBuf::Ref(), C4StringTable::RegString(), Retries, StdCompiler::SEP_DOLLAR, StdCompiler::SEP_SEP, StdCompiler::Separator(), Strings, Target, Target2, Text, Tx, Ty, UpdateInterval, and StdCompiler::Value().

Here is the call graph for this function:

◆ Default()

void C4Command::Default ( )

Definition at line 207 of file C4Command.cpp.

208 {
210  cObj=nullptr;
211  Evaluated=false;
212  PathChecked=false;
213  Finished=false;
214  Tx=C4VNull;
215  Ty=0;
216  Target=Target2=nullptr;
217  Data.Set0();
218  UpdateInterval=0;
219  Failures=0;
220  Retries=0;
221  Permit=0;
222  Text=nullptr;
223  Next=nullptr;
224  iExec=0;
226 }
int32_t iExec
Definition: C4Command.h:91
C4Command * Next
Definition: C4Command.h:90
void Set0()
Definition: C4Value.h:332

References BaseMode, C4CMD_Mode_SilentSub, C4CMD_None, C4VNull, cObj, Command, Data, Evaluated, Failures, Finished, iExec, Next, PathChecked, Permit, Retries, C4Value::Set0(), Target, Target2, Text, Tx, Ty, and UpdateInterval.

Referenced by C4Command(), and Set().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Denumerate()

void C4Command::Denumerate ( C4ValueNumbers numbers)

Definition at line 1911 of file C4Command.cpp.

1912 {
1915  Tx.Denumerate(numbers);
1916 }
void DenumeratePointers()
Definition: C4ObjectPtr.cpp:49
void Denumerate(C4ValueNumbers *)
Definition: C4Value.cpp:251

References C4Value::Denumerate(), C4ObjectPtr::DenumeratePointers(), Target, Target2, and Tx.

Here is the call graph for this function:

◆ Dig()

void C4Command::Dig ( )
protected

Definition at line 454 of file C4Command.cpp.

455 {
456  // Current object and target coordinates
457  int32_t cx,cy,tx,ty;
458  cx=cObj->GetX(); cy=cObj->GetY();
459  tx=Tx._getInt(); ty=Ty+cObj->Shape.GetY() + 3; // Target coordinates are bottom center
460  bool fDigOutMaterial=Data.getBool();
461 
462  // Grabbing: let go
463  if (cObj->GetProcedure()==DFA_PUSH)
464  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
465 
466  // If contained: exit
467  if (cObj->Contained)
468  { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
469 
470  // Scaling or hangling: let go
472  ObjectComLetGo(cObj,(cObj->Action.Dir==DIR_Left) ? +1 : -1);
473 
474  // Determine move-to range
475  int32_t iMoveToRange = MoveToRange;
476  if (cObj->Def->MoveToRange > 0) iMoveToRange = cObj->Def->MoveToRange;
477 
478  // Target reached: success
479  if (Inside(cx - tx, -iMoveToRange, +iMoveToRange)
480  && Inside(cy - ty, -iMoveToRange, +iMoveToRange))
481  {
483  Finish(true); return;
484  }
485 
486  // Can start digging only from walk
487  if (cObj->GetProcedure()!=DFA_DIG)
488  if (cObj->GetProcedure()!=DFA_WALK)
489  // Continue trying (assume currently in flight)
490  return;
491 
492  // Start digging
493  if (cObj->GetProcedure()!=DFA_DIG)
494  if (!ObjectComDig(cObj))
495  { Finish(); return; }
496 
497  // Dig2Object
498  if (fDigOutMaterial) cObj->Action.Data=1;
499 
500  // Head to target
501  if (cx<tx-DigRange) cObj->Action.ComDir=COMD_Right;
502  if (cx>tx+DigRange) cObj->Action.ComDir=COMD_Left;
503  if (cy<ty-DigRange) cObj->Action.ComDir=COMD_Down;
504  if (cx<tx-DigRange) if (cy<ty-DigRange) cObj->Action.ComDir=COMD_DownRight;
505  if (cx>tx-DigRange) if (cy<ty-DigRange) cObj->Action.ComDir=COMD_DownLeft;
506  if (cx<tx-DigRange) if (cy>ty+DigRange) cObj->Action.ComDir=COMD_UpRight;
507  if (cx>tx+DigRange) if (cy>ty+DigRange) cObj->Action.ComDir=COMD_UpLeft;
508 
509 }
const int32_t MoveToRange
Definition: C4Command.cpp:37
const int32_t DigRange
Definition: C4Command.cpp:37
@ C4CMD_UnGrab
Definition: C4Command.h:35
#define COMD_UpLeft
Definition: C4Object.h:58
#define COMD_DownRight
Definition: C4Object.h:54
#define COMD_Down
Definition: C4Object.h:55
#define COMD_DownLeft
Definition: C4Object.h:56
#define DIR_Left
Definition: C4Object.h:41
#define COMD_UpRight
Definition: C4Object.h:52
#define COMD_Right
Definition: C4Object.h:53
#define COMD_Left
Definition: C4Object.h:57
bool ObjectComLetGo(C4Object *cObj, int32_t xdirf)
bool ObjectComDig(C4Object *cObj)
@ DFA_HANGLE
@ DFA_WALK
@ DFA_PUSH
@ DFA_SCALE
int32_t Data
Definition: C4Object.h:84
int32_t ComDir
Definition: C4Object.h:82
int32_t Dir
Definition: C4Object.h:80
int32_t MoveToRange
Definition: C4Def.h:135
C4Action Action
Definition: C4Object.h:145
C4Shape Shape
Definition: C4Object.h:146
int32_t GetY() const
Definition: C4Shape.h:63
bool getBool() const
Definition: C4Value.h:113

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4CMD_Exit, C4CMD_UnGrab, cObj, COMD_Down, COMD_DownLeft, COMD_DownRight, COMD_Left, COMD_Right, COMD_UpLeft, COMD_UpRight, C4Action::ComDir, C4Object::Contained, Data, C4Action::Data, C4Object::Def, DFA_DIG, DFA_HANGLE, DFA_PUSH, DFA_SCALE, DFA_WALK, DigRange, C4Action::Dir, DIR_Left, Finish(), C4Value::getBool(), C4Object::GetProcedure(), C4Object::GetX(), C4Object::GetY(), C4Shape::GetY(), Inside(), MoveToRange, C4Def::MoveToRange, ObjectComDig(), ObjectComLetGo(), ObjectComStop(), C4Object::Shape, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Drop()

void C4Command::Drop ( )
protected

Definition at line 841 of file C4Command.cpp.

842 {
843 
844  // Digging: stop
846 
847  // Drop specific object not in contents: get object
848  if (Target)
849  if (!cObj->Contents.GetLink(Target))
850  {
851  cObj->AddCommand(C4CMD_Get,Target,0,0,40);
852  return;
853  }
854 
855  // Determine move-to range
856  int32_t iMoveToRange = MoveToRange;
857  if (cObj->Def->MoveToRange > 0) iMoveToRange = cObj->Def->MoveToRange;
858 
859  // Target coordinates are not default 0/0: targeted drop
860  if ((Tx._getInt()!=0) || (Ty!=0))
861  {
862  // Grabbing: let go
863  if (cObj->GetProcedure()==DFA_PUSH)
864  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
865  // At target position: drop
866  if (Inside<int32_t>(cObj->GetX() - Tx._getInt(), -iMoveToRange, +iMoveToRange) && Inside<int32_t>(cObj->GetY()-Ty,-15,+15))
867  {
870  Finish(true);
871  return;
872  }
873  // Move to target position
874  cObj->AddCommand(C4CMD_MoveTo,nullptr,Tx._getInt(),Ty,20);
875  return;
876  }
877 
878  // Contained: put
879  if (cObj->Contained)
880  {
882  Finish(true); return;
883  }
884 
885  // Pushing: put
886  if (cObj->GetProcedure()==DFA_PUSH)
887  {
888  if (cObj->Action.Target)
890  Finish(true); return;
891  }
892 
893  // Outside: Drop
895  Finish(true);
896 }
#define COMD_Stop
Definition: C4Object.h:50
bool ObjectComPutTake(C4Object *cObj, C4Object *pTarget, C4Object *pThing)
bool ObjectComDrop(C4Object *cObj, C4Object *pThing)
C4ObjectPtr Target
Definition: C4Object.h:87
const C4ObjectLink * GetLink(const C4Object *obj) const

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4CMD_Get, C4CMD_MoveTo, C4CMD_UnGrab, cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, C4Object::Contents, C4Object::Def, DFA_DIG, DFA_PUSH, Finish(), C4ObjectList::GetLink(), C4Object::GetProcedure(), C4Object::GetX(), C4Object::GetY(), MoveToRange, C4Def::MoveToRange, ObjectComDrop(), ObjectComPutTake(), ObjectComStop(), Target, C4Action::Target, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Enter()

void C4Command::Enter ( )
protected

Definition at line 564 of file C4Command.cpp.

565 {
566  DWORD ocf;
567 
568  // No object to enter or can't enter by def
569  if (!Target || cObj->Def->NoPushEnter) { Finish(); return; }
570 
571  // Already in target object
572  if (cObj->Contained==Target) { Finish(true); return; }
573 
574  // Digging: stop
576 
577  // Pushing grab only or pushing not desired: let go
578  if (cObj->GetProcedure()==DFA_PUSH)
579  if (cObj->Action.Target)
581  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
582 
583  // Pushing target: let go
584  if (cObj->GetProcedure()==DFA_PUSH)
585  if (cObj->Action.Target==Target)
586  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
587 
588  // Grabbing overrides position for target
589  int32_t cx,cy;
590  cx=cObj->GetX(); cy=cObj->GetY();
591  if (cObj->GetProcedure()==DFA_PUSH)
592  if (cObj->Action.Target)
593  { cx=cObj->Action.Target->GetX(); cy=cObj->Action.Target->GetY(); }
594 
595  // If in entrance range
596  ocf=OCF_Entrance;
597  if (!cObj->Contained && Target->At(cx,cy,ocf) && (ocf & OCF_Entrance))
598  {
599  // Stop
601  // Pushing: push target into entrance, then stop
602  if ((cObj->GetProcedure()==DFA_PUSH) && cObj->Action.Target)
603  {
605  Finish(true); return;
606  }
607  // Else, enter self
608  else
609  {
610  // If entrance open, enter object
611  if (Target->EntranceStatus!=0)
612  {
613  cObj->Enter(Target);
614  Finish(true); return;
615  }
616  else // Else, activate entrance
618  }
619 
620  }
621  else // Else, move to object's entrance
622  {
623  int32_t ex,ey,ewdt,ehgt;
624  if (Target->GetEntranceArea(ex,ey,ewdt,ehgt))
625  cObj->AddCommand(C4CMD_MoveTo,nullptr,ex+ewdt/2,ey+ehgt/2,50, nullptr, true, C4VInt((Data.getInt() & C4CMD_Enter_PushTarget) ? C4CMD_MoveTo_PushTarget : 0));
626  }
627 
628 }
const int32_t C4CMD_MoveTo_PushTarget
Definition: C4Command.h:66
const int32_t C4CMD_Enter_PushTarget
Definition: C4Command.h:68
@ P_Touchable
C4Value C4VInt(int32_t i)
Definition: C4Value.h:239
uint32_t DWORD
int32_t NoPushEnter
Definition: C4Def.h:132
bool Enter(C4Object *pTarget, bool fCalls=true, bool fCopyMotion=true, bool *pfRejectCollect=nullptr)
bool EntranceStatus
Definition: C4Object.h:130
bool At(int32_t ctx, int32_t cty) const
bool ActivateEntrance(int32_t by_plr, C4Object *by_obj)
Definition: C4Object.cpp:689
BYTE GetEntranceArea(int32_t &aX, int32_t &aY, int32_t &aWdt, int32_t &aHgt) const
Definition: C4Object.cpp:708
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:855

References C4Object::Action, C4Object::ActivateEntrance(), C4Object::AddCommand(), C4Object::At(), C4CMD_Enter, C4CMD_Enter_PushTarget, C4CMD_MoveTo, C4CMD_MoveTo_PushTarget, C4CMD_UnGrab, C4VInt(), cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, C4Object::Controller, Data, C4Object::Def, DFA_DIG, DFA_PUSH, C4Object::Enter(), C4Object::EntranceStatus, Finish(), C4Object::GetEntranceArea(), C4Value::getInt(), C4Object::GetProcedure(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), C4Def::NoPushEnter, ObjectComStop(), OCF_Entrance, P_Touchable, C4Object::SetCommand(), Target, and C4Action::Target.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Execute()

void C4Command::Execute ( )

Definition at line 1295 of file C4Command.cpp.

1296 {
1297 
1298  // Finished?!
1299  if (Finished) return;
1300 
1301  // Parent object safety
1302  if (!cObj) { Finish(); return; }
1303 
1304  // Delegated command failed
1305  if (Failures)
1306  {
1307  // Retry
1308  if (Retries>0)
1309  { Failures=0; Retries--; cObj->AddCommand(C4CMD_Retry,nullptr,0,0,10); return; }
1310  // Too many failures
1311  else
1312  { Finish(); return; }
1313  }
1314 
1315  // Command update
1316  if (UpdateInterval>0)
1317  {
1318  UpdateInterval--;
1319  if (UpdateInterval==0)
1320  {
1321  Finish(true); return;
1322  }
1323  }
1324 
1325  // Initial command evaluation
1326  if (InitEvaluation()) return;
1327 
1328  // from now on, we are executing this command... and nobody
1329  // should dare deleting us
1330  iExec = 1;
1331 
1332  // Execute
1333  switch (Command)
1334  {
1335  case C4CMD_Follow: Follow(); break;
1336  case C4CMD_MoveTo: MoveTo(); break;
1337  case C4CMD_Enter: Enter(); break;
1338  case C4CMD_Exit: Exit(); break;
1339  case C4CMD_Grab: Grab(); break;
1340  case C4CMD_UnGrab: UnGrab(); break;
1341  case C4CMD_Throw: Throw(); break;
1342  case C4CMD_Jump: Jump(); break;
1343  case C4CMD_Wait: Wait(); break;
1344  case C4CMD_Get: Get(); break;
1345  case C4CMD_Put: Put(); break;
1346  case C4CMD_Drop: Drop(); break;
1347  case C4CMD_Dig: Dig(); break;
1348  case C4CMD_Activate: Activate(); break;
1349  case C4CMD_PushTo: PushTo(); break;
1350  case C4CMD_Transfer: Transfer(); break;
1351  case C4CMD_Attack: Attack(); break;
1352  case C4CMD_Buy: Buy(); break;
1353  case C4CMD_Sell: Sell(); break;
1354  case C4CMD_Acquire: Acquire(); break;
1355  case C4CMD_Retry: Retry(); break;
1356  case C4CMD_Home: Home(); break;
1357  case C4CMD_Call: Call(); break;
1358  case C4CMD_Take: Take(); break; // carlo
1359  case C4CMD_Take2: Take2(); break; // carlo
1360  default: Finish(); break;
1361  }
1362 
1363  /* // Remember this command might have already been deleted through calls
1364  // made during execution. You must not do anything here... */
1365 
1366  // check: command must be deleted?
1367  if (iExec > 1)
1368  delete this;
1369  else
1370  iExec = 0;
1371 
1372 }
@ C4CMD_Acquire
Definition: C4Command.h:48
@ C4CMD_Call
Definition: C4Command.h:51
@ C4CMD_Home
Definition: C4Command.h:50
@ C4CMD_Sell
Definition: C4Command.h:47
@ C4CMD_Drop
Definition: C4Command.h:40
@ C4CMD_Transfer
Definition: C4Command.h:44
@ C4CMD_Follow
Definition: C4Command.h:29
@ C4CMD_Activate
Definition: C4Command.h:42
@ C4CMD_Take
Definition: C4Command.h:52
@ C4CMD_Wait
Definition: C4Command.h:37
@ C4CMD_Attack
Definition: C4Command.h:45
@ C4CMD_Retry
Definition: C4Command.h:49
@ C4CMD_Take2
Definition: C4Command.h:53
@ C4CMD_Jump
Definition: C4Command.h:36
@ C4CMD_Put
Definition: C4Command.h:39
@ C4CMD_PushTo
Definition: C4Command.h:43
@ C4CMD_Dig
Definition: C4Command.h:41
@ C4CMD_Grab
Definition: C4Command.h:33
void Drop()
Definition: C4Command.cpp:841
void Acquire()
Definition: C4Command.cpp:1655
void Dig()
Definition: C4Command.cpp:454
void Put()
Definition: C4Command.cpp:1173
void Buy()
Definition: C4Command.cpp:1645
void Enter()
Definition: C4Command.cpp:564
void Retry()
Definition: C4Command.cpp:1800
void Take2()
Definition: C4Command.cpp:835
void Call()
Definition: C4Command.cpp:1833
void Sell()
Definition: C4Command.cpp:1650
void Transfer()
Definition: C4Command.cpp:1571
void Grab()
Definition: C4Command.cpp:669
void Get()
Definition: C4Command.cpp:955
bool InitEvaluation()
Definition: C4Command.cpp:1392
void Throw()
Definition: C4Command.cpp:755
void MoveTo()
Definition: C4Command.cpp:257
void PushTo()
Definition: C4Command.cpp:701
void Attack()
Definition: C4Command.cpp:1600
void Take()
Definition: C4Command.cpp:829
void Home()
Definition: C4Command.cpp:1805
void UnGrab()
Definition: C4Command.cpp:748
void Wait()
Definition: C4Command.cpp:920
void Jump()
Definition: C4Command.cpp:898
void Exit()
Definition: C4Command.cpp:630
void Follow()
Definition: C4Command.cpp:512
void Activate()
Definition: C4Command.cpp:1105

References Acquire(), Activate(), C4Object::AddCommand(), Attack(), Buy(), C4CMD_Acquire, C4CMD_Activate, C4CMD_Attack, C4CMD_Buy, C4CMD_Call, C4CMD_Dig, C4CMD_Drop, C4CMD_Enter, C4CMD_Exit, C4CMD_Follow, C4CMD_Get, C4CMD_Grab, C4CMD_Home, C4CMD_Jump, C4CMD_MoveTo, C4CMD_PushTo, C4CMD_Put, C4CMD_Retry, C4CMD_Sell, C4CMD_Take, C4CMD_Take2, C4CMD_Throw, C4CMD_Transfer, C4CMD_UnGrab, C4CMD_Wait, Call(), cObj, Command, Dig(), Drop(), Enter(), Exit(), Failures, Finish(), Finished, Follow(), Get(), Grab(), Home(), iExec, InitEvaluation(), Jump(), MoveTo(), PushTo(), Put(), Retries, Retry(), Sell(), Take(), Take2(), Throw(), Transfer(), UnGrab(), UpdateInterval, and Wait().

Referenced by C4Object::ExecuteCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Exit()

void C4Command::Exit ( )
protected

Definition at line 630 of file C4Command.cpp.

631 {
632 
633  // Outside: done
634  if (!cObj->Contained) { Finish(true); return; }
635 
636  // Entrance open, leave object
638  {
639  // Exit to container's container
640  if (cObj->Contained->Contained)
641  { cObj->Enter(cObj->Contained->Contained); Finish(true); return; }
642  // Exit to entrance area
643  int32_t ex,ey,ewdt,ehgt;
644  if (cObj->Contained->OCF & OCF_Entrance)
645  if (cObj->Contained->GetEntranceArea(ex,ey,ewdt,ehgt))
646  { cObj->Exit(ex+ewdt/2,ey+ehgt+cObj->Shape.GetY()-1); Finish(true); return; }
647  // Exit jump out of collection area
650  {
653  Finish(true); return;
654  }
655  // Plain exit
656  cObj->Exit(cObj->GetX(),cObj->GetY());
657  Finish(true); return;
658  }
659 
660  // Entrance closed, activate entrance
661  else
662  {
664  // Entrance activation failed: fail
665  { Finish(); return; }
666  }
667 }
bool ObjectComJump(C4Object *cObj)
@ P_Collectible
C4Rect Collection
Definition: C4Def.h:106
bool Exit(int32_t iX=0, int32_t iY=0, int32_t iR=0, C4Real iXDir=Fix0, C4Real iYDir=Fix0, C4Real iRDir=Fix0, bool fCalls=true)
int32_t y
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30

References C4Object::ActivateEntrance(), cObj, C4Def::Collection, C4Object::Contained, C4Object::Controller, C4Object::Def, C4Object::Enter(), C4Object::EntranceStatus, C4Object::Exit(), Finish(), C4Object::GetEntranceArea(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), C4Shape::GetY(), ObjectComJump(), C4Object::OCF, OCF_Entrance, P_Collectible, C4Object::Shape, C4Rect::Wdt, and C4Rect::y.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Fail()

void C4Command::Fail ( const char *  szFailMessage = nullptr)
protected

Definition at line 1703 of file C4Command.cpp.

1704 {
1705  // Check for base command (next unfinished)
1706  C4Command *pBase;
1707  for (pBase=Next; pBase; pBase=pBase->Next) if (!pBase->Finished) break;
1708 
1709  bool ExecFail = false;
1710  switch (BaseMode)
1711  {
1712  // silent subcommand
1713  case C4CMD_Mode_SilentSub:
1714  {
1715  // Just count failures in base command
1716  if (pBase) { pBase->Failures++; return; }
1717  else ExecFail = true;
1718  break;
1719  }
1720  // verbose subcommand
1721  case C4CMD_Mode_Sub:
1722  {
1723  // Count failures in base command
1724  if (pBase) { pBase->Failures++; }
1725  // Execute fail message, if base will fail
1726  if (!pBase || !pBase->Retries) ExecFail = true;
1727  break;
1728  }
1729  // base command
1730  case C4CMD_Mode_Base:
1731  {
1732  // Just execute fail notice
1733  ExecFail = true;
1734  break;
1735  }
1736  // silent base command: do nothing
1737  }
1738 
1739  char szCommandName[24 + 1];
1740  char szObjectName[C4MaxName + 1];
1741  StdStrBuf str;
1742 
1743  if (ExecFail && cObj && (cObj->OCF & OCF_CrewMember))
1744  {
1745  // Fail message
1746  if (szFailMessage)
1747  str = szFailMessage;
1748  C4Object * l_Obj = cObj;
1749  switch (Command)
1750  {
1751  case C4CMD_Call:
1752  {
1753  // Call fail-function in target object (no message if non-zero)
1754  int32_t l_Command = Command;
1755  if (CallFailed()) return;
1756  // Fail-function not available or returned zero: standard message
1757  SCopy(LoadResStr(CommandNameID(l_Command)),szCommandName);
1758  str.Format(LoadResStr("IDS_CON_FAILURE"),szCommandName);
1759  break;
1760  }
1761  case C4CMD_Exit:
1762  // No message
1763  break;
1764  case C4CMD_Dig:
1765  // No message
1766  break;
1767  case C4CMD_Acquire:
1768  // Already has a fail message
1769  if (szFailMessage) break;
1770  // Fail message with name of target type
1771  SCopy(LoadResStr(CommandNameID(Command)), szCommandName);
1772  C4Def *pDef; pDef = Data.getDef();
1773  SCopy(pDef ? pDef->GetName() : LoadResStr("IDS_OBJ_UNKNOWN"), szObjectName);
1774  str.Format(LoadResStr("IDS_CON_FAILUREOF"), szCommandName, szObjectName);
1775  break;
1776  default:
1777  // Already has a fail message
1778  if (szFailMessage) break;
1779  // Standard no-can-do message
1780  SCopy(LoadResStr(CommandNameID(Command)), szCommandName);
1781  str.Format(LoadResStr("IDS_CON_FAILURE"), szCommandName);
1782  break;
1783  }
1784  if (l_Obj) if (l_Obj->Status && !l_Obj->Def->SilentCommands)
1785  {
1786  // Message (if not empty)
1787  if (!!str)
1788  {
1789  ::Messages.Append(C4GM_Target, str.getData(), l_Obj, NO_OWNER, 0, 0, C4RGB(0xff, 0xff, 0xff), true);
1790  }
1791  // Stop Clonk
1792  l_Obj->Action.ComDir = COMD_Stop;
1793  // Clonk-specific fail action/sound
1795  l_Obj->Call(PSF_CommandFailure, &pars);
1796  }
1797  }
1798 }
const char * CommandName(int32_t iCommand)
Definition: C4Command.cpp:46
const char * CommandNameID(int32_t iCommand)
Definition: C4Command.cpp:80
const int32_t C4CMD_Mode_Base
Definition: C4Command.h:60
const int NO_OWNER
Definition: C4Constants.h:137
C4GameMessageList Messages
const int32_t C4GM_Target
Definition: C4GameMessage.h:31
#define PSF_CommandFailure
Definition: C4GameScript.h:102
const unsigned int C4MaxName
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
C4Value C4VObj(C4Object *pObj)
Definition: C4Value.cpp:88
C4Value C4VString(C4String *pStr)
Definition: C4Value.h:243
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
#define C4RGB(r, g, b)
Definition: StdColors.h:26
int32_t CallFailed()
Definition: C4Command.cpp:1918
Definition: C4Def.h:99
int32_t SilentCommands
Definition: C4Def.h:139
bool Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t bCol, bool fNoDuplicates=false)
const char * GetName() const override
Definition: C4PropList.cpp:243
const char * getData() const
Definition: StdBuf.h:442
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174

References C4Object::Action, C4GameMessageList::Append(), BaseMode, C4CMD_Acquire, C4CMD_Call, C4CMD_Dig, C4CMD_Exit, C4CMD_Mode_Base, C4CMD_Mode_SilentSub, C4CMD_Mode_Sub, C4GM_Target, C4MaxName, C4RGB, C4VInt(), C4VObj(), C4VString(), C4PropList::Call(), CallFailed(), cObj, COMD_Stop, C4Action::ComDir, Command, CommandName(), CommandNameID(), Data, C4Object::Def, Failures, Finished, StdStrBuf::Format(), StdStrBuf::getData(), C4Value::getDef(), C4PropListStatic::GetName(), LoadResStr(), Messages, Next, NO_OWNER, C4Object::OCF, OCF_CrewMember, PSF_CommandFailure, Retries, SCopy(), C4Def::SilentCommands, C4PropList::Status, Target, Target2, Tx, and Ty.

Referenced by Finish().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Finish()

void C4Command::Finish ( bool  fSuccess = false,
const char *  szFailMessage = nullptr 
)
protected

Definition at line 1374 of file C4Command.cpp.

1375 {
1376  // Mark finished
1377  Finished=true;
1378  // Failed
1379  if (!fSuccess)
1380  Fail(szFailMessage);
1381  else
1382  {
1383  // successful commands might gain EXP
1384  int32_t iExpGain = GetExpGain();
1385  if (iExpGain && cObj) if (cObj->Info)
1386  for (int32_t i=iExpGain; i; --i)
1387  if (!(++cObj->Info->ControlCount%5))
1388  cObj->DoExperience(1);
1389  }
1390 }
int32_t GetExpGain()
Definition: C4Command.cpp:1932
void Fail(const char *szFailMessage=nullptr)
Definition: C4Command.cpp:1703
C4ObjectInfo * Info
Definition: C4Object.h:143
void DoExperience(int32_t change)
int32_t ControlCount
Definition: C4ObjectInfo.h:38

References cObj, C4ObjectInfo::ControlCount, C4Object::DoExperience(), Fail(), Finished, GetExpGain(), and C4Object::Info.

Referenced by Acquire(), Activate(), Attack(), Buy(), Call(), Dig(), Drop(), Enter(), Execute(), Exit(), Follow(), Get(), GetTryEnter(), Grab(), Home(), Jump(), MoveTo(), PushTo(), Put(), Sell(), Take(), Take2(), Throw(), Transfer(), and UnGrab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FlightControl()

bool C4Command::FlightControl ( )
protected

Definition at line 1471 of file C4Command.cpp.

1472 {
1473  // Crew members or pathfinder objects only
1474  if (!((cObj->OCF & OCF_CrewMember) || cObj->Def->Pathfinder)) return false;
1475 
1476  // Not while in a disabled action
1477  C4PropList* pActionDef = cObj->GetAction();
1478  if (pActionDef)
1479  {
1480  if (pActionDef->GetPropertyInt(P_ObjectDisabled)) return false;
1481  }
1482 
1483  // Target angle
1484  int32_t cx=cObj->GetX(),cy=cObj->GetY();
1485  int32_t iAngle = Angle(cx,cy,Tx._getInt(),Ty); while (iAngle>180) iAngle-=360;
1486 
1487  // Target in flight angle (sector +/- from straight up), beyond minimum distance, and top free
1488  if (Inside(iAngle, -FlightAngleRange, +FlightAngleRange)
1489  || Inside(iAngle, -FlightAngleRange, +FlightAngleRange))
1490  if (Distance(cx,cy,Tx._getInt(),Ty) > 30)
1491  {
1492  int32_t iTopFree;
1493  for (iTopFree=0; (iTopFree<50) && !GBackSolid(cx,cy+cObj->Shape.GetY()-iTopFree); ++iTopFree) {}
1494  if (iTopFree>=15)
1495  {
1496  // Take off
1497  return cObj->SetActionByName("Fly"); // This is a little primitive... we should have a ObjectActionFly or maybe a command for this...
1498  }
1499  }
1500 
1501  // No flight control
1502  return false;
1503 }
const int32_t FlightAngleRange
Definition: C4Command.cpp:41
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:229
@ P_ObjectDisabled
int32_t Angle(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iPrec)
Definition: Standard.cpp:37
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
Definition: Standard.cpp:25
int32_t Pathfinder
Definition: C4Def.h:134
C4PropList * GetAction() const
bool SetActionByName(C4String *ActName, C4Object *pTarget=nullptr, C4Object *pTarget2=nullptr, int32_t iCalls=SAC_StartCall|SAC_AbortCall, bool fForce=false)

References C4Value::_getInt(), Angle(), cObj, C4Object::Def, Distance(), FlightAngleRange, GBackSolid(), C4Object::GetAction(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), C4Shape::GetY(), Inside(), C4Object::OCF, OCF_CrewMember, P_ObjectDisabled, C4Def::Pathfinder, C4Object::SetActionByName(), C4Object::Shape, Tx, and Ty.

Referenced by MoveTo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Follow()

void C4Command::Follow ( )
protected

Definition at line 512 of file C4Command.cpp.

513 {
514  // No-one to follow
515  if (!Target) { Finish(); return; }
516 
517  // Follow containment
519  {
520  // Only crew members can follow containment
521  if (!cObj->Def->CrewMember)
522  { Finish(); return; }
523  // Exit/enter
524  if (cObj->Contained) cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50);
525  else cObj->AddCommand(C4CMD_Enter,Target->Contained,0,0,50);
526  return;
527  }
528 
529  // Follow target grabbing
530  if (Target->GetProcedure()==DFA_PUSH)
531  {
532  // Grabbing same: copy ComDir
533  if (cObj->GetProcedure()==DFA_PUSH)
535  {
537  return;
538  }
539  // Else, grab target's grab
541  return;
542  }
543  else if (cObj->GetProcedure()==DFA_PUSH)
544  {
545  // Follow ungrabbing
547  return;
548  }
549 
550  // If in following range
551  if (Inside<int32_t>(cObj->GetX()-Target->GetX(),-FollowRange,+FollowRange)
552  && Inside<int32_t>(cObj->GetY()-Target->GetY(),-FollowRange,+FollowRange))
553  {
554  // Copy target's Action.ComDir
556  }
557  else // Else, move to target
558  {
559  cObj->AddCommand(C4CMD_MoveTo,nullptr,Target->GetX(),Target->GetY(),10);
560  }
561 
562 }
const int32_t FollowRange
Definition: C4Command.cpp:38
int32_t CrewMember
Definition: C4Def.h:112

References C4Object::Action, C4Object::AddCommand(), C4CMD_Enter, C4CMD_Exit, C4CMD_Grab, C4CMD_MoveTo, C4CMD_UnGrab, cObj, C4Action::ComDir, C4Object::Contained, C4Def::CrewMember, C4Object::Def, DFA_PUSH, Finish(), FollowRange, C4Object::GetProcedure(), C4Object::GetX(), C4Object::GetY(), Target, and C4Action::Target.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get()

void C4Command::Get ( )
protected

Definition at line 955 of file C4Command.cpp.

956 {
957 
958  // Data set and target specified: open get menu & done (old style)
959  if (((Data.getInt()==1) || (Data.getInt()==2)) && Target)
960  {
962  Finish(true); return;
963  }
964 
965  // Get target specified by container and type
966  if (!Target && Target2 && Data)
967  if (!(Target = Target2->Contents.Find(Data.getDef())))
968  { Finish(); return; }
969 
970  // No target: failure
971  if (!Target) { Finish(); return; }
972 
973  // Target not carryable: failure
974  if (!(Target->OCF & OCF_Carryable))
975  { Finish(); return; }
976 
977  // Target collected
978  if (Target->Contained == cObj)
979  {
980  // Get-count specified: decrease count and continue with next object
981  if (Tx._getInt() > 1)
982  { Target = nullptr; Tx--; return; }
983  // We're done
984  else
985  { cObj->Action.ComDir=COMD_Stop; Finish(true); return; }
986  }
987 
988  // Grabbing other than target container: let go
989  if (cObj->GetProcedure()==DFA_PUSH)
991  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
992 
993  // Target in solid: dig out
994  if (!Target->Contained && (Target->OCF & OCF_InSolid))
995  {
996  // Check for closest free position
997  int32_t iX=Target->GetX(),iY=Target->GetY();
998  // Find all-closest dig-out position
999  if (!FindClosestFree(iX,iY,-120,+120,-1,-1))
1000  // None found
1001  { Finish(); return; }
1002  // Check good-angle left/right dig-out position
1003  int32_t iX2=Target->GetX(),iY2=Target->GetY();
1004  if (FindClosestFree(iX2,iY2,-140,+140,-40,+40))
1005  // Use good-angle position if it's not way worse
1006  if ( Distance(Target->GetX(),Target->GetY(),iX2,iY2) < 10*Distance(Target->GetX(),Target->GetY(),iX,iY) )
1007  { iX=iX2; iY=iY2; }
1008  // Move to closest free position (if not in dig-direct range)
1011  { cObj->AddCommand(C4CMD_MoveTo,nullptr,iX,iY,50); return; }
1012  // DigTo
1013  cObj->AddCommand(C4CMD_Dig,nullptr,Target->GetX(),Target->GetY()+4,50); return;
1014  }
1015 
1016  // Digging: stop
1018 
1019  // Target contained
1020  if (Target->Contained)
1021  {
1022  // target can't be taken out of containers?
1023  if (Target->Def->NoGet) return;
1024  // In same container: grab target
1025  if (cObj->Contained==Target->Contained)
1026  {
1027  GetTryEnter();
1028  // Done
1029  return;
1030  }
1031 
1032  // Leave own container
1033  if (cObj->Contained)
1034  { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
1035 
1036  // Target container has grab get: grab target container
1038  {
1039  // Grabbing target container
1041  {
1042  GetTryEnter();
1043  // Done
1044  return;
1045  }
1046  // Grab target container
1048  return;
1049  }
1050 
1051  // Target container has entrance: enter target container
1052  if (Target->Contained->OCF & OCF_Entrance)
1053  { cObj->AddCommand(C4CMD_Enter,Target->Contained,0,0,50); return; }
1054 
1055  // Can't get to target due to target container: fail
1056  Finish();
1057  return;
1058  }
1059 
1060  // Target outside
1061 
1062  // Leave own container
1063  if (cObj->Contained) { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
1064 
1065  // Outside
1066  if (!cObj->Contained)
1067  {
1068 
1069  // Target in collection range
1071  if (cObj->At(Target->GetX(),Target->GetY(),ocf))
1072  {
1073  // stop here
1075  // try getting the object
1076  if (GetTryEnter()) return;
1077  }
1078 
1079  // Target not in range
1080  else
1081  {
1082  // Target in jumping range above clonk: try side-move jump
1083  if (Inside<int32_t>(cObj->GetX()-Target->GetX(),-10,+10))
1084  if (Inside<int32_t>(cObj->GetY()-Target->GetY(),30,50))
1085  {
1086  int32_t iSideX=1; if (Random(2)) iSideX=-1;
1087  iSideX=cObj->GetX()+iSideX*(cObj->GetY()-Target->GetY());
1088  if (PathFree(iSideX,cObj->GetY(),Target->GetX(),Target->GetY()))
1089  {
1090  // Side-move jump
1091  cObj->AddCommand(C4CMD_Jump,nullptr,Tx._getInt(),Ty);
1092  // FIXME: Drop stuff if full here
1093  cObj->AddCommand(C4CMD_MoveTo,nullptr,iSideX,cObj->GetY(),50);
1094  }
1095  }
1096  // Move to target (random offset for difficult pickups)
1097  // ...avoid offsets into solid which would lead to high above surface locations!
1098  cObj->AddCommand(C4CMD_MoveTo,nullptr,Target->GetX()+Random(15)-7,Target->GetY(),25,nullptr);
1099  }
1100 
1101  }
1102 
1103 }
const int32_t DigOutPositionRange
Definition: C4Command.cpp:38
const uint32_t OCF_Carryable
Definition: C4Constants.h:82
const uint32_t OCF_Collection
Definition: C4Constants.h:93
const uint32_t OCF_Normal
Definition: C4Constants.h:79
const uint32_t OCF_InSolid
Definition: C4Constants.h:99
const int32_t C4D_Grab_Get
Definition: C4Def.h:63
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
bool FindClosestFree(int32_t &rX, int32_t &rY, int32_t iAngle1, int32_t iAngle2, int32_t iExcludeAngle1, int32_t iExcludeAngle2)
@ C4MN_Get
Definition: C4ObjectMenu.h:39
@ C4MN_Contents
Definition: C4ObjectMenu.h:44
uint32_t Random()
Definition: C4Random.cpp:43
bool GetTryEnter()
Definition: C4Command.cpp:926
int32_t NoGet
Definition: C4Def.h:144
int32_t GrabPutGet
Definition: C4Def.h:124

References C4Value::_getInt(), C4Object::Action, C4Object::ActivateMenu(), C4Object::AddCommand(), C4Object::At(), C4CMD_Dig, C4CMD_Enter, C4CMD_Exit, C4CMD_Grab, C4CMD_Jump, C4CMD_MoveTo, C4CMD_UnGrab, C4D_Grab_Get, C4MN_Contents, C4MN_Get, cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, C4Object::Contents, Data, C4Object::Def, DFA_DIG, DFA_PUSH, DigOutPositionRange, Distance(), C4ObjectList::Find(), FindClosestFree(), Finish(), C4Value::getDef(), C4Value::getInt(), C4Object::GetProcedure(), GetTryEnter(), C4Object::GetX(), C4Object::GetY(), C4Def::GrabPutGet, Inside(), C4Def::NoGet, ObjectComStop(), C4Object::OCF, OCF_Carryable, OCF_Collection, OCF_Entrance, OCF_InSolid, OCF_Normal, PathFree(), Random(), Target, C4Action::Target, Target2, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetExpGain()

int32_t C4Command::GetExpGain ( )
protected

Definition at line 1932 of file C4Command.cpp.

1933 {
1934  // return exp gained by this command
1935  switch (Command)
1936  {
1937  // internal
1938  case C4CMD_Wait:
1939  case C4CMD_Transfer:
1940  case C4CMD_Retry:
1941  case C4CMD_Call:
1942  return 0;
1943 
1944  // regular move commands
1945  case C4CMD_Follow:
1946  case C4CMD_MoveTo:
1947  case C4CMD_Enter:
1948  case C4CMD_Exit:
1949  return 1;
1950 
1951  // simple activities
1952  case C4CMD_Grab:
1953  case C4CMD_UnGrab:
1954  case C4CMD_Throw:
1955  case C4CMD_Jump:
1956  case C4CMD_Get:
1957  case C4CMD_Put:
1958  case C4CMD_Drop:
1959  case C4CMD_Activate:
1960  case C4CMD_PushTo:
1961  case C4CMD_Dig:
1962  case C4CMD_Buy:
1963  case C4CMD_Sell:
1964  case C4CMD_Take:
1965  case C4CMD_Take2:
1966  return 1;
1967 
1968  // not that simple
1969  case C4CMD_Acquire:
1970  case C4CMD_Home:
1971  return 2;
1972 
1973  // victory!
1974  case C4CMD_Attack:
1975  return 15;
1976  }
1977  // unknown command
1978  return 0;
1979 }

References C4CMD_Acquire, C4CMD_Activate, C4CMD_Attack, C4CMD_Buy, C4CMD_Call, C4CMD_Dig, C4CMD_Drop, C4CMD_Enter, C4CMD_Exit, C4CMD_Follow, C4CMD_Get, C4CMD_Grab, C4CMD_Home, C4CMD_Jump, C4CMD_MoveTo, C4CMD_PushTo, C4CMD_Put, C4CMD_Retry, C4CMD_Sell, C4CMD_Take, C4CMD_Take2, C4CMD_Throw, C4CMD_Transfer, C4CMD_UnGrab, C4CMD_Wait, and Command.

Referenced by Finish().

Here is the caller graph for this function:

◆ GetTryEnter()

bool C4Command::GetTryEnter ( )
protected

Definition at line 926 of file C4Command.cpp.

927 {
928  // Target contained and container has RejectContents: fail
929  if (Target->Contained && !!Target->Contained->Call(PSF_RejectContents)) { Finish(); return false; }
930  // FIXME: Drop stuff if full here
931  bool fWasContained = !!Target->Contained;
932  // Grab target object
933  bool fRejectCollect = false;
934  bool fSuccess = !!Target->Enter(cObj, true, true, &fRejectCollect);
935  // target is void?
936  // well...most likely the new container has done something with it
937  // so count it as success
938  if (!Target) { Finish(true); return true; }
939  // collection rejected by target: make room for more contents
940  if (fRejectCollect)
941  {
942  if (cObj->PutAwayUnusedObject(Target)) return false;
943  // Can't get due to RejectCollect: fail
944  Finish();
945  return false;
946  }
947  // if not successfully entered for any other reason, fail
948  if (!fSuccess) { Finish(); return false; }
949  // get-callback for getting out of containers
950  if (fWasContained) cObj->Call(PSF_Get, &C4AulParSet(Target));
951  // entered
952  return true;
953 }
#define PSF_RejectContents
Definition: C4GameScript.h:134
#define PSF_Get
Definition: C4GameScript.h:54
bool PutAwayUnusedObject(C4Object *pToMakeRoomForObject)

References C4PropList::Call(), cObj, C4Object::Contained, C4Object::Enter(), Finish(), PSF_Get, PSF_RejectContents, C4Object::PutAwayUnusedObject(), and Target.

Referenced by Get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Grab()

void C4Command::Grab ( )
protected

Definition at line 669 of file C4Command.cpp.

670 {
671  DWORD ocf;
672  // Command fulfilled
673  if (cObj->GetProcedure()==DFA_PUSH)
674  if (cObj->Action.Target==Target)
675  { Finish(true); return; }
676  // Digging: stop
678  // Grabbing: let go
679  if (cObj->GetProcedure()==DFA_PUSH)
680  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
681  // No target
682  if (!Target) { Finish(); return; }
683  // At target object: grab
684  ocf=OCF_All;
685  if (!cObj->Contained && Target->At(cObj->GetX(),cObj->GetY(),ocf))
686  {
687  // Scaling or hangling: let go
689  ObjectComLetGo(cObj,(cObj->Action.Dir==DIR_Left) ? +1 : -1);
690  // Grab
693  }
694  // Else, move to object
695  else
696  {
697  cObj->AddCommand(C4CMD_MoveTo,nullptr,Target->GetX()+Tx._getInt(),Target->GetY()+Ty,50);
698  }
699 }
const uint32_t OCF_All
Definition: C4Constants.h:78
bool ObjectComGrab(C4Object *cObj, C4Object *pTarget)

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4Object::At(), C4CMD_MoveTo, C4CMD_UnGrab, cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, DFA_DIG, DFA_HANGLE, DFA_PUSH, DFA_SCALE, C4Action::Dir, DIR_Left, Finish(), C4Object::GetProcedure(), C4Object::GetX(), C4Object::GetY(), ObjectComGrab(), ObjectComLetGo(), ObjectComStop(), OCF_All, Target, C4Action::Target, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Home()

void C4Command::Home ( )
protected

Definition at line 1805 of file C4Command.cpp.

1806 {
1807  Finish();
1808 }

References Finish().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitEvaluation()

bool C4Command::InitEvaluation ( )
protected

Definition at line 1392 of file C4Command.cpp.

1393 {
1394  // Already evaluated
1395  if (Evaluated) return false;
1396  // Set evaluation flag
1397  Evaluated=true;
1398  // Evaluate
1399  switch (Command)
1400  {
1401  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1402  case C4CMD_MoveTo:
1403  {
1404  // Target coordinates by Target
1405  if (Target) { Tx+=Target->GetX(); Ty+=Target->GetY(); Target=nullptr; }
1406  // Adjust coordinates
1407  int32_t iTx = Tx._getInt();
1409  Tx.SetInt(iTx);
1410  return true;
1411  }
1412  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1413  case C4CMD_PushTo:
1414  {
1415  // Adjust coordinates
1416  int32_t iTx = Tx._getInt();
1418  Tx.SetInt(iTx);
1419  return true;
1420  }
1421  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1422  case C4CMD_Exit:
1423  // Cancel attach
1425  return true;
1426  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1427  case C4CMD_Jump:
1428  {
1429  if (Tx._getInt())
1430  {
1431  if (Tx._getInt()<cObj->GetX()) cObj->SetDir(DIR_Left);
1432  if (Tx._getInt()>cObj->GetX()) cObj->SetDir(DIR_Right);
1433  }
1435  return true;
1436  }
1437  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1438  case C4CMD_Wait:
1439  // Update interval by Data
1440  if (!!Data) UpdateInterval=Data.getInt();
1441  // Else update interval by Tx
1442  else if (Tx._getInt()) UpdateInterval=Tx._getInt();
1443  return true;
1444  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1445  case C4CMD_Acquire:
1446  // update default search range
1447  if (!Tx._getInt()) Tx.SetInt(500);
1448  if (!Ty) Ty=250;
1449  return true;
1450  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1451  }
1452  // Need not be evaluated
1453  return false;
1454 }
bool FreeMoveTo(C4Object *cObj)
Definition: C4Command.cpp:134
void AdjustMoveToTarget(int32_t &rX, int32_t &rY, bool fFreeMove, int32_t iShapeHgt)
Definition: C4Command.cpp:142
const int32_t C4CMD_MoveTo_NoPosAdjust
Definition: C4Command.h:65
#define DIR_Right
Definition: C4Object.h:42
bool ObjectComCancelAttach(C4Object *cObj)
void SetDir(int32_t tdir)
int32_t Hgt
Definition: C4Rect.h:30

References C4Value::_getInt(), AdjustMoveToTarget(), C4CMD_Acquire, C4CMD_Exit, C4CMD_Jump, C4CMD_MoveTo, C4CMD_MoveTo_NoPosAdjust, C4CMD_PushTo, C4CMD_Wait, cObj, Command, Data, DIR_Left, DIR_Right, Evaluated, FreeMoveTo(), C4Value::getInt(), C4Object::GetX(), C4Object::GetY(), C4Rect::Hgt, ObjectComCancelAttach(), ObjectComJump(), C4Object::SetDir(), C4Value::SetInt(), C4Object::Shape, Target, Tx, Ty, and UpdateInterval.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Jump()

void C4Command::Jump ( )
protected

Definition at line 898 of file C4Command.cpp.

899 {
900  // Already in air?
901  if (cObj->GetProcedure()==DFA_FLIGHT)
902  {
903  // Check whether target position is given
904  if (Tx._getInt())
905  {
907  else if (cObj->GetX()>Tx._getInt()) cObj->Action.ComDir=COMD_Left;
908  else cObj->Action.ComDir=COMD_Stop;
909  }
910  }
911  else
912  {
914  // Done
915  Finish(true);
916  return;
917  }
918 }
@ DFA_FLIGHT

References C4Value::_getInt(), C4Object::Action, cObj, COMD_Left, COMD_Right, COMD_Stop, C4Action::ComDir, DFA_FLIGHT, Finish(), C4Object::GetProcedure(), C4Object::GetX(), and Tx.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ JumpControl()

bool C4Command::JumpControl ( )
protected

Definition at line 1505 of file C4Command.cpp.

1506 {
1507 
1508  // Crew members or pathfinder objects only
1509  if (! ((cObj->OCF & OCF_CrewMember) || cObj->Def->Pathfinder) ) return false;
1510 
1511  // Target angle
1512  int32_t cx=cObj->GetX(),cy=cObj->GetY();
1513  int32_t iAngle = Angle(cx,cy,Tx._getInt(),Ty); while (iAngle>180) iAngle-=360;
1514 
1515  // Diagonal free jump (if in angle range, minimum distance, and top free)
1518  if (PathFree(cx,cy,Tx._getInt(),Ty))
1519  if (Distance(cx,cy,Tx._getInt(),Ty)>30)
1520  {
1521  int32_t iTopFree;
1522  for (iTopFree=0; (iTopFree<50) && !GBackSolid(cx,cy+cObj->Shape.GetY()-iTopFree); ++iTopFree) {}
1523  if (iTopFree>=15)
1524  {
1525  cObj->AddCommand(C4CMD_Jump,nullptr,Tx,Ty); return true;
1526  }
1527  }
1528 
1529  // High angle side move - jump (2x range)
1530  if (Inside<int32_t>(iAngle-JumpHighAngle,-3*JumpAngleRange,+3*JumpAngleRange))
1531  // Vertical range
1532  if (Inside<int32_t>(cy-Ty,10,40))
1533  {
1534  int32_t iSide=SolidOnWhichSide(Tx._getInt(),Ty); // take jump height of side move position into consideration...!
1535  int32_t iDist=5*Abs(cy-Ty)/6;
1536  int32_t iSideX=cx-iDist*iSide,iSideY=cy; AdjustMoveToTarget(iSideX,iSideY,false,0);
1537  // Side move target in range
1538  if (Inside<int32_t>(iSideY-cy,-20,+20))
1539  {
1540  // Path free from side move target to jump target
1541  if (PathFree(iSideX,iSideY,Tx._getInt(),Ty))
1542  {
1543  cObj->AddCommand(C4CMD_Jump,nullptr,Tx,Ty);
1544  cObj->AddCommand(C4CMD_MoveTo,nullptr,iSideX,iSideY,50);
1545  return true;
1546  }
1547  }
1548  }
1549 
1550  // Low side contact jump
1551  // Only jump before almost running off a cliff
1552  int32_t iLowSideRange=5;
1553  if (!(GBackDensity(cx,cy+cObj->Shape.Hgt/2) >= cObj->Shape.ContactDensity))
1554  {
1555  if (cObj->t_contact & CNAT_Right)
1556  if (Inside(iAngle-JumpLowAngle,-iLowSideRange*JumpAngleRange,+iLowSideRange*JumpAngleRange))
1557  {
1558  cObj->AddCommand(C4CMD_Jump,nullptr,Tx,Ty); return true;
1559  }
1560  if (cObj->t_contact & CNAT_Left)
1561  if (Inside(iAngle+JumpLowAngle,-iLowSideRange*JumpAngleRange,+iLowSideRange*JumpAngleRange))
1562  {
1563  cObj->AddCommand(C4CMD_Jump,nullptr,Tx,Ty); return true;
1564  }
1565  }
1566 
1567  // No jump control
1568  return false;
1569 }
const int32_t JumpLowAngle
Definition: C4Command.cpp:40
const int32_t JumpAngleRange
Definition: C4Command.cpp:40
const int32_t JumpHighAngle
Definition: C4Command.cpp:40
const int32_t JumpAngle
Definition: C4Command.cpp:40
int32_t SolidOnWhichSide(int32_t iX, int32_t iY)
Definition: C4Command.cpp:186
const BYTE CNAT_Right
Definition: C4Constants.h:110
const BYTE CNAT_Left
Definition: C4Constants.h:109
int32_t GBackDensity(int32_t x, int32_t y)
Definition: C4Landscape.h:224
T Abs(T val)
Definition: Standard.h:42
uint32_t t_contact
Definition: C4Object.h:131
int32_t ContactDensity
Definition: C4Shape.h:47

References C4Value::_getInt(), Abs(), C4Object::AddCommand(), AdjustMoveToTarget(), Angle(), C4CMD_Jump, C4CMD_MoveTo, CNAT_Left, CNAT_Right, cObj, C4Shape::ContactDensity, C4Object::Def, Distance(), GBackDensity(), GBackSolid(), C4Object::GetX(), C4Object::GetY(), C4Shape::GetY(), C4Rect::Hgt, Inside(), JumpAngle, JumpAngleRange, JumpHighAngle, JumpLowAngle, C4Object::OCF, OCF_CrewMember, C4Def::Pathfinder, PathFree(), C4Object::Shape, SolidOnWhichSide(), C4Object::t_contact, Tx, and Ty.

Referenced by MoveTo().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MoveTo()

void C4Command::MoveTo ( )
protected

Definition at line 257 of file C4Command.cpp.

258 {
259  // Determine move-to range
260  int32_t iMoveToRange = MoveToRange;
261  if (cObj->Def->MoveToRange > 0) iMoveToRange = cObj->Def->MoveToRange;
262 
263  // Current object position
264  int32_t cx,cy; cx=cObj->GetX(); cy=cObj->GetY();
265  bool fWaypoint=false;
266  if (Next && (Next->Command==C4CMD_MoveTo)) fWaypoint=true;
267 
268  // Contained: exit
269  if (cObj->Contained)
270  { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
271 
272  // Check path (crew members or specific only)
273  if ((cObj->OCF & OCF_CrewMember) || cObj->Def->Pathfinder)
274  if (!PathChecked)
275  // Not too far
276  if (Distance(cx,cy,Tx._getInt(),Ty)<MaxPathRange)
277  // Not too close
278  if (!(Inside(cx-Tx._getInt(),-PathRange,+PathRange) && Inside(cy-Ty,-PathRange,+PathRange)))
279  {
280  // Path not free: find path
281  if (!PathFree(cx,cy,Tx._getInt(),Ty))
282  {
285  if (!Game.PathFinder.Find( cObj->GetX(),cObj->GetY(),
286  Tx._getInt(),Ty,
288  { /* Path not found: react? */ PathChecked=true; /* recheck delay */ }
289  return;
290  }
291  // Path free: recheck delay
292  else
293  PathChecked=true;
294  }
295  // Path recheck
296  if (!::Game.iTick35) PathChecked=false;
297 
298  // Pushing grab only or not desired: let go (pulling, too?)
299  if (cObj->GetProcedure()==DFA_PUSH)
300  if (cObj->Action.Target)
302  {
303  // Re-evaluate this command because vehicle control might have blocked evaluation
304  Evaluated=false;
305  cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return;
306  }
307 
308  // Special by procedure
309  switch (cObj->GetProcedure())
310  {
311  // Push/pull
312  case DFA_PUSH: case DFA_PULL:
313  // Use target object's position if on final waypoint
314  if (!fWaypoint)
315  if (cObj->Action.Target)
316  { cx=cObj->Action.Target->GetX(); cy=cObj->Action.Target->GetY(); }
317  break;
318  // dig: stop
319  case DFA_DIG:
321  break;
322  }
323 
324  // Target range
325  int32_t iTargetRange = iMoveToRange;
326  int32_t iRangeFactorTop=1, iRangeFactorBottom=1, iRangeFactorSide=1;
327 
328  // Crew members/pathfinder specific target range
329  if (cObj->OCF & OCF_CrewMember) // || cObj->Def->Pathfinder ? (Sven2)
330  {
331  // Range by size
332  iTargetRange=cObj->Shape.Wdt/2;
333  // Easier range if waypoint
334  if (fWaypoint)
335  if (cObj->GetProcedure()!=DFA_SCALE)
336  { iRangeFactorTop=3; iRangeFactorSide=3; iRangeFactorBottom=2; }
337  }
338 
339  // Target reached (success)
340  if (Inside(cx-Tx._getInt(),-iRangeFactorSide*iTargetRange,+iRangeFactorSide*iTargetRange)
341  && Inside(cy-Ty,-iRangeFactorBottom*iTargetRange,+iRangeFactorTop*iTargetRange))
342  {
344  Finish(true); return;
345  }
346 
347  // Idles can't move to
348  if (!cObj->GetAction())
349  { Finish(); return; }
350 
351  // Action
352  switch (cObj->GetProcedure())
353  {
354  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
355  case DFA_WALK:
356  // Head to target
357  if (cx<Tx._getInt()-iTargetRange) cObj->Action.ComDir=COMD_Right;
358  if (cx>Tx._getInt()+iTargetRange) cObj->Action.ComDir=COMD_Left;
359  // Flight control
360  if (FlightControl()) return;
361  // Jump control
362  if (JumpControl()) return;
363  break;
364  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
365  case DFA_PUSH: case DFA_PULL:
366  // Head to target
367  if (cx<Tx._getInt()-iTargetRange) cObj->Action.ComDir=COMD_Right;
368  if (cx>Tx._getInt()+iTargetRange) cObj->Action.ComDir=COMD_Left;
369  break;
370  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
371  case DFA_SCALE:
372  // Head to target
373  if (cy>Ty+iTargetRange) cObj->Action.ComDir=COMD_Up;
374  if (cy<Ty-iTargetRange) cObj->Action.ComDir=COMD_Down;
375  // Let-Go Control
376  if (cObj->Action.Dir==DIR_Left)
377  {
378  // Target direction
379  if ((Tx._getInt()>cx+LetGoRange1) && (Inside(cy-Ty,-LetGoRange2,+LetGoRange2)))
380  { ObjectComLetGo(cObj,+1); return; }
381  // Contact (not if just started)
382  if (cObj->Action.Time>2)
383  if (cObj->t_contact/* & CNAT_Left*/)
384  { ObjectComLetGo(cObj,+1); return; }
385  }
386  if (cObj->Action.Dir==DIR_Right)
387  {
388  // Target direction
389  if ((Tx._getInt()<cx-LetGoRange1) && (Inside(cy-Ty,-LetGoRange2,+LetGoRange2)))
390  { ObjectComLetGo(cObj,-1); return; }
391  // Contact (not if just started)
392  if (cObj->Action.Time>2)
393  if (cObj->t_contact/* & CNAT_Right*/)
394  { ObjectComLetGo(cObj,-1); return; }
395  }
396  break;
397  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
398  case DFA_SWIM:
399  // Head to target
400  if (::Game.iTick2)
401  {
402  if (cx<Tx._getInt()-iTargetRange) cObj->Action.ComDir=COMD_Right;
403  if (cx>Tx._getInt()+iTargetRange) cObj->Action.ComDir=COMD_Left;
404  }
405  else
406  {
407  if (cy<Ty) cObj->Action.ComDir=COMD_Down;
408  if (cy>Ty) cObj->Action.ComDir=COMD_Up;
409  }
410  break;
411  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
412  case DFA_HANGLE:
413  // Head to target
414  if (cx<Tx._getInt()-iTargetRange) cObj->Action.ComDir=COMD_Right;
415  if (cx>Tx._getInt()+iTargetRange) cObj->Action.ComDir=COMD_Left;
416  // Let-Go Control
417  if (Abs(Angle(cx,cy,Tx._getInt(),Ty))>LetGoHangleAngle)
418  ObjectComLetGo(cObj,0);
419  break;
420  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
421  case DFA_FLOAT:
422  {
423  C4Real dx = itofix(Tx._getInt()) - cObj->fix_x, dy = itofix(Ty) - cObj->fix_y;
424  // normalize
425  C4Real dScale = C4REAL100(cObj->GetAction()->GetPropertyInt(P_Speed)) / std::max(Abs(dx), Abs(dy));
426  dx *= dScale; dy *= dScale;
427  // difference to momentum
428  dx -= cObj->xdir; dy -= cObj->ydir;
429  // steer
430  if (Abs(dx)+Abs(dy) < C4REAL100(20)) cObj->Action.ComDir = COMD_Stop;
431  else if (Abs(dy) * 3 < dx) cObj->Action.ComDir = COMD_Right;
432  else if (Abs(dy) * 3 < -dx) cObj->Action.ComDir = COMD_Left;
433  else if (Abs(dx) * 3 < dy) cObj->Action.ComDir = COMD_Down;
434  else if (Abs(dx) * 3 < -dy) cObj->Action.ComDir = COMD_Up;
435  else if (dx > 0 && dy > 0) cObj->Action.ComDir = COMD_DownRight;
436  else if (dx < 0 && dy > 0) cObj->Action.ComDir = COMD_DownLeft;
437  else if (dx > 0 && dy < 0) cObj->Action.ComDir = COMD_UpRight;
438  else cObj->Action.ComDir = COMD_UpLeft;
439  }
440  break;
441  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
442  case DFA_FLIGHT:
443  // Try to move into right direction
444  if (cx<Tx._getInt()-iTargetRange) cObj->Action.ComDir=COMD_Right;
445  if (cx>Tx._getInt()+iTargetRange) cObj->Action.ComDir=COMD_Left;
446  // Flight control
447  if (FlightControl()) return;
448  break;
449  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
450  }
451 
452 }
const int32_t PathRange
Definition: C4Command.cpp:39
const int32_t LetGoRange1
Definition: C4Command.cpp:37
const int32_t MaxPathRange
Definition: C4Command.cpp:39
const int32_t LetGoRange2
Definition: C4Command.cpp:37
const int32_t LetGoHangleAngle
Definition: C4Command.cpp:42
#define COMD_Up
Definition: C4Object.h:51
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
C4Real C4REAL100(int x)
Definition: C4Real.h:267
@ DFA_SWIM
@ DFA_FLOAT
@ P_Speed
@ DFA_PULL
int32_t Time
Definition: C4Object.h:83
bool JumpControl()
Definition: C4Command.cpp:1505
bool FlightControl()
Definition: C4Command.cpp:1471
int32_t NoTransferZones
Definition: C4Def.h:146
Definition: C4Real.h:59
C4PathFinder PathFinder
Definition: C4Game.h:84
int32_t iTick2
Definition: C4Game.h:130
int32_t iTick35
Definition: C4Game.h:130
C4Real ydir
Definition: C4Object.h:124
C4Real fix_y
Definition: C4Object.h:123
C4Real xdir
Definition: C4Object.h:124
C4Real fix_x
Definition: C4Object.h:123
void EnableTransferZones(bool fEnabled)
void SetLevel(int iLevel)
bool Find(int32_t iFromX, int32_t iFromY, int32_t iToX, int32_t iToY, SetWaypointFn fnSetWaypoint)

References C4Value::_getInt(), Abs(), C4Object::Action, C4Object::AddCommand(), Angle(), C4CMD_Exit, C4CMD_MoveTo, C4CMD_MoveTo_PushTarget, C4CMD_UnGrab, C4REAL100(), cObj, COMD_Down, COMD_DownLeft, COMD_DownRight, COMD_Left, COMD_Right, COMD_Stop, COMD_Up, COMD_UpLeft, COMD_UpRight, C4Action::ComDir, Command, C4Object::Contained, Data, C4Object::Def, DFA_DIG, DFA_FLIGHT, DFA_FLOAT, DFA_HANGLE, DFA_PULL, DFA_PUSH, DFA_SCALE, DFA_SWIM, DFA_WALK, C4Action::Dir, DIR_Left, DIR_Right, Distance(), C4PathFinder::EnableTransferZones(), Evaluated, C4PathFinder::Find(), Finish(), C4Object::fix_x, C4Object::fix_y, FlightControl(), Game, C4Object::GetAction(), C4Value::getInt(), C4Object::GetProcedure(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), Inside(), C4Game::iTick2, C4Game::iTick35, itofix(), JumpControl(), LetGoHangleAngle, LetGoRange1, LetGoRange2, MaxPathRange, MoveToRange, C4Def::MoveToRange, Next, C4Def::NoTransferZones, ObjectComLetGo(), ObjectComStop(), C4Object::OCF, OCF_CrewMember, P_Speed, P_Touchable, PathChecked, C4Game::PathFinder, C4Def::Pathfinder, PathFree(), PathRange, C4PathFinder::SetLevel(), C4Object::Shape, C4Object::t_contact, C4Action::Target, C4Action::Time, Tx, Ty, C4Rect::Wdt, C4Object::xdir, and C4Object::ydir.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PushTo()

void C4Command::PushTo ( )
protected

Definition at line 701 of file C4Command.cpp.

702 {
703  // Target check
704  if (!Target) { Finish(); return; }
705 
706  // Target is target self: fail
707  if (Target==Target2) { Finish(); return; }
708 
709  // Command fulfilled
710  if (Target2)
711  {
712  // Object in correct target container: success
713  if (Target->Contained==Target2)
714  { Finish(true); return; }
715  }
716  else
717  {
718  // Object at target position: success
721  {
724  cObj->AddCommand(C4CMD_Wait,nullptr,0,0,10);
725  Finish(true); return;
726  }
727  }
728 
729  // Digging: stop
731 
732  // Target contained: activate
733  if (Target->Contained)
734  { cObj->AddCommand(C4CMD_Activate,Target,0,0,40); return; }
735 
736  // Grab target
737  if (!((cObj->GetProcedure()==DFA_PUSH) && (cObj->Action.Target==Target)))
738  { cObj->AddCommand(C4CMD_Grab,Target,0,0,40); return; }
739 
740  // Move to target position / enter target object
741  if (Target2)
742  { cObj->AddCommand(C4CMD_Enter,Target2,0,0,40, nullptr, true, C4Value(C4CMD_Enter_PushTarget)); return; }
743  else
744  { cObj->AddCommand(C4CMD_MoveTo,nullptr,Tx,Ty,40, nullptr, true, C4Value(C4CMD_MoveTo_PushTarget)); return; }
745 
746 }
const int32_t PushToRange
Definition: C4Command.cpp:38

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4CMD_Activate, C4CMD_Enter, C4CMD_Enter_PushTarget, C4CMD_Grab, C4CMD_MoveTo, C4CMD_MoveTo_PushTarget, C4CMD_UnGrab, C4CMD_Wait, cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, DFA_DIG, DFA_PUSH, Finish(), C4Object::GetProcedure(), C4Object::GetX(), C4Object::GetY(), Inside(), ObjectComStop(), PushToRange, Target, C4Action::Target, Target2, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Put()

void C4Command::Put ( )
protected

Definition at line 1173 of file C4Command.cpp.

1174 {
1175  // No target container: failure
1176  if (!Target) { Finish(); return; }
1177 
1178  // Thing to put specified by type
1179  if (!Target2 && Data)
1180  if (!(Target2 = cObj->Contents.Find(Data.getDef())))
1181  { Finish(); return; }
1182 
1183  // No thing to put specified
1184  if (!Target2)
1185  // Assume first contents object
1186  if (!(Target2 = cObj->Contents.GetObject()))
1187  // No contents object to put - most likely we did have a target but it was deleted,
1188  // e.g. by AutoSellContents in a base. New behaviour: if there is nothing to put, we
1189  // now consider the command succesfully completed.
1190  { Finish(true); return; }
1191 
1192  // Thing is in target
1193  if (Target2->Contained == Target)
1194  {
1195  // Put-count specified: decrease count and continue with next object
1196  if (Tx._getInt() > 1)
1197  { Target2 = nullptr; Tx--; return; }
1198  // We're done
1199  else
1200  { Finish(true); return; }
1201  }
1202 
1203  // Thing to put not in contents: get object
1204  if (!cObj->Contents.GetLink(Target2))
1205  {
1206  // Object is nearby and traveling: wait
1207  if (!Target2->Contained)
1208  if (Distance(cObj->GetX(),cObj->GetY(),Target2->GetX(),Target2->GetY())<80)
1209  if (Target2->OCF & OCF_HitSpeed1)
1210  return;
1211  // Go get it
1212  cObj->AddCommand(C4CMD_Get,Target2,0,0,40); return;
1213  }
1214 
1215  // Target is contained: can't do it
1216  if (Target->Contained)
1217  { Finish(); return; }
1218 
1219  // Digging: stop
1221 
1222  // Grabbing other than target: let go
1223  C4Object *pGrabbing=nullptr;
1224  if (cObj->GetProcedure()==DFA_PUSH)
1225  pGrabbing = cObj->Action.Target;
1226  if (pGrabbing && (pGrabbing!=Target))
1227  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
1228 
1229  // Inside target container
1230  if (cObj->Contained == Target)
1231  {
1232  // Try to put
1234  Finish(); // Putting failed
1235  return;
1236  }
1237 
1238  // Leave own container
1239  if (cObj->Contained)
1240  { cObj->AddCommand(C4CMD_Exit,nullptr,0,0,50); return; }
1241 
1242  // Target has collection: throw in if not fragile, not grabbing target and throwing position found
1243  if (Target->OCF & OCF_Collection)
1244  if (!Target2->Def->Fragile)
1245  if (pGrabbing!=Target)
1246  {
1247  int32_t iTx = Target->GetX() + Target->Def->Collection.x + Target->Def->Collection.Wdt/2;
1248  int32_t iTy = Target->GetY() + Target->Def->Collection.y + Target->Def->Collection.Hgt/2;
1250  int32_t iHeight = cObj->Shape.Hgt;
1251  int32_t iPosX,iPosY;
1252  int32_t iObjDist = Distance(cObj->GetX(),cObj->GetY(),Target->GetX(),Target->GetY());
1253  if ( (FindThrowingPosition(iTx,iTy,pthrow,-pthrow,iHeight,iPosX,iPosY) && (Distance(iPosX,iPosY,cObj->GetX(),cObj->GetY()) < iObjDist))
1254  || (FindThrowingPosition(iTx,iTy,pthrow*-1,-pthrow,iHeight,iPosX,iPosY) && (Distance(iPosX,iPosY,cObj->GetX(),cObj->GetY()) < iObjDist)) )
1255  {
1256  // Throw
1257  cObj->AddCommand(C4CMD_Throw,Target2,iTx,iTy,5);
1258  return;
1259  }
1260  }
1261 
1262  // Target has C4D_Grab_Put: grab target and put
1264  {
1265  // Grabbing target container
1266  if (pGrabbing==Target)
1267  {
1268  // Try to put
1270  // Putting failed
1271  { Finish(); return; }
1272  // Let go (if we grabbed the target because of this command)
1273  if (Ty) cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0);
1274  return;
1275  }
1276  // Grab target and let go after putting
1277  cObj->AddCommand(C4CMD_Grab,Target,0,0,50);
1278  Ty = 1;
1279  return;
1280  }
1281 
1282  // Target can be entered: enter target
1283  if (Target->OCF & OCF_Entrance)
1284  { cObj->AddCommand(C4CMD_Enter,Target,0,0,50); return; }
1285 
1286 }
const uint32_t OCF_HitSpeed1
Definition: C4Constants.h:84
const int32_t C4D_Grab_Put
Definition: C4Def.h:62
bool FindThrowingPosition(int32_t iTx, int32_t iTy, C4Real fXDir, C4Real fYDir, int32_t iHeight, int32_t &rX, int32_t &rY)
bool ObjectComPut(C4Object *cObj, C4Object *pTarget, C4Object *pThing)
@ P_ThrowSpeed
int32_t Fragile
Definition: C4Def.h:130
C4Object * GetObject(int index=0) const
int32_t x
Definition: C4Rect.h:30

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4CMD_Enter, C4CMD_Exit, C4CMD_Get, C4CMD_Grab, C4CMD_Throw, C4CMD_UnGrab, C4D_Grab_Put, C4REAL100(), cObj, C4Def::Collection, C4Object::Contained, C4Object::Contents, Data, C4Object::Def, DFA_DIG, DFA_PUSH, Distance(), C4ObjectList::Find(), FindThrowingPosition(), Finish(), C4Def::Fragile, C4Value::getDef(), C4ObjectList::GetLink(), C4ObjectList::GetObject(), C4Object::GetProcedure(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), C4Def::GrabPutGet, C4Rect::Hgt, ObjectComPut(), ObjectComStop(), C4Object::OCF, OCF_Collection, OCF_Entrance, OCF_HitSpeed1, P_ThrowSpeed, C4Object::Shape, Target, C4Action::Target, Target2, Tx, Ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Retry()

void C4Command::Retry ( )
protected

Definition at line 1800 of file C4Command.cpp.

1801 {
1802 
1803 }

Referenced by Execute().

Here is the caller graph for this function:

◆ Sell()

void C4Command::Sell ( )
protected

Definition at line 1650 of file C4Command.cpp.

1651 {
1652  Finish();
1653 }

References Finish().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Set()

void C4Command::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 at line 1810 of file C4Command.cpp.

1813 {
1814  // Reset
1815  Clear(); Default();
1816  // Set
1817  Command=iCommand;
1818  cObj=pObj;
1819  Target=pTarget;
1820  Tx=nTx; Ty=iTy;
1822  Tx.SetInt(0);
1823  Target2=pTarget2;
1824  Data=iData;
1825  UpdateInterval=iUpdateInterval;
1826  Evaluated=fEvaluated;
1827  Retries=iRetries;
1828  Text = szText;
1829  if (Text) Text->IncRef();
1830  BaseMode=iBaseMode;
1831 }
@ C4V_Int
Definition: C4Value.h:26
ALWAYS_INLINE bool CheckConversion(C4V_Type vtToType) const
Definition: C4Value.h:189

References BaseMode, C4CMD_Call, C4V_Int, C4Value::CheckConversion(), Clear(), cObj, Command, Data, Default(), Evaluated, C4RefCnt::IncRef(), Retries, C4Value::SetInt(), Target, Target2, Text, Tx, Ty, and UpdateInterval.

Referenced by C4Object::AddCommand().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Take()

void C4Command::Take ( )
protected

Definition at line 829 of file C4Command.cpp.

830 {
832  Finish(true);
833 }
bool ObjectComTake(C4Object *cObj)

References cObj, Finish(), and ObjectComTake().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Take2()

void C4Command::Take2 ( )
protected

Definition at line 835 of file C4Command.cpp.

836 {
838  Finish(true);
839 }
bool ObjectComTake2(C4Object *cObj)

References cObj, Finish(), and ObjectComTake2().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Throw()

void C4Command::Throw ( )
protected

Definition at line 755 of file C4Command.cpp.

756 {
757 
758  // Digging: stop
760 
761  // Throw specific object not in contents: get object
762  if (Target)
763  if (!cObj->Contents.GetLink(Target))
764  {
765  cObj->AddCommand(C4CMD_Get,Target,0,0,40);
766  return;
767  }
768 
769  // Determine move-to range
770  int32_t iMoveToRange = MoveToRange;
771  if (cObj->Def->MoveToRange > 0) iMoveToRange = cObj->Def->MoveToRange;
772 
773  // Target coordinates are not default 0/0: targeted throw
774  if ((Tx._getInt()!=0) || (Ty!=0))
775  {
776 
777  // Grabbing: let go
778  if (cObj->GetProcedure()==DFA_PUSH)
779  { cObj->AddCommand(C4CMD_UnGrab,nullptr,0,0,50); return; }
780 
781  // Preferred throwing direction
782  int32_t iDir=+1; if (cObj->GetX() > Tx._getInt()) iDir=-1;
783 
784  // Find throwing position
785  int32_t iTx,iTy;
787  int32_t iHeight = cObj->Shape.Hgt;
788  if (!FindThrowingPosition(Tx._getInt(),Ty,pthrow*iDir,-pthrow,iHeight,iTx,iTy))
789  if (!FindThrowingPosition(Tx._getInt(),Ty,pthrow*iDir*-1,-pthrow,iHeight,iTx,iTy))
790  // No throwing position: fail
791  { Finish(); return; }
792 
793  // At throwing position: face target and throw
794  if (Inside<int32_t>(cObj->GetX() - iTx, -iMoveToRange, +iMoveToRange) && Inside<int32_t>(cObj->GetY()-iTy,-15,+15))
795  {
796  if (cObj->GetX() < Tx._getInt()) cObj->SetDir(DIR_Right); else cObj->SetDir(DIR_Left);
799  Finish(true); // Throw successfull: done, else continue
800  return;
801  }
802 
803  // Move to target position
804  cObj->AddCommand(C4CMD_MoveTo,nullptr,iTx,iTy,20);
805 
806  return;
807  }
808 
809  // Contained: put or take
810  if (cObj->Contained)
811  {
813  Finish(true); return;
814  }
815 
816  // Pushing: put or take
817  if (cObj->GetProcedure()==DFA_PUSH)
818  {
819  if (cObj->Action.Target)
821  Finish(true); return;
822  }
823 
824  // Outside: Throw
826  Finish(true);
827 }
bool ObjectComThrow(C4Object *cObj, C4Object *pThing)

References C4Value::_getInt(), C4Object::Action, C4Object::AddCommand(), C4CMD_Get, C4CMD_MoveTo, C4CMD_UnGrab, C4REAL100(), cObj, COMD_Stop, C4Action::ComDir, C4Object::Contained, C4Object::Contents, C4Object::Def, DFA_DIG, DFA_PUSH, DIR_Left, DIR_Right, FindThrowingPosition(), Finish(), C4ObjectList::GetLink(), C4Object::GetProcedure(), C4PropList::GetPropertyInt(), C4Object::GetX(), C4Object::GetY(), C4Rect::Hgt, MoveToRange, C4Def::MoveToRange, ObjectComPutTake(), ObjectComStop(), ObjectComThrow(), P_ThrowSpeed, C4Object::SetDir(), C4Object::Shape, Target, C4Action::Target, Tx, and Ty.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Transfer()

void C4Command::Transfer ( )
protected

Definition at line 1571 of file C4Command.cpp.

1572 {
1573 
1574  // No target: failure
1575  if (!Target) { Finish(); return; }
1576 
1577  // Find transfer zone
1578  C4TransferZone *pZone;
1579  int32_t iEntryX,iEntryY;
1580  if (!(pZone=Game.TransferZones.Find(Target))) { Finish(); return; }
1581 
1582  // Not at or in transfer zone: move to entry point
1583  if (!Inside<int32_t>(cObj->GetX()-pZone->X,-5,pZone->Wdt-1+5))
1584  {
1585  if (!pZone->GetEntryPoint(iEntryX,iEntryY,cObj->GetX(),cObj->GetY())) { Finish(); return; }
1586  cObj->AddCommand(C4CMD_MoveTo,nullptr,iEntryX,iEntryY,25);
1587  return;
1588  }
1589 
1590  // Call target transfer script
1591  if (!::Game.iTick5)
1592  {
1593  if (!Target->Call(PSF_ControlTransfer, &C4AulParSet(cObj, Tx, Ty)).getBool())
1594  // Transfer not handled by target: done
1595  { Finish(true); return; }
1596  }
1597 
1598 }
#define PSF_ControlTransfer
Definition: C4GameScript.h:78
C4TransferZones TransferZones
Definition: C4Game.h:85
int32_t iTick5
Definition: C4Game.h:130
bool GetEntryPoint(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY)
C4TransferZone * Find(C4Object *pObj)

References C4Object::AddCommand(), C4CMD_MoveTo, C4PropList::Call(), cObj, C4TransferZones::Find(), Finish(), Game, C4TransferZone::GetEntryPoint(), C4Object::GetX(), C4Object::GetY(), C4Game::iTick5, PSF_ControlTransfer, Target, C4Game::TransferZones, Tx, Ty, C4TransferZone::Wdt, and C4TransferZone::X.

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UnGrab()

void C4Command::UnGrab ( )
protected

Definition at line 748 of file C4Command.cpp.

749 {
752  Finish(true);
753 }
bool ObjectComUnGrab(C4Object *cObj)

References C4Object::Action, cObj, COMD_Stop, C4Action::ComDir, Finish(), and ObjectComUnGrab().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Wait()

void C4Command::Wait ( )
protected

Definition at line 920 of file C4Command.cpp.

921 {
922  // Digging: stop
924 }

References cObj, DFA_DIG, C4Object::GetProcedure(), and ObjectComStop().

Referenced by Execute().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ BaseMode

int32_t C4Command::BaseMode

Definition at line 92 of file C4Command.h.

Referenced by Clear(), CompileFunc(), Default(), Fail(), and Set().

◆ cObj

◆ Command

◆ Data

◆ Evaluated

int32_t C4Command::Evaluated

Definition at line 87 of file C4Command.h.

Referenced by Clear(), CompileFunc(), Default(), InitEvaluation(), MoveTo(), and Set().

◆ Failures

int32_t C4Command::Failures

Definition at line 88 of file C4Command.h.

Referenced by CompileFunc(), Default(), Execute(), and Fail().

◆ Finished

int32_t C4Command::Finished

◆ iExec

int32_t C4Command::iExec

Definition at line 91 of file C4Command.h.

Referenced by C4Object::ClearCommand(), C4Object::ClearCommands(), Default(), and Execute().

◆ Next

◆ PathChecked

int32_t C4Command::PathChecked

Definition at line 87 of file C4Command.h.

Referenced by Clear(), CompileFunc(), Default(), and MoveTo().

◆ Permit

int32_t C4Command::Permit

Definition at line 88 of file C4Command.h.

Referenced by CompileFunc(), and Default().

◆ Retries

int32_t C4Command::Retries

Definition at line 88 of file C4Command.h.

Referenced by CompileFunc(), Default(), Execute(), Fail(), and Set().

◆ Target

◆ Target2

◆ Text

C4String* C4Command::Text

Definition at line 89 of file C4Command.h.

Referenced by Call(), CallFailed(), Clear(), CompileFunc(), Default(), C4Object::Draw(), and Set().

◆ Tx

◆ Ty

◆ UpdateInterval

int32_t C4Command::UpdateInterval

Definition at line 86 of file C4Command.h.

Referenced by Clear(), CompileFunc(), Default(), Execute(), InitEvaluation(), and Set().


The documentation for this class was generated from the following files: