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

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

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

2875 {
2876  // Grab lost script call on target (quite hacky stuff...)
2877  if (prev_target && prev_target->Status) prev_target->Call(PSF_GrabLost);
2878  // Clear commands down to first PushTo (if any) in command stack
2879  for (C4Command *pCom=cObj->Command; pCom; pCom=pCom->Next)
2880  if (pCom->Next && pCom->Next->Command==C4CMD_PushTo)
2881  {
2882  cObj->ClearCommand(pCom);
2883  break;
2884  }
2885 }
C4Command * Next
Definition: C4Command.h:90
C4Command * Command
Definition: C4Object.h:166
void ClearCommand(C4Command *pUntil)
Definition: C4Object.cpp:2552
int32_t Status
Definition: C4PropList.h:170
#define PSF_GrabLost
Definition: C4GameScript.h:75
C4Value Call(C4PropertyName k, C4AulParSet *pPars=0, bool fPassErrors=false)
Definition: C4PropList.h:112

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 3257 of file C4Object.cpp.

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

Referenced by C4Object::ExecAction().

3258 {
3259  // try if line could go by a path directly when skipping on evertex. If fAlternate is true, try by skipping two vertices
3260  for (int32_t cnt=0; cnt+2+fAlternate<rShape.VtxNum; cnt++)
3261  if (PathFree(rShape.VtxX[cnt],rShape.VtxY[cnt],
3262  rShape.VtxX[cnt+2+fAlternate],rShape.VtxY[cnt+2+fAlternate]))
3263  {
3264  if (fAlternate) rShape.RemoveVertex(cnt+2);
3265  rShape.RemoveVertex(cnt+1);
3266  return true;
3267  }
3268  return false;
3269 }
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 3251 of file C4Object.cpp.

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

Referenced by C4Object::ExecAction().

3252 {
3253  ObjectComStop(cobj);
3254  cobj->AddCommand(C4CMD_Wait,nullptr,0,0,50);
3255 }
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:2569
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 3139 of file C4Object.cpp.

References Abs().

3140 {
3141  if (val==target) return;
3142  if (Abs(val-target)<=step) { val=target; return; }
3143  if (val<target) val+=step; else val-=step;
3144 }
T Abs(T val)
Definition: Standard.h:44

Here is the call graph for this function: