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 3143 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().

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

2872 {
2873  // Grab lost script call on target (quite hacky stuff...)
2874  if (prev_target && prev_target->Status) prev_target->Call(PSF_GrabLost);
2875  // Clear commands down to first PushTo (if any) in command stack
2876  for (C4Command *pCom=cObj->Command; pCom; pCom=pCom->Next)
2877  if (pCom->Next && pCom->Next->Command==C4CMD_PushTo)
2878  {
2879  cObj->ClearCommand(pCom);
2880  break;
2881  }
2882 }
C4Command * Next
Definition: C4Command.h:90
C4Command * Command
Definition: C4Object.h:166
void ClearCommand(C4Command *pUntil)
Definition: C4Object.cpp:2549
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 3254 of file C4Object.cpp.

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

Referenced by C4Object::ExecAction().

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

Here is the call graph for this function:

Here is the caller graph for this function:

void StopActionDelayCommand ( C4Object cobj)

Definition at line 3248 of file C4Object.cpp.

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

Referenced by C4Object::ExecAction().

3249 {
3250  ObjectComStop(cobj);
3251  cobj->AddCommand(C4CMD_Wait,nullptr,0,0,50);
3252 }
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:2566
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 3136 of file C4Object.cpp.

References Abs().

3137 {
3138  if (val==target) return;
3139  if (Abs(val-target)<=step) { val=target; return; }
3140  if (val<target) val+=step; else val-=step;
3141 }
T Abs(T val)
Definition: Standard.h:42

Here is the call graph for this function: