OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Object.cpp File Reference
Include dependency graph for C4Object.cpp:

Go to the source code of this file.

Functions

void GrabLost (C4Object *cObj, C4Object *prev_target)
 
void Towards (C4Real &val, C4Real target, C4Real step)
 
bool DoBridge (C4Object *clk)
 
void StopActionDelayCommand (C4Object *cobj)
 
bool ReduceLineSegments (C4Shape &rShape, bool fAlternate)
 

Function Documentation

bool DoBridge ( C4Object clk)

clk->Shape.Attach(cx2, cy2, (clk->Action.t_attach & CNAT_Flags) | CNAT_Bottom) ||

Definition at line 3139 of file C4Object.cpp.

References C4Object::Action, C4Shape::CheckContact(), COMD_Left, COMD_Right, COMD_Up, COMD_UpLeft, COMD_UpRight, C4Action::ComDir, C4Action::Dir, DIR_Right, C4Landscape::DrawMaterialRect(), C4Action::GetBridgeData(), C4Object::GetX(), C4Object::GetY(), C4Rect::Hgt, Landscape, C4Object::MovePosition(), ObjectActionStand(), C4Action::SetBridgeData(), C4Object::Shape, C4Action::Time, and C4Rect::Wdt.

Referenced by C4Object::ExecAction().

3140 {
3141  int32_t iBridgeTime; bool fMoveClonk, fWall; int32_t iBridgeMaterial;
3142  clk->Action.GetBridgeData(iBridgeTime, fMoveClonk, fWall, iBridgeMaterial);
3143  if (!iBridgeTime) iBridgeTime = 100; // default bridge time
3144  if (clk->Action.Time>=iBridgeTime) { ObjectActionStand(clk); return false; }
3145  // get bridge advancement
3146  int32_t dtp;
3147  if (fWall) switch (clk->Action.ComDir)
3148  {
3149  case COMD_Left: case COMD_Right: dtp = 4; fMoveClonk = false; break; // vertical wall: default 25 pixels
3150  case COMD_UpLeft: case COMD_UpRight: dtp = 5; fMoveClonk = false; break; // diagonal roof over Clonk: default 20 pixels up and 20 pixels side (28 pixels - optimized to close tunnels completely)
3151  case COMD_Up: dtp = 5; break; // horizontal roof over Clonk
3152  default: return true; // bridge procedure just for show
3153  }
3154  else switch (clk->Action.ComDir)
3155  {
3156  case COMD_Left: case COMD_Right: dtp = 5; break; // horizontal bridges: default 20 pixels
3157  case COMD_Up: dtp = 4; break; // vertical bridges: default 25 pixels (same as
3158  case COMD_UpLeft: case COMD_UpRight: dtp = 6; break; // diagonal bridges: default 16 pixels up and 16 pixels side (23 pixels)
3159  default: return true; // bridge procedure just for show
3160  }
3161  if (clk->Action.Time % dtp) return true; // no advancement in this frame
3162  // get target pos for Clonk and bridge
3163  int32_t cx=clk->GetX(), cy=clk->GetY(), cw=clk->Shape.Wdt, ch=clk->Shape.Hgt;
3164  int32_t tx=cx,ty=cy+ch/2;
3165  int32_t dt;
3166  if (fMoveClonk) dt = 0; else dt = clk->Action.Time / dtp;
3167  if (fWall) switch (clk->Action.ComDir)
3168  {
3169  case COMD_Left: tx-=cw/2; ty+=-dt; break;
3170  case COMD_Right: tx+=cw/2; ty+=-dt; break;
3171  case COMD_Up:
3172  {
3173  int32_t x0;
3174  if (fMoveClonk) x0=-3; else x0=(iBridgeTime/dtp)/-2;
3175  tx+=(x0+dt)*((clk->Action.Dir==DIR_Right)*2-1); cx+=((clk->Action.Dir==DIR_Right)*2-1); ty-=ch+3; break;
3176  }
3177  case COMD_UpLeft: tx-=-4+dt; ty+=-ch-7+dt; break;
3178  case COMD_UpRight: tx+=-4+dt; ty+=-ch-7+dt; break;
3179  }
3180  else switch (clk->Action.ComDir)
3181  {
3182  case COMD_Left: tx+=-3-dt; --cx; break;
3183  case COMD_Right: tx+=+2+dt; ++cx; break;
3184  case COMD_Up: tx+=(-cw/2+(cw-1)*(clk->Action.Dir==DIR_Right))*(!fMoveClonk); ty+=-dt-fMoveClonk; --cy; break;
3185  case COMD_UpLeft: tx+=-5-dt+fMoveClonk*3; ty+=2-dt-fMoveClonk*3; --cx; --cy; break;
3186  case COMD_UpRight: tx+=+5+dt-fMoveClonk*2; ty+=2-dt-fMoveClonk*3; ++cx; --cy; break;
3187  }
3188  // check if Clonk movement is posible
3189  if (fMoveClonk)
3190  {
3191  int32_t cx2=cx, cy2=cy;
3192  if ( clk->Shape.CheckContact(cx2, cy2-1))
3193  {
3194  // Clonk would collide here: Change to nonmoving Clonk mode and redo bridging
3195  iBridgeTime -= clk->Action.Time;
3196  clk->Action.Time = 0;
3197  if (fWall && clk->Action.ComDir==COMD_Up)
3198  {
3199  // special for roof above Clonk: The nonmoving roof is started at bridgelength before the Clonk
3200  // so, when interrupted, an action time halfway through the action must be set
3201  clk->Action.Time = iBridgeTime;
3202  iBridgeTime += iBridgeTime;
3203  }
3204  clk->Action.SetBridgeData(iBridgeTime, false, fWall, iBridgeMaterial);
3205  return DoBridge(clk);
3206  }
3207  }
3208  // draw bridge into landscape
3209  ::Landscape.DrawMaterialRect(iBridgeMaterial,tx-2,ty,4,3);
3210  // Move Clonk
3211  if (fMoveClonk) clk->MovePosition(cx-clk->GetX(), cy-clk->GetY());
3212  return true;
3213 }
int32_t GetY() const
Definition: C4Object.h:287
#define COMD_UpRight
Definition: C4Object.h:52
bool DoBridge(C4Object *clk)
Definition: C4Object.cpp:3139
void MovePosition(int32_t dx, int32_t dy)
Definition: C4Movement.cpp:522
int32_t Time
Definition: C4Object.h:83
#define DIR_Right
Definition: C4Object.h:42
int32_t Wdt
Definition: C4Rect.h:30
C4Landscape Landscape
int32_t GetX() const
Definition: C4Object.h:286
#define COMD_Right
Definition: C4Object.h:53
bool ObjectActionStand(C4Object *cObj)
Definition: C4ObjectCom.cpp:45
void DrawMaterialRect(int32_t mat, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt)
#define COMD_Up
Definition: C4Object.h:51
#define COMD_Left
Definition: C4Object.h:57
int32_t Dir
Definition: C4Object.h:80
bool CheckContact(int32_t cx, int32_t cy)
Definition: C4Shape.cpp:335
int32_t Hgt
Definition: C4Rect.h:30
C4Action Action
Definition: C4Object.h:147
C4Shape Shape
Definition: C4Object.h:148
void SetBridgeData(int32_t iBridgeTime, bool fMoveClonk, bool fWall, int32_t iBridgeMaterial)
Definition: C4Object.cpp:64
#define COMD_UpLeft
Definition: C4Object.h:58
int32_t ComDir
Definition: C4Object.h:82
void GetBridgeData(int32_t &riBridgeTime, bool &rfMoveClonk, bool &rfWall, int32_t &riBridgeMaterial)
Definition: C4Object.cpp:74

Here is the call graph for this function:

Here is the caller graph for this function:

void GrabLost ( C4Object cObj,
C4Object prev_target 
)

Definition at line 2867 of file C4Object.cpp.

References C4CMD_PushTo, C4PropList::Call(), C4Object::ClearCommand(), C4Object::Command, C4Command::Next, PSF_GrabLost, and C4PropList::Status.

Referenced by C4Object::ExecAction(), and C4Object::NoAttachAction().

2868 {
2869  // Grab lost script call on target (quite hacky stuff...)
2870  if (prev_target && prev_target->Status) prev_target->Call(PSF_GrabLost);
2871  // Clear commands down to first PushTo (if any) in command stack
2872  for (C4Command *pCom=cObj->Command; pCom; pCom=pCom->Next)
2873  if (pCom->Next && pCom->Next->Command==C4CMD_PushTo)
2874  {
2875  cObj->ClearCommand(pCom);
2876  break;
2877  }
2878 }
C4Command * Next
Definition: C4Command.h:90
C4Command * Command
Definition: C4Object.h:166
void ClearCommand(C4Command *pUntil)
Definition: C4Object.cpp:2545
int32_t Status
Definition: C4PropList.h:168
#define PSF_GrabLost
Definition: C4GameScript.h:75
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:110

Here is the call graph for this function:

Here is the caller graph for this function:

bool ReduceLineSegments ( C4Shape rShape,
bool  fAlternate 
)

Definition at line 3250 of file C4Object.cpp.

References PathFree(), C4Shape::RemoveVertex(), C4Shape::VtxNum, C4Shape::VtxX, and C4Shape::VtxY.

Referenced by C4Object::ExecAction().

3251 {
3252  // try if line could go by a path directly when skipping on evertex. If fAlternate is true, try by skipping two vertices
3253  for (int32_t cnt=0; cnt+2+fAlternate<rShape.VtxNum; cnt++)
3254  if (PathFree(rShape.VtxX[cnt],rShape.VtxY[cnt],
3255  rShape.VtxX[cnt+2+fAlternate],rShape.VtxY[cnt+2+fAlternate]))
3256  {
3257  if (fAlternate) rShape.RemoveVertex(cnt+2);
3258  rShape.RemoveVertex(cnt+1);
3259  return true;
3260  }
3261  return false;
3262 }
int32_t VtxNum
Definition: C4Shape.h:42
int32_t VtxX[C4D_MaxVertex]
Definition: C4Shape.h:43
bool RemoveVertex(int32_t iPos)
Definition: C4Shape.cpp:326
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
int32_t VtxY[C4D_MaxVertex]
Definition: C4Shape.h:44

Here is the call graph for this function:

Here is the caller graph for this function:

void StopActionDelayCommand ( C4Object cobj)

Definition at line 3244 of file C4Object.cpp.

References C4Object::AddCommand(), C4CMD_Wait, and ObjectComStop().

Referenced by C4Object::ExecAction().

3245 {
3246  ObjectComStop(cobj);
3247  cobj->AddCommand(C4CMD_Wait,nullptr,0,0,50);
3248 }
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)
Definition: C4Object.cpp:2562
bool ObjectComStop(C4Object *cObj)

Here is the call graph for this function:

Here is the caller graph for this function:

void Towards ( C4Real val,
C4Real  target,
C4Real  step 
)

Definition at line 3132 of file C4Object.cpp.

References Abs().

3133 {
3134  if (val==target) return;
3135  if (Abs(val-target)<=step) { val=target; return; }
3136  if (val<target) val+=step; else val-=step;
3137 }
T Abs(T val)
Definition: Standard.h:42

Here is the call graph for this function: