OpenClonk
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

◆ DoBridge()

bool DoBridge ( C4Object clk)

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

Definition at line 3144 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.

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

◆ GrabLost()

void GrabLost ( C4Object cObj,
C4Object prev_target 
)

Definition at line 2872 of file C4Object.cpp.

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

Referenced by C4Object::NoAttachAction().

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

◆ ReduceLineSegments()

bool ReduceLineSegments ( C4Shape rShape,
bool  fAlternate 
)

Definition at line 3255 of file C4Object.cpp.

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

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

◆ StopActionDelayCommand()

void StopActionDelayCommand ( C4Object cobj)

Definition at line 3249 of file C4Object.cpp.

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

3250 {
3251  ObjectComStop(cobj);
3252  cobj->AddCommand(C4CMD_Wait,nullptr,0,0,50);
3253 }
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:2567
bool ObjectComStop(C4Object *cObj)
Here is the call graph for this function:

◆ Towards()

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

Definition at line 3137 of file C4Object.cpp.

References Abs().

3138 {
3139  if (val==target) return;
3140  if (Abs(val-target)<=step) { val=target; return; }
3141  if (val<target) val+=step; else val-=step;
3142 }
T Abs(T val)
Definition: Standard.h:42
Here is the call graph for this function: