1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 1998-2000, Matthes Bender 5 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 6 * Copyright (c) 2009-2016, The OpenClonk Team and contributors 7 * 8 * Distributed under the terms of the ISC license; see accompanying file 9 * "COPYING" for details. 10 * 11 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 12 * See accompanying file "TRADEMARK" for details. 13 * 14 * To redistribute this file separately, substitute the full license texts 15 * for the above references. 16 */ 17 18 /* That which fills the world with life */ 19 20 #ifndef INC_C4Object 21 #define INC_C4Object 22 23 #include "game/C4GameScript.h" 24 #include "graphics/C4Facet.h" 25 #include "object/C4Id.h" 26 #include "object/C4ObjectPtr.h" 27 #include "object/C4Sector.h" 28 #include "object/C4Shape.h" 29 #include "script/C4PropList.h" 30 #include "script/C4Value.h" 31 32 /* Object status */ 33 34 #define C4OS_DELETED 0 35 #define C4OS_NORMAL 1 36 #define C4OS_INACTIVE 2 37 38 /* Action.Dir is the direction the object is actually facing. */ 39 40 #define DIR_None 0 41 #define DIR_Left 0 42 #define DIR_Right 1 43 44 /* Action.ComDir tells an active object which way it ought to be going. 45 If you set the ComDir to COMD_Stop, the object won't sit still immediately 46 but will try to slow down according to it's current Action. ComDir values 47 circle clockwise from COMD_Up 1 through COMD_UpLeft 8. */ 48 49 #define COMD_None -1 50 #define COMD_Stop 0 51 #define COMD_Up 1 52 #define COMD_UpRight 2 53 #define COMD_Right 3 54 #define COMD_DownRight 4 55 #define COMD_Down 5 56 #define COMD_DownLeft 6 57 #define COMD_Left 7 58 #define COMD_UpLeft 8 59 60 /* Visibility values tell conditions for an object's visibility */ 61 62 #define VIS_All 0 63 #define VIS_None 1 64 #define VIS_Owner 2 65 #define VIS_Allies 4 66 #define VIS_Enemies 8 67 #define VIS_Select 16 68 #define VIS_God 32 69 #define VIS_LayerToggle 64 70 #define VIS_OverlayOnly 128 71 #define VIS_Editor 256 72 73 74 class C4Action 75 { 76 public: 77 C4Action(); 78 ~C4Action(); 79 public: 80 int32_t Dir; 81 int32_t DrawDir; // NoSave // - needs to be calculated for old-style objects.txt anyway 82 int32_t ComDir; 83 int32_t Time; 84 int32_t Data; 85 int32_t Phase,PhaseDelay; 86 int32_t t_attach; // SyncClearance-NoSave // 87 C4ObjectPtr Target,Target2; 88 C4Facet Facet; // NoSave // 89 int32_t FacetX,FacetY; // NoSave // 90 StdMeshInstanceAnimationNode* Animation; // NoSave // 91 public: 92 void Default(); 93 void CompileFunc(StdCompiler *pComp); 94 95 // BRIDGE procedure: data mask 96 void SetBridgeData(int32_t iBridgeTime, bool fMoveClonk, bool fWall, int32_t iBridgeMaterial); 97 void GetBridgeData(int32_t &riBridgeTime, bool &rfMoveClonk, bool &rfWall, int32_t &riBridgeMaterial); 98 }; 99 100 class C4Object: public C4PropListNumbered 101 { 102 private: 103 void UpdateInMat(); 104 void Splash(); 105 public: 106 C4Object(); 107 ~C4Object() override; 108 C4ID id; 109 int32_t RemovalDelay; // NoSave // 110 int32_t Owner; 111 int32_t Controller; 112 int32_t LastEnergyLossCausePlayer; // last player that caused an energy loss to this Clonk (used to trace kills when player tumbles off a cliff, etc.) 113 int32_t Category; 114 int32_t old_x, old_y; C4LArea Area; // position as currently seen by Game.Objecets.Sectors. UpdatePos to sync. 115 int32_t Mass, OwnMass; 116 int32_t Damage; 117 int32_t Energy; 118 int32_t Breath; 119 int32_t InMat; // SyncClearance-NoSave // 120 uint32_t Color; 121 int32_t Audible, AudiblePan, AudiblePlayer; // NoSave // 122 int32_t lightRange; 123 int32_t lightFadeoutRange; 124 uint32_t lightColor; 125 C4Real fix_x,fix_y,fix_r; // SyncClearance-Fix // 126 C4Real xdir,ydir,rdir; 127 int32_t iLastAttachMovementFrame; // last frame in which Attach-movement by a SolidMask was done 128 bool Mobile; 129 bool Unsorted; // NoSave // 130 bool Initializing; // NoSave // 131 bool InLiquid; 132 bool EntranceStatus; 133 uint32_t t_contact; // SyncClearance-NoSave // 134 uint32_t OCF; 135 uint32_t Marker; // state var used by Objects::CrossCheck and C4FindObject - NoSave 136 C4ObjectPtr Layer; 137 C4DrawTransform *pDrawTransform; // assigned drawing transformation 138 139 // Menu 140 class C4ObjectMenu *Menu; // SyncClearance-NoSave // 141 142 C4Facet TopFace; // NoSave // 143 C4Def *Def; 144 C4ObjectPtr Contained; 145 C4ObjectInfo *Info; 146 147 C4Action Action; 148 C4Shape Shape; 149 bool fOwnVertices; // if set, vertices aren't restored from def but from end of own vtx list 150 C4TargetRect SolidMask; 151 bool HalfVehicleSolidMask; 152 C4Rect PictureRect; 153 C4NotifyingObjectList Contents; 154 C4MaterialList *MaterialContents; // SyncClearance-NoSave // 155 C4DefGraphics *pGraphics; // currently set object graphics 156 StdMeshInstance* pMeshInstance; // Instance for mesh-type objects 157 C4Effect *pEffects; // linked list of effects 158 // particle lists that are bound to this object (either in front of behind it) 159 class C4ParticleList *FrontParticles, *BackParticles; 160 void ClearParticleLists(); 161 162 uint32_t ColorMod; // color by which the object-drawing is modulated 163 uint32_t BlitMode; // extra blitting flags (like additive, ClrMod2, etc.) 164 bool CrewDisabled; // CrewMember-functionality currently disabled 165 166 // Commands 167 C4Command *Command; 168 169 StdCopyStrBuf nInfo; 170 171 class C4GraphicsOverlay *pGfxOverlay; // singly linked list of overlay graphics 172 protected: 173 bool OnFire; 174 int32_t Con; 175 int32_t Plane; 176 bool Alive; 177 C4SolidMask *pSolidMaskData; // NoSave // 178 public: 179 void Resort(); SetPlane(int32_t z)180 void SetPlane(int32_t z) { if (z) Plane = z; Resort(); } GetPlane()181 int32_t GetPlane() const { return Plane; } 182 int32_t GetSolidMaskPlane() const; 183 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); 184 void SetCommand(int32_t iCommand, C4Object *pTarget=nullptr, int32_t iTx=0, int32_t iTy=0, C4Object *pTarget2=nullptr, bool fControl=false, C4Value iData=C4VNull, int32_t iRetries=0, C4String *szText=nullptr) 185 { SetCommand(iCommand, pTarget, C4VInt(iTx), iTy, pTarget2, fControl, iData, iRetries, szText); } 186 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); 187 bool AddCommand(int32_t iCommand, C4Object *pTarget=nullptr, int32_t iTx=0, 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) 188 { return AddCommand(iCommand, pTarget, C4VInt(iTx), iTy, iUpdateInterval, pTarget2, fInitEvaluation, iData, fAppend, iRetries, szText, iBaseMode); } 189 C4Command *FindCommand(int32_t iCommandType) const; // find a command of the given type 190 void ClearCommand(C4Command *pUntil); 191 void ClearCommands(); 192 void DrawSelectMark(C4TargetFacet &cgo) const; 193 void UpdateActionFace(); 194 void SyncClearance(); 195 void SetSolidMask(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY); 196 void SetHalfVehicleSolidMask(bool set); 197 bool CheckSolidMaskRect(); // clip bounds of SolidMask in graphics - return whether the solidmask still exists 198 bool MenuCommand(const char *szCommand); 199 200 void Clear(); 201 void ClearInfo(C4ObjectInfo *pInfo); 202 bool AssignInfo(); 203 bool ValidateOwner(); 204 bool AssignLightRange(); 205 void DrawPicture(C4Facet &cgo, bool fSelected=false, C4DrawTransform* transform=nullptr); 206 void Picture2Facet(C4FacetSurface &cgo); // set picture to facet, or create facet in current size and draw if specific states are being needed 207 void Default(); 208 bool Init(C4PropList *ndef, C4Object *pCreator, 209 int32_t owner, C4ObjectInfo *info, 210 int32_t nx, int32_t ny, int32_t nr, 211 C4Real nxdir, C4Real nydir, C4Real nrdir, int32_t iController); 212 void CompileFunc(StdCompiler *pComp, C4ValueNumbers *); 213 void Denumerate(C4ValueNumbers *) override; 214 void DrawLine(C4TargetFacet &cgo, int32_t at_player); 215 bool SetPhase(int32_t iPhase); 216 void AssignRemoval(bool fExitContents=false); 217 enum DrawMode { ODM_Normal=0, ODM_Overlay=1, ODM_BaseOnly=2 }; 218 void Draw(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0); 219 void DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer = -1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0); 220 void DrawActionFace(C4TargetFacet &cgo, float offX, float offY) const; 221 void DrawFace(C4TargetFacet &cgo, float offX, float offY, int32_t iPhaseX=0, int32_t iPhaseY=0) const; 222 void DrawFaceImpl(C4TargetFacet &cgo, bool action, float fx, float fy, float fwdt, float fhgt, float tx, float ty, float twdt, float thgt, C4DrawTransform* transform) const; 223 void Execute(); 224 void ClearPointers(C4Object *ptr); 225 bool ExecMovement(); 226 void ExecAction(); 227 bool ExecLife(); 228 bool ExecuteCommand(); 229 void AssignDeath(bool fForced); // assigns death - if forced, it's killed even if an effect stopped this 230 void ContactAction(); 231 void NoAttachAction(); 232 void DoMovement(); 233 void Stabilize(); 234 void SetOCF(); 235 void UpdateOCF(); // Update fluctuant OCF 236 void UpdateShape(bool bUpdateVertices=true); 237 void UpdatePos(); // pos/shape changed 238 void UpdateSolidMask(bool fRestoreAttachedObjects); 239 void UpdateMass(); 240 bool ChangeDef(C4ID idNew); 241 void UpdateFace(bool bUpdateShape, bool fTemp=false); 242 void UpdateGraphics(bool fGraphicsChanged, bool fTemp=false); // recreates solidmasks (if fGraphicsChanged), validates Color 243 void UpdateFlipDir(); // applies new flipdir to draw transform matrix; creates/deletes it if necessary 244 bool At(int32_t ctx, int32_t cty) const; 245 bool At(int32_t ctx, int32_t cty, DWORD &ocf) const; 246 void GetOCFForPos(int32_t ctx, int32_t cty, DWORD &ocf) const; 247 bool CloseMenu(bool fForce); 248 bool ActivateMenu(int32_t iMenu, int32_t iMenuSelect=0, int32_t iMenuData=0, int32_t iMenuPosition=0, C4Object *pTarget=nullptr); 249 int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=nullptr, bool collide_halfvehic=false); 250 bool Contact(int32_t cnat); 251 void StopAndContact(C4Real & ctco, C4Real limit, C4Real & speed, int32_t cnat); 252 enum { SAC_StartCall = 1, SAC_EndCall = 2, SAC_AbortCall = 4 }; 253 C4PropList* GetAction() const; 254 bool SetAction(C4PropList * Act, C4Object *pTarget=nullptr, C4Object *pTarget2=nullptr, int32_t iCalls = SAC_StartCall | SAC_AbortCall, bool fForce = false); 255 bool SetActionByName(C4String * ActName, C4Object *pTarget=nullptr, C4Object *pTarget2=nullptr, int32_t iCalls = SAC_StartCall | SAC_AbortCall, bool fForce = false); 256 bool SetActionByName(const char * szActName, C4Object *pTarget=nullptr, C4Object *pTarget2=nullptr, int32_t iCalls = SAC_StartCall | SAC_AbortCall, bool fForce = false); 257 void SetDir(int32_t tdir); SetCategory(int32_t Category)258 void SetCategory(int32_t Category) { this->Category = Category; Resort(); SetOCF(); } 259 int32_t GetProcedure() const; 260 bool Enter(C4Object *pTarget, bool fCalls=true, bool fCopyMotion=true, bool *pfRejectCollect=nullptr); 261 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); 262 void CopyMotion(C4Object *from); 263 void ForcePosition(C4Real tx, C4Real ty); 264 void MovePosition(int32_t dx, int32_t dy); 265 void MovePosition(C4Real dx, C4Real dy); 266 void DoMotion(int32_t mx, int32_t my); 267 bool ActivateEntrance(int32_t by_plr, C4Object *by_obj); 268 void DoDamage(int32_t iLevel, int32_t iCausedByPlr, int32_t iCause); 269 void DoEnergy(int32_t iChange, bool fExact, int32_t iCause, int32_t iCausedByPlr); 270 void UpdatLastEnergyLossCause(int32_t iNewCausePlr); 271 void DoBreath(int32_t iChange); 272 void DoCon(int32_t iChange, bool grow_from_center); GetCon()273 int32_t GetCon() const { return Con; } 274 void DoExperience(int32_t change); 275 bool Promote(int32_t torank, bool exception, bool fForceRankName); 276 bool Push(C4Real txdir, C4Real dforce, bool fStraighten); 277 bool Lift(C4Real tydir, C4Real dforce); 278 void Fling(C4Real txdir, C4Real tydir, bool fAddSpeed); // set/add given speed to current, setting jump/tumble-actions 279 C4Object* CreateContents(C4PropList *); 280 bool CreateContentsByList(C4IDList &idlist); 281 BYTE GetArea(int32_t &aX, int32_t &aY, int32_t &aWdt, int32_t &aHgt) const; addtop()282 inline int32_t addtop() const { return std::max<int32_t>(18-Shape.Hgt,0); } // Minimum top action size for build check Left()283 inline int32_t Left() const { return GetX()+Shape.x; } // left border of shape Top()284 inline int32_t Top() const { return GetY()+Shape.y-addtop(); } // top border of shape (+build-top) Width()285 inline int32_t Width() const { return Shape.Wdt; } // width of shape Height()286 inline int32_t Height() const { return Shape.Hgt+addtop(); } // height of shape (+build-top) GetX()287 inline int32_t GetX() const { return fixtoi(fix_x); } GetY()288 inline int32_t GetY() const { return fixtoi(fix_y); } GetR()289 inline int32_t GetR() const { return fixtoi(fix_r); } GetFixedX()290 inline C4Real GetFixedX() const { return fix_x; } GetFixedY()291 inline C4Real GetFixedY() const { return fix_y; } GetFixedR()292 inline C4Real GetFixedR() const { return fix_r; } 293 BYTE GetEntranceArea(int32_t &aX, int32_t &aY, int32_t &aWdt, int32_t &aHgt) const; 294 BYTE GetMomentum(C4Real &rxdir, C4Real &rydir) const; 295 C4Real GetSpeed() const; 296 StdStrBuf GetDataString(); 297 void SetName (const char *NewName = nullptr) override; 298 int32_t GetValue(C4Object *pInBase, int32_t iForPlayer); 299 bool SetOwner(int32_t iOwner); 300 bool SetLightRange(int32_t iToRange, int32_t iToFadeoutRange); GetLightColor()301 uint32_t GetLightColor() const { return lightColor; } 302 bool SetLightColor(uint32_t iValue); SetOnFire(bool OnFire)303 void SetOnFire(bool OnFire) override { this->OnFire = OnFire; SetOCF(); } GetOnFire()304 bool GetOnFire() const { return OnFire; } SetAlive(bool Alive)305 void SetAlive(bool Alive) { this->Alive = Alive; SetOCF(); } GetAlive()306 bool GetAlive() const { return Alive; } 307 void UpdateLight(); 308 void SetAudibilityAt(C4TargetFacet &cgo, int32_t iX, int32_t iY, int32_t player); 309 bool IsVisible(int32_t iForPlr, bool fAsOverlay) const; // return whether an object is visible for the given player 310 void SetRotation(int32_t nr); 311 void PrepareDrawing() const; // set blit modulation and/or additive blitting 312 void FinishedDrawing() const; // reset any modulation 313 void DrawSolidMask(C4TargetFacet &cgo) const; // draw topface image only 314 bool Collect(C4Object *pObj); // add object to contents if it can be carried - no OCF and range checks are done! 315 bool GrabInfo(C4Object *pFrom); // grab info object from other object 316 bool ShiftContents(bool fShiftBack, bool fDoCalls); // rotate through contents 317 void DirectComContents(C4Object *pTarget, bool fDoCalls); // direct com: scroll contents to given ID 318 void GetParallaxity(int32_t *parX, int32_t *parY) const; 319 bool GetDrawPosition(const C4TargetFacet & cgo, float & resultx, float & resulty, float & resultzoom) const; // converts the object's position into screen coordinates 320 bool GetDrawPosition(const C4TargetFacet & cgo, float x, float y, float zoom, float & resultx, float & resulty, float & resultzoom) const; // converts object coordinates into screen coordinates 321 bool IsInLiquidCheck() const; // returns whether the Clonk is within liquid material 322 void UpdateInLiquid(); // makes splash when a liquid is entered 323 void GrabContents(C4Object *pFrom); // grab all contents that don't reject it 324 bool GetDragImage(C4Object **drag_object, C4Def **drag_id) const; // return true if object is draggable; assign drag_object/drag_id to gfx to be used for dragging 325 int32_t AddObjectAndContentsToArray(C4ValueArray *target_array, int32_t index=0); // add self, contents and child contents count recursively to value array. Return index after last added item. 326 327 protected: 328 void SideBounds(C4Real &ctcox); // apply bounds at side; regarding bourder bound and pLayer 329 void VerticalBounds(C4Real &ctcoy); // apply bounds at top and bottom; regarding border bound and pLayer 330 331 public: BoundsCheck(C4Real & ctcox,C4Real & ctcoy)332 void BoundsCheck(C4Real &ctcox, C4Real &ctcoy) // do bound checks, correcting target positions as necessary and doing contact-calls 333 { SideBounds(ctcox); VerticalBounds(ctcoy); } 334 335 bool DoSelect(); // cursor callback if not disabled 336 void UnSelect(); // unselect callback 337 void GetViewPos(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const; 338 void GetViewPosPar(float &riX, float &riY, float tx, float ty, const C4Facet &fctViewport) const; // get position this object is seen at, calculating parallaxity 339 bool PutAwayUnusedObject(C4Object *pToMakeRoomForObject); // either directly put the least-needed object away, or add a command to do it - return whether successful 340 GetGraphics()341 C4DefGraphics *GetGraphics() const { return pGraphics; } // return current object graphics 342 bool SetGraphics(const char *szGraphicsName=nullptr, C4Def *pSourceDef=nullptr); // set used graphics for object; if szGraphicsName or *szGraphicsName are nullptr, the default graphics of the given def are used; pSourceDef defaults to own def 343 bool SetGraphics(C4DefGraphics *pNewGfx, bool fUpdateData); // set used graphics for object 344 345 class C4GraphicsOverlay *GetGraphicsOverlay(int32_t iForID) const; // get specified gfx overlay 346 class C4GraphicsOverlay *GetGraphicsOverlay(int32_t iForID, bool fCreate); // get specified gfx overlay; create if not existant and specified 347 bool RemoveGraphicsOverlay(int32_t iOverlayID); // remove specified overlay from the overlay list; return if found 348 bool HasGraphicsOverlayRecursion(const C4Object *pCheckObj) const; // returns whether, at any overlay recursion depth, the given object appears as an MODE_Object-overlay 349 void UpdateScriptPointers(); // update ptrs to C4AulScript * 350 351 bool StatusActivate(); // put into active list 352 bool StatusDeactivate(bool fClearPointers); // put into inactive list 353 354 void ClearContentsAndContained(bool fDoCalls=true); // exit from container and eject contents (doing calbacks) 355 356 bool AdjustWalkRotation(int32_t iRangeX, int32_t iRangeY, int32_t iSpeed); 357 358 StdStrBuf GetInfoString(); // return def desc plus effects 359 360 bool CanConcatPictureWith(C4Object *pOtherObject) const; // return whether this object should be grouped with the other in activation lists, contents list, etc. 361 362 bool IsMoveableBySolidMask(int ComparisonPlane) const; 363 364 // This function is used for: 365 // -Objects to be removed when a player is removed 366 // -Objects that are not to be saved in "SaveScenario"-mode 367 bool IsPlayerObject(int32_t iPlayerNumber=NO_OWNER) const;// true for any object that belongs to any player (NO_OWNER) or a specified player 368 369 // This function is used for: 370 // -Objects that are not to be saved in "SaveScenario"-mode 371 bool IsUserPlayerObject();// true for any object that belongs to any player (NO_OWNER) or a specified player 372 373 // overloaded from C4PropList GetObject()374 C4Object * GetObject() override { return this; } GetObject()375 C4Object const * GetObject() const override { return this; } 376 void SetPropertyByS(C4String * k, const C4Value & to) override; 377 void ResetProperty(C4String * k) override; 378 bool GetPropertyByS(const C4String *k, C4Value *pResult) const override; 379 C4ValueArray * GetProperties() const override; 380 }; 381 382 #endif 383