forked from Mirrors/openclonk
Compare commits
55 Commits
Author | SHA1 | Date |
---|---|---|
Armin Burgmeier | db68467d91 | |
Armin Burgmeier | f10f7a4d48 | |
Armin Burgmeier | 80599754c7 | |
Armin Burgmeier | ecec556395 | |
Armin Burgmeier | cd67961aa6 | |
Armin Burgmeier | 74ab62b66f | |
Armin Burgmeier | c16c7e4298 | |
Armin Burgmeier | d388f1a3f3 | |
Armin Burgmeier | 7452f11dca | |
Armin Burgmeier | e16de2d46f | |
Armin Burgmeier | 6006b83aa6 | |
Armin Burgmeier | 2aef0d896d | |
Armin Burgmeier | 24b93532a1 | |
Armin Burgmeier | f58b565604 | |
Armin Burgmeier | 6bb893f387 | |
Armin Burgmeier | a309e52de3 | |
Armin Burgmeier | f54b471115 | |
Armin Burgmeier | 27d72b12ce | |
Armin Burgmeier | c3eaa66bef | |
Armin Burgmeier | 4f2aedd635 | |
Armin Burgmeier | 012507805f | |
Armin Burgmeier | 76dfb050e4 | |
Armin Burgmeier | aaa76be2c4 | |
Armin Burgmeier | 2c82a66083 | |
Armin Burgmeier | 002d64108d | |
Armin Burgmeier | 72d4aa69c5 | |
Armin Burgmeier | dd4469ec30 | |
Armin Burgmeier | da0109919b | |
Armin Burgmeier | 32b650c462 | |
Armin Burgmeier | 628e3a9b13 | |
Armin Burgmeier | c9f91af4d2 | |
Armin Burgmeier | 4306ba7648 | |
Armin Burgmeier | 889be3d2e4 | |
Armin Burgmeier | 4c3629cde6 | |
Armin Burgmeier | 886b1e254b | |
Armin Burgmeier | bd45ae0fab | |
Armin Burgmeier | a2997fc763 | |
Armin Burgmeier | 56282e6168 | |
Armin Burgmeier | eacc4d6917 | |
Armin Burgmeier | 89c63b393b | |
Armin Burgmeier | a84faff0cf | |
Armin Burgmeier | 8952bc4f43 | |
Armin Burgmeier | 54540a8dac | |
Armin Burgmeier | 4b7b924961 | |
Armin Burgmeier | acff7e76be | |
Armin Burgmeier | a556dc1798 | |
Armin Burgmeier | 1ef0f3ce41 | |
Armin Burgmeier | 6cf22b7d22 | |
Armin Burgmeier | 4b8c7e9c6a | |
Armin Burgmeier | a4b455a2a4 | |
Armin Burgmeier | abc948d591 | |
Armin Burgmeier | 2484f44ecb | |
Armin Burgmeier | a0ec851b70 | |
Armin Burgmeier | 745ab91665 | |
Armin Burgmeier | b83cc3c6d2 |
|
@ -482,6 +482,9 @@ set(OC_CLONK_SOURCES
|
|||
src/object/C4ObjectPtr.cpp
|
||||
src/object/C4ObjectPtr.h
|
||||
src/object/C4ObjectScript.cpp
|
||||
src/object/C4Rope.cpp
|
||||
src/object/C4Rope.h
|
||||
src/object/C4RopeScript.cpp
|
||||
src/object/C4Sector.cpp
|
||||
src/object/C4Sector.h
|
||||
src/object/C4Shape.cpp
|
||||
|
|
|
@ -28,7 +28,8 @@ public func ConnectTo(object connect)
|
|||
/* rope->BreakRope(true);
|
||||
SetRope(true);
|
||||
rope->Connect(tower, connect);*/
|
||||
rope->Reconnect(connect);
|
||||
//rope->Reconnect(connect);
|
||||
rope->SetFront(connect);
|
||||
AddEffect("Connecting", this, 1, 1, this, nil, connect);
|
||||
return true;
|
||||
}
|
||||
|
@ -61,7 +62,7 @@ private func FxConnectingTimer(object target, effect)
|
|||
if (!effect.connection)
|
||||
{
|
||||
Unhook();
|
||||
rope->BreakRope(true);
|
||||
rope->Remove(); //BreakRope(true);
|
||||
SetRope();
|
||||
return -1;
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ public func Interact(object clonk)
|
|||
{
|
||||
RemoveEffect("Connecting", this);
|
||||
Unhook();
|
||||
rope->BreakRope(true);
|
||||
//rope->BreakRope(true);
|
||||
SetRope();
|
||||
return true;
|
||||
}
|
||||
|
@ -115,22 +116,30 @@ func Initialize()
|
|||
|
||||
func SetRope(bool no_connect)
|
||||
{
|
||||
rope = CreateObject(LiftTower_Rope,0,0,NO_OWNER);
|
||||
rope = CreateRope(this, tower, 5, LiftTower_Rope);
|
||||
if(rope)
|
||||
{
|
||||
rope->SetBackFixed(true);
|
||||
rope->SetBackAutoSegmentation(250);
|
||||
tower->SetRope(rope);
|
||||
}
|
||||
return rope;
|
||||
/*rope = CreateObject(LiftTower_Rope,0,0,NO_OWNER);
|
||||
if (!no_connect) rope->Connect(tower, this);
|
||||
tower->SetRope(rope);
|
||||
return rope;
|
||||
return rope;*/
|
||||
}
|
||||
|
||||
public func Destruction()
|
||||
{
|
||||
if(rope)
|
||||
rope->HookRemoved();
|
||||
rope->Remove();
|
||||
}
|
||||
|
||||
protected func Rotation()
|
||||
{
|
||||
if (!rope) return;
|
||||
SetR(rope->GetHookAngle());
|
||||
//SetR(rope->GetHookAngle()); // TODO: Hook rotation by last segment
|
||||
}
|
||||
|
||||
public func NoLiftTowerConnection() { return true; }
|
||||
|
|
|
@ -4,5 +4,5 @@ Version=5,2,0,1
|
|||
Category=C4D_StaticBack
|
||||
Vertices=2
|
||||
Width=2
|
||||
Height=12
|
||||
Offset=-1,-6
|
||||
Height=11
|
||||
Offset=-1,-5
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -66,7 +66,7 @@ func Interact(object clonk)
|
|||
return true;
|
||||
}
|
||||
|
||||
func SetRope(object rope_to_set)
|
||||
func SetRope(proplist rope_to_set)
|
||||
{
|
||||
rope = rope_to_set;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func SetRope(object rope_to_set)
|
|||
|
||||
public func ControlUp(object clonk)
|
||||
{
|
||||
return DrawIn();
|
||||
return this->DrawIn();
|
||||
}
|
||||
public func ControlStop(object clonk)
|
||||
{
|
||||
|
@ -89,10 +89,14 @@ public func DrawIn()
|
|||
if (hook->Contained() == this) return false;
|
||||
if (ObjectDistance(hook) < LIFTTOWER_HOOK_LOOSEDIST) return false;
|
||||
if (GetEffect("DrawIn", this)) return false;
|
||||
rope->ConnectPull();
|
||||
return AddEffect("DrawIn", this, 1, 1, this);
|
||||
}
|
||||
|
||||
private func FxDrawInStart(effect)
|
||||
{
|
||||
rope->PullBack(40);
|
||||
}
|
||||
|
||||
private func FxDrawInTimer(effect)
|
||||
{
|
||||
if (!rope) return -1;
|
||||
|
@ -101,15 +105,17 @@ private func FxDrawInTimer(effect)
|
|||
OnRopeBreak();
|
||||
return -1;
|
||||
}
|
||||
rope->DoLength(-1);
|
||||
//rope->DoLength(-1);
|
||||
if (ObjectDistance(hook) < LIFTTOWER_HOOK_LOOSEDIST) return -1;
|
||||
}
|
||||
|
||||
private func FxDrawInStop(object target, effect, int temp)
|
||||
{
|
||||
rope->PullBack(0);
|
||||
|
||||
if (temp) return;
|
||||
if (!rope) return;
|
||||
rope->ConnectLoose();
|
||||
//rope->ConnectLoose();
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
|
|
|
@ -11,7 +11,7 @@ VertexX=-22,-22,0,0,20,20
|
|||
VertexY=7,-7,7,-7,-8,1
|
||||
VertexFriction=30,60,30,60,60,30
|
||||
Value=40
|
||||
Mass=100
|
||||
Mass=70
|
||||
Components=Wood=3;Metal=2;
|
||||
Rotate=1
|
||||
Float=1
|
||||
|
|
|
@ -32,7 +32,7 @@ func Initialize()
|
|||
{
|
||||
SetCategory(C4D_StaticBack);
|
||||
CreateCase();
|
||||
CreateRope();
|
||||
CreateCaseRope();
|
||||
|
||||
if (partner)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ func CreateCase()
|
|||
case->Connect(this);
|
||||
}
|
||||
|
||||
func CreateRope()
|
||||
func CreateCaseRope()
|
||||
{
|
||||
rope = CreateObject(ElevatorRope, -19 * GetCalcDir(), -11, GetOwner());
|
||||
rope->SetAction("Be", case.back);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[DefCore]
|
||||
id=LiftTower_Rope
|
||||
Version=5,2,0,1
|
||||
Category=C4D_StaticBack
|
||||
Vertices=2
|
||||
Width=2
|
||||
Height=11
|
||||
Offset=-1,-5
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
|
||||
func Initialize()
|
||||
{
|
||||
var a = CreateObject(Rock, 100, 100, NO_OWNER);
|
||||
var b = CreateObject(Rock, 200, 100, NO_OWNER);
|
||||
//a->SetCategory(C4D_StaticBack);
|
||||
//b->SetCategory(C4D_StaticBack);
|
||||
Scenario.rope = CreateRope(a, b, 5, LiftTower_Rope);
|
||||
//CreateRope(a, b, 100, LiftTower_Rope);
|
||||
}
|
||||
|
||||
func InitializePlayer(int plr)
|
||||
{
|
||||
var clonk = GetCrew(plr, 0);
|
||||
var a = CreateObject(Rock, clonk->GetX(), clonk->GetY()-100, NO_OWNER);
|
||||
a->SetCategory(C4D_StaticBack);
|
||||
var rope = CreateRope(a, clonk, 5, LiftTower_Rope);
|
||||
|
||||
rope->SetFrontAutoSegmentation(200);
|
||||
}
|
|
@ -678,6 +678,7 @@ bool C4Game::GameOverCheck()
|
|||
|
||||
C4ST_NEW(ControlRcvStat, "C4Game::Execute ReceiveControl")
|
||||
C4ST_NEW(ControlStat, "C4Game::Execute ExecuteControl")
|
||||
C4ST_NEW(ExecRopesStat, "C4Game::Execute ExecRopes")
|
||||
C4ST_NEW(ExecObjectsStat, "C4Game::Execute ExecObjects")
|
||||
C4ST_NEW(GEStats, "C4Game::Execute pGlobalEffects->Execute")
|
||||
C4ST_NEW(PXSStat, "C4Game::Execute PXS.Execute")
|
||||
|
@ -736,6 +737,7 @@ bool C4Game::Execute() // Returns true if the game is over
|
|||
// Game
|
||||
|
||||
EXEC_S( ExecObjects(); , ExecObjectsStat )
|
||||
EXEC_S( Ropes.Execute(); , ExecRopesStat )
|
||||
if (pGlobalEffects)
|
||||
EXEC_S_DR( pGlobalEffects->Execute(NULL); , GEStats , "GEEx\0");
|
||||
EXEC_S_DR( PXS.Execute(); , PXSStat , "PXSEx")
|
||||
|
@ -916,6 +918,7 @@ void C4Game::ClearPointers(C4Object * pObj)
|
|||
TransferZones.ClearPointers(pObj);
|
||||
if (pGlobalEffects)
|
||||
pGlobalEffects->ClearPointers(pObj);
|
||||
Ropes.ClearPointers(pObj);
|
||||
}
|
||||
|
||||
bool C4Game::TogglePause()
|
||||
|
@ -2192,6 +2195,7 @@ bool C4Game::InitScriptEngine()
|
|||
InitCoreFunctionMap(&ScriptEngine);
|
||||
InitObjectFunctionMap(&ScriptEngine);
|
||||
InitGameFunctionMap(&ScriptEngine);
|
||||
Ropes.InitFunctionMap(&ScriptEngine);
|
||||
|
||||
// system functions: check if system group is open
|
||||
if (!Application.OpenSystemGroup())
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <C4Extra.h>
|
||||
#include "C4Scoreboard.h"
|
||||
#include <C4PlayerControl.h>
|
||||
#include <C4Rope.h>
|
||||
|
||||
class C4Game
|
||||
{
|
||||
|
@ -88,6 +89,8 @@ public:
|
|||
C4FileMonitor *pFileMonitor;
|
||||
C4GameSec1Timer *pSec1Timer;
|
||||
|
||||
C4RopeList Ropes;
|
||||
|
||||
char CurrentScenarioSection[C4MaxName+1];
|
||||
char ScenarioFilename[_MAX_PATH+1];
|
||||
StdCopyStrBuf ScenarioTitle;
|
||||
|
|
|
@ -254,6 +254,11 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
::Objects.Draw(cgo, Player, 1, 2147483647 /* INT32_MAX */);
|
||||
C4ST_STOP(ObjStat)
|
||||
|
||||
// draw ropes
|
||||
C4ST_STARTNEW(ObjStat, "C4Viewport::Draw: Ropes")
|
||||
::Game.Ropes.Draw(cgo, NULL);
|
||||
C4ST_STOP(ObjStat)
|
||||
|
||||
// draw global particles
|
||||
C4ST_STARTNEW(PartStat, "C4Viewport::Draw: Particles")
|
||||
::Particles.GlobalParticles.Draw(cgo,NULL);
|
||||
|
|
|
@ -2264,6 +2264,23 @@ static C4String *FnGetPlayerControlAssignment(C4PropList * _this, long player, l
|
|||
return String(assignment->GetKeysAsString(human_readable, short_name).getData());
|
||||
}
|
||||
|
||||
static C4PropList* FnCreateRope(C4PropList* _this, C4Object* First, C4Object* Second, int SegmentLength, C4PropList* Graphics)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!Graphics) return NULL;
|
||||
C4Def* Def = Graphics->GetDef();
|
||||
if(!Def) return NULL;
|
||||
|
||||
return Game.Ropes.CreateRope(First, Second, itofix(SegmentLength), &Def->Graphics);
|
||||
}
|
||||
catch(const C4RopeError& err)
|
||||
{
|
||||
DebugLogF("Failed to create rope: %s", err.what());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern C4ScriptConstDef C4ScriptGameConstMap[];
|
||||
extern C4ScriptFnDef C4ScriptGameFnMap[];
|
||||
|
||||
|
@ -2428,6 +2445,7 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "GetPlayerControlAssignment", FnGetPlayerControlAssignment);
|
||||
AddFunc(pEngine, "PlayerObjectCommand", FnPlayerObjectCommand);
|
||||
AddFunc(pEngine, "EditCursor", FnEditCursor);
|
||||
AddFunc(pEngine, "CreateRope", FnCreateRope);
|
||||
|
||||
F(GetPlrKnowledge);
|
||||
F(GetComponent);
|
||||
|
|
|
@ -29,6 +29,16 @@
|
|||
|
||||
#ifdef C4REAL_USE_FIXNUM
|
||||
|
||||
C4Fixed Sqrt(C4Fixed x)
|
||||
{
|
||||
assert(x.val >= 0);
|
||||
assert(FIXED_SHIFT % 2 == 0);
|
||||
|
||||
C4Fixed ret;
|
||||
ret.val = SqrtI(x.val) << (FIXED_SHIFT >> 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static table with sinus values from 0.00 degree to 90.00 degree inclusively
|
||||
long SineTable[9001] =
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ class C4Fixed
|
|||
friend C4Fixed itofix(int32_t x, int32_t prec);
|
||||
friend float fixtof(const C4Fixed &x);
|
||||
friend C4Fixed ftofix(float x);
|
||||
friend C4Fixed Sqrt(C4Fixed x);
|
||||
#else
|
||||
friend void FIXED_TO_FLOAT(float *pVal);
|
||||
#endif
|
||||
|
@ -296,6 +297,8 @@ inline C4Real C4REAL100(int x) { return itofix(x, 100); }
|
|||
inline C4Real C4REAL256(int x) { C4Fixed r; r.val = x * FIXED_FPF / 256; return r; }
|
||||
inline C4Real C4REAL10(int x) { return itofix(x, 10); }
|
||||
|
||||
C4Fixed Sqrt(C4Fixed x);
|
||||
|
||||
#else
|
||||
|
||||
// *** wrap C4Real to float
|
||||
|
|
|
@ -71,6 +71,28 @@ int Pow(int base, int exponent)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Fast(?) Integer square root */
|
||||
uint32_t SqrtI(uint32_t a)
|
||||
{
|
||||
uint32_t rem = 0;
|
||||
uint32_t root = 0;
|
||||
for(unsigned int i = 0; i < (sizeof(a)*8)/2; i++)
|
||||
{
|
||||
root <<= 1;
|
||||
rem = ((rem << 2) + (a >> (sizeof(a)*8 - 2)));
|
||||
a <<= 2;
|
||||
root ++;
|
||||
if(root <= rem)
|
||||
{
|
||||
rem -= root;
|
||||
root++;
|
||||
}
|
||||
else
|
||||
root--;
|
||||
}
|
||||
return root >> 1;
|
||||
}
|
||||
|
||||
bool ForLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
|
||||
bool (*fnCallback)(int32_t, int32_t, int32_t), int32_t iPar,
|
||||
int32_t *lastx, int32_t *lasty)
|
||||
|
|
|
@ -48,6 +48,7 @@ int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2);
|
|||
int Angle(int iX1, int iY1, int iX2, int iY2);
|
||||
int Pow(int base, int exponent);
|
||||
int32_t StrToI32(const char *s, int base, const char **scan_end);
|
||||
uint32_t SqrtI(uint32_t a);
|
||||
|
||||
#include <cstring>
|
||||
inline void ZeroMem(void *lpMem, size_t dwSize)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2012 Armin Burgmeier
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
|
||||
#ifndef INC_C4Rope
|
||||
#define INC_C4Rope
|
||||
|
||||
#include <stdexcept>
|
||||
#include <C4Object.h>
|
||||
|
||||
// All units in pixels and frames
|
||||
|
||||
class C4RopeError: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
C4RopeError(const std::string& message): std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
// C4RopeLinks are intermediate rope elements that are inserted and removed
|
||||
// such that
|
||||
class C4RopeLink
|
||||
{
|
||||
public:
|
||||
C4Real x, y; // pos
|
||||
C4RopeLink* Next;
|
||||
C4RopeLink* Prev;
|
||||
};
|
||||
|
||||
class C4Rope;
|
||||
class C4RopeElement
|
||||
{
|
||||
friend class C4Rope;
|
||||
public:
|
||||
C4RopeElement(C4Object* obj, bool fixed);
|
||||
C4RopeElement(C4Real x, C4Real y, C4Real m, bool fixed);
|
||||
~C4RopeElement();
|
||||
|
||||
C4Real GetX() const { return Object ? GetTargetX() : x; }
|
||||
C4Real GetY() const { return Object ? GetTargetY() : y; }
|
||||
C4Real GetVx() const { return Object ? Object->xdir : vx; }
|
||||
C4Real GetVy() const { return Object ? Object->ydir : vy; }
|
||||
C4Real GetMass() const { return Object ? itofix(Object->Mass) : m; }
|
||||
C4Object* GetObject() const { return Object; }
|
||||
|
||||
C4Real GetTargetX() const;
|
||||
C4Real GetTargetY() const;
|
||||
|
||||
C4Real GetPrevLinkX() const { assert(Prev); return LastLink ? LastLink->x : Prev->oldx; }
|
||||
C4Real GetPrevLinkY() const { assert(Prev); return LastLink ? LastLink->y : Prev->oldy; }
|
||||
C4Real GetNextLinkX() const { assert(Next); return FirstLink ? FirstLink->x : Next->oldx; }
|
||||
C4Real GetNextLinkY() const { assert(Next); return FirstLink ? FirstLink->y : Next->oldy; }
|
||||
|
||||
void AddForce(C4Real x, C4Real y);
|
||||
void Execute(const C4Rope* rope, C4Real dt);
|
||||
private:
|
||||
bool InsertLinkPosition(int from_x, int from_y, int to_x, int to_y, int link_x, int link_y, int& insert_x, int& insert_y);
|
||||
void InsertLink(C4RopeElement* from, C4RopeElement* to, int insert_x, int insert_y);
|
||||
|
||||
void ResetForceRedirection(C4Real dt);
|
||||
void SetForceRedirection(const C4Rope* rope, int ox, int oy);
|
||||
bool SetForceRedirectionByLookAround(const C4Rope* rope, int ox, int oy, C4Real dx, C4Real dy, C4Real l, C4Real angle);
|
||||
|
||||
bool Fixed; // Apply rope forces to this element?
|
||||
C4Real x, y; // pos; ignored if Object != NULL
|
||||
C4Real oldx, oldy; // position in the previous frame. Used for linking
|
||||
C4Real vx, vy; // velocity; ignored if Object != NULL
|
||||
C4Real m; // mass; ignored if Object != NULL
|
||||
C4Real fx, fy; // force
|
||||
C4Real rx, ry; // force redirection
|
||||
C4Real rdt; // force redirection timeout
|
||||
C4Real fcx, fcy; // force after solve -- for debug output only
|
||||
C4RopeElement* Next; // next rope element, or NULL
|
||||
C4RopeElement* Prev; // prev rope element, or NULL
|
||||
C4RopeLink* FirstLink; // first rope link between this and next, or NULL
|
||||
C4RopeLink* LastLink; // last rope link between this and prev, or NULL
|
||||
C4Object* Object; // Connected object. If set, x/y/vx/vy/m are ignored.
|
||||
int LastContactVertex; // Vertex which most recently had collision with landscape
|
||||
};
|
||||
|
||||
class C4Rope: public C4PropListNumbered
|
||||
{
|
||||
public:
|
||||
C4Rope(C4PropList* Prototype, C4Object* first_obj, C4Object* second_obj, C4Real segment_length, C4DefGraphics* graphics);
|
||||
~C4Rope();
|
||||
|
||||
void Draw(C4TargetFacet& cgo, C4BltTransform* pTransform);
|
||||
void Execute();
|
||||
|
||||
void ClearPointers(C4Object* obj);
|
||||
|
||||
C4Real GetSegmentLength() const { return l; }
|
||||
C4Real GetOuterFriction() const { return mu; }
|
||||
|
||||
C4RopeElement* GetFront() const { return Front; }
|
||||
C4RopeElement* GetBack() const { return Back; }
|
||||
void SetFront(C4Object* obj, C4Real x, C4Real y) { Front->Object = obj; Front->x = x; Front->y = y; Front->LastContactVertex = -1; }
|
||||
void SetBack(C4Object* obj, C4Real x, C4Real y) { Back->Object = obj; Back->x = x; Back->y = y; Back->LastContactVertex = -1; }
|
||||
|
||||
C4Real GetFrontAutoSegmentation() const { return FrontAutoSegmentation; }
|
||||
C4Real GetBackAutoSegmentation() const { return BackAutoSegmentation; }
|
||||
void SetFrontAutoSegmentation(C4Real max) { FrontAutoSegmentation = max; }
|
||||
void SetBackAutoSegmentation(C4Real max) { BackAutoSegmentation = max; }
|
||||
|
||||
bool GetFrontFixed() const { return Front->Fixed; }
|
||||
bool GetBackFixed() const { return Back->Fixed; }
|
||||
void SetFrontFixed(bool fixed) { Front->Fixed = fixed; }
|
||||
void SetBackFixed(bool fixed) { Back->Fixed = fixed; }
|
||||
|
||||
void PullFront(C4Real f) { FrontPull = f; }
|
||||
void PullBack(C4Real f) { BackPull = f; }
|
||||
private:
|
||||
C4Real GetL(const C4RopeElement* prev, const C4RopeElement* next) const;
|
||||
|
||||
void DoAutoSegmentation(C4RopeElement* fixed, C4RopeElement* first, C4Real max);
|
||||
void Solve(C4RopeElement* prev, C4RopeElement* next);
|
||||
|
||||
// Whether to apply repulsive forces between rope segments.
|
||||
// TODO: Could be made a property...
|
||||
static const bool ApplyRepulsive = false;
|
||||
|
||||
unsigned int NumIterations; // Number of iterations per frame
|
||||
const float Width; // Width of rope
|
||||
C4DefGraphics* Graphics;
|
||||
int32_t SegmentCount;
|
||||
|
||||
C4Real l; // spring length in equilibrium
|
||||
C4Real k; // spring constant
|
||||
C4Real mu; // outer friction constant
|
||||
C4Real eta; // inner friction constant
|
||||
|
||||
C4RopeElement* Front;
|
||||
C4RopeElement* Back;
|
||||
|
||||
C4Real FrontAutoSegmentation;
|
||||
C4Real BackAutoSegmentation;
|
||||
|
||||
C4Real FrontPull;
|
||||
C4Real BackPull;
|
||||
};
|
||||
|
||||
class C4RopeAul: public C4AulScript
|
||||
{
|
||||
public:
|
||||
C4RopeAul();
|
||||
virtual ~C4RopeAul();
|
||||
|
||||
virtual bool Delete() { return false; }
|
||||
virtual C4PropListStatic* GetPropList() { return RopeDef; }
|
||||
|
||||
void InitFunctionMap(C4AulScriptEngine* pEngine);
|
||||
|
||||
protected:
|
||||
C4PropListStatic* RopeDef;
|
||||
};
|
||||
|
||||
class C4RopeList
|
||||
{
|
||||
public:
|
||||
C4RopeList();
|
||||
|
||||
void InitFunctionMap(C4AulScriptEngine* pEngine) { RopeAul.InitFunctionMap(pEngine); }
|
||||
|
||||
void Execute();
|
||||
void Draw(C4TargetFacet& cgo, C4BltTransform* pTransform);
|
||||
|
||||
C4Rope* CreateRope(C4Object* first_obj, C4Object* second_obj, C4Real segment_length, C4DefGraphics* graphics);
|
||||
void RemoveRope(C4Rope* rope);
|
||||
|
||||
void ClearPointers(C4Object* obj);
|
||||
|
||||
private:
|
||||
C4RopeAul RopeAul;
|
||||
std::vector<C4Rope*> Ropes;
|
||||
};
|
||||
|
||||
#endif // INC_C4Rope
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2012 Armin Burgmeier
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
|
||||
#include <C4Include.h>
|
||||
#include <C4Rope.h>
|
||||
#include <C4AulDefFunc.h>
|
||||
|
||||
static C4Void FnRemove(C4Rope* Rope)
|
||||
{
|
||||
Game.Ropes.RemoveRope(Rope);
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Object* FnGetFront(C4Rope* Rope)
|
||||
{
|
||||
return Rope->GetFront()->GetObject();
|
||||
}
|
||||
|
||||
static C4Object* FnGetBack(C4Rope* Rope)
|
||||
{
|
||||
return Rope->GetBack()->GetObject();
|
||||
}
|
||||
|
||||
static C4Void FnSetFront(C4Rope* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
|
||||
{
|
||||
Rope->SetFront(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnSetBack(C4Rope* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
|
||||
{
|
||||
Rope->SetBack(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnSetFrontAutoSegmentation(C4Rope* Rope, int max)
|
||||
{
|
||||
Rope->SetFrontAutoSegmentation(itofix(max));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnSetBackAutoSegmentation(C4Rope* Rope, int max)
|
||||
{
|
||||
Rope->SetBackAutoSegmentation(itofix(max));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnSetFrontFixed(C4Rope* Rope, bool fixed)
|
||||
{
|
||||
Rope->SetFrontFixed(fixed);
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnSetBackFixed(C4Rope* Rope, bool fixed)
|
||||
{
|
||||
Rope->SetBackFixed(fixed);
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnPullFront(C4Rope* Rope, int force)
|
||||
{
|
||||
Rope->PullFront(itofix(force));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
static C4Void FnPullBack(C4Rope* Rope, int force)
|
||||
{
|
||||
Rope->PullBack(itofix(force));
|
||||
return C4Void();
|
||||
}
|
||||
|
||||
C4RopeAul::C4RopeAul():
|
||||
RopeDef(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
C4RopeAul::~C4RopeAul()
|
||||
{
|
||||
delete RopeDef;
|
||||
}
|
||||
|
||||
void C4RopeAul::InitFunctionMap(C4AulScriptEngine* pEngine)
|
||||
{
|
||||
delete RopeDef;
|
||||
RopeDef = C4PropList::NewStatic(NULL, NULL, ::Strings.RegString("Rope"));
|
||||
RopeDef->SetName("Rope");
|
||||
pEngine->RegisterGlobalConstant("Rope", C4VPropList(RopeDef));
|
||||
|
||||
Reg2List(pEngine);
|
||||
|
||||
::AddFunc(this, "Remove", FnRemove);
|
||||
::AddFunc(this, "GetFront", FnGetFront);
|
||||
::AddFunc(this, "GetBack", FnGetBack);
|
||||
::AddFunc(this, "SetFront", FnSetFront);
|
||||
::AddFunc(this, "SetBack", FnSetBack);
|
||||
::AddFunc(this, "SetFrontAutoSegmentation", FnSetFrontAutoSegmentation);
|
||||
::AddFunc(this, "SetBackAutoSegmentation", FnSetBackAutoSegmentation);
|
||||
::AddFunc(this, "SetFrontFixed", FnSetFrontFixed);
|
||||
::AddFunc(this, "SetBackFixed", FnSetBackFixed);
|
||||
::AddFunc(this, "PullFront", FnPullFront);
|
||||
::AddFunc(this, "PullBack", FnPullBack);
|
||||
RopeDef->Freeze();
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
#include <C4Object.h>
|
||||
#include <C4Effect.h>
|
||||
#include <C4DefList.h>
|
||||
#include <C4Rope.h>
|
||||
|
||||
inline const static char *FnStringPar(C4String *pString)
|
||||
{
|
||||
|
@ -98,6 +99,14 @@ public:
|
|||
NeedObjectContext(const char *function) : C4AulExecError(FormatString("%s: must be called from object context", function).getData()) {}
|
||||
};
|
||||
|
||||
// Other functions are callable in rope context only.
|
||||
// This exception gets thrown if they are called from anywhere else.
|
||||
class NeedRopeContext : public C4AulExecError
|
||||
{
|
||||
public:
|
||||
NeedRopeContext(const char *function) : C4AulExecError(FormatString("%s: must be called from rope context", function).getData()) {}
|
||||
};
|
||||
|
||||
// Then there's functions that don't care, but need either defn or object context.
|
||||
// This exception gets thrown if those are called from global scripts.
|
||||
class NeedNonGlobalContext : public C4AulExecError
|
||||
|
@ -313,6 +322,27 @@ public C4AulDefFuncHelper { \
|
|||
Func pFunc; \
|
||||
}; \
|
||||
template <typename RType LIST(N, TYPENAMES)> \
|
||||
class C4AulDefRopeFunc##N: \
|
||||
public C4AulDefFuncHelper { \
|
||||
public: \
|
||||
/* A pointer to the function which this class wraps */ \
|
||||
typedef RType (*Func)(C4Rope * LIST(N, PARS)); \
|
||||
virtual int GetParCount() { return N; } \
|
||||
virtual C4V_Type GetRetType() \
|
||||
{ return C4ValueConv<RType>::Type(); } \
|
||||
/* Constructor, using the base class to create the ParType array */ \
|
||||
C4AulDefRopeFunc##N(C4AulScript *pOwner, const char *pName, Func pFunc, bool Public): \
|
||||
C4AulDefFuncHelper(pOwner, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
|
||||
/* Extracts the parameters from C4Values and wraps the return value in a C4Value */ \
|
||||
virtual C4Value Exec(C4PropList * _this, C4Value pPars[], bool fPassErrors) \
|
||||
{ \
|
||||
C4Rope * Rope; if (!_this || !(Rope = dynamic_cast<C4Rope*>(_this))) throw new NeedRopeContext(GetName()); \
|
||||
return C4ValueConv<RType>::ToC4V(pFunc(Rope LIST(N, CONV_FROM_C4V))); \
|
||||
} \
|
||||
protected: \
|
||||
Func pFunc; \
|
||||
}; \
|
||||
template <typename RType LIST(N, TYPENAMES)> \
|
||||
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4PropList * LIST(N, PARS)), bool Public=true) \
|
||||
{ \
|
||||
new C4AulDefFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
|
||||
|
@ -321,6 +351,11 @@ template <typename RType LIST(N, TYPENAMES)> \
|
|||
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4Object * LIST(N, PARS)), bool Public=true) \
|
||||
{ \
|
||||
new C4AulDefObjectFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
|
||||
} \
|
||||
template <typename RType LIST(N, TYPENAMES)> \
|
||||
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4Rope * LIST(N, PARS)), bool Public=true) \
|
||||
{ \
|
||||
new C4AulDefRopeFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
|
||||
}
|
||||
|
||||
TEMPLATE(0)
|
||||
|
|
Loading…
Reference in New Issue