summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DTCallback.c116
-rw-r--r--DTFilterObjects.c318
-rw-r--r--DTMenuCompatibility.c46
-rw-r--r--DTObjectSerializing.c107
-rw-r--r--DTPlayers.c22
-rw-r--r--DTQuickSort.c22
-rw-r--r--DTScopedVars.c31
-rw-r--r--DTTransform.c47
-rw-r--r--DTUtility.c76
9 files changed, 645 insertions, 140 deletions
diff --git a/DTCallback.c b/DTCallback.c
index 6e026b7..5e6fb3f 100644
--- a/DTCallback.c
+++ b/DTCallback.c
@@ -5,10 +5,12 @@ static const CallbackTarget_Bind = -1;
static const CallbackTarget_Global = -2;
static const CallbackTarget_Scenario = -3;
+// NOTE: fast callbacks (fast = true for ObjectCallback or DefinitionCallback) use ObjectCall/DefinitionCall directly for greater performance if possible (refs = 0 and GetLength(args) <= 8 for CallA()) and thus must be real functions of the desired object/definition. safe mode is ignored for fast callbacks
+
global func GlobalCallback(string name) { return [CallbackTarget_Global, name]; }
global func ScenarioCallback(string name) { return [CallbackTarget_Scenario, name]; }
-global func ObjectCallback(string name, object target) { return [target || this || FatalError("ObjectCallback without target object"), name]; }
-global func DefinitionCallback(string name, id target) { return [target || GetID() || FatalError("DefinitionCallback without target definition"), name]; }
+global func ObjectCallback(string name, object target, bool fast) { return [target || this || FatalError("ObjectCallback without target object"), name, fast]; }
+global func DefinitionCallback(string name, id target, bool fast) { return [target || GetID() || FatalError("DefinitionCallback without target definition"), name, fast]; }
global func Callback(string name, target) { return [target || this || GetID() || CallbackTarget_Global, name]; }
global func BindCallback(callback, array binding) { return [CallbackTarget_Bind, callback, binding]; }
@@ -50,19 +52,44 @@ global func CallA(callback, args, bool safe, array refs)
{
callback = [this, callback];
}
+
if(GetType(callback) != C4V_Array)
{
return _inherited(callback, args, ...);
}
- else
+
+ var target = callback[0], function = callback[1];
+
+ if((GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID) && GetLength(callback) == 3 && callback[2] && !refs && GetLength(args) <= 8) // fast callback
+ {
+ if(GetType(target) == C4V_C4Object)
+ {
+ return ObjectCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ }
+ else if(GetType(target) == C4V_C4ID)
+ {
+ return DefinitionCall(target, function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
+ }
+ }
+
+ refs = refs || [];
+
+ if(target == CallbackTarget_Scenario)
+ {
+ return GameCall(function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
+ }
+ else if(target == CallbackTarget_Bind)
+ {
+ return CallA(function, BindArgs(callback[2], args, safe, refs), safe, refs);
+ }
+
+ if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID || target == CallbackTarget_Global)
{
- refs = refs || [];
var safeModifier = "";
if(safe)
{
safeModifier = "~";
}
- var target = callback[0], function = callback[1];
var argsStr = "", pos = 0;
for(var arg in args)
{
@@ -80,32 +107,35 @@ global func CallA(callback, args, bool safe, array refs)
}
++pos;
}
+
if(target == CallbackTarget_Global)
{
return GlobalEval(Format("%s(%s)", function, argsStr));
}
- else if(target == CallbackTarget_Scenario)
+ else if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID)
{
- return GameCall(function, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
+ return eval(Format("%s->%s%s(%s)", Serialize(target), safeModifier, function, argsStr));
}
- else if(target == CallbackTarget_Bind)
+ }
+ else
+ {
+ if(this)
+ {
+ return this->~CallCustom(callback, args, ...);
+ }
+ else if(GetID())
{
- return CallA(callback[1], BindArgs(callback[2], args, safe, refs), safe, refs);
+ return GetID()->~CallCustom(callback, args, ...);
}
else
{
- if(GetType(target) == C4V_C4Object || GetType(target) == C4V_C4ID)
- {
- return eval(Format("%s->%s%s(%s)", Serialize(target), safeModifier, function, argsStr));
- }
- else
- {
- return (this && this->~CallCustom(callback, args, ...)) || ROCK->~CallCustom(callback, args, ...);
- }
+ return CallCustom(callback, args, ...);
}
}
}
+global func CallCustom() { return _inherited(...); }
+
global func BindArgs_ArgumentArrayPart(array binding, array args, bool safe)
{
var ret = args[binding[0]];
@@ -164,7 +194,18 @@ global func BindArgs(array binding, array args, bool safe, array& refs)
}
else if(GetType(bind[0]) == C4V_Int && bind[0] < 0)
{
- ret[pos] = BindCustomArgs(bind, args, safe);
+ if(this)
+ {
+ ret[pos] = this->~BindCustomArgs(bind, args, safe);
+ }
+ else if(GetID())
+ {
+ ret[pos] = GetID()->~BindCustomArgs(bind, args, safe);
+ }
+ else
+ {
+ ret[pos] = BindCustomArgs(bind, args, safe);
+ }
}
else
{
@@ -230,16 +271,32 @@ global func CheckCallback(callback)
}
else if(GetType(callback[0]) == C4V_C4ID || GetType(callback[0]) == C4V_C4Object)
{
- if(GetLength(callback) == 2 && GetType(callback[1]) == C4V_String && callback[1] != "")
+ if(GetLength(callback) == 2 || (GetLength(callback) == 3 && (!callback[2] || GetType(callback[2]) == C4V_Bool))) // length 2 for callbacks created by Callback() or Object/DefinitionCallback() before fast was introduced
{
- return true;
+ if(GetType(callback[1]) == C4V_String && callback[1] != "")
+ {
+ return true;
+ }
}
}
}
- return (this && this->~CheckCustomCallback(callback, ...)) || ROCK->~CheckCustomCallback(callback, ...);
+ if(this)
+ {
+ return this->~CheckCustomCallback(callback, ...);
+ }
+ else if(GetID())
+ {
+ return GetID()->~CheckCustomCallback(callback, ...);
+ }
+ else
+ {
+ return CheckCustomCallback(callback, ...);
+ }
}
+global func CheckCustomCallback() { return _inherited(...); }
+
global func CheckBindCallbackBinding(array binding)
{
for(var b in binding)
@@ -295,7 +352,20 @@ global func CheckBindCallbackBinding(array binding)
}
else if(GetType(b[0]) == C4V_Int && b[0] < 0)
{
- if(!CheckBindCallbackCustomBinding(b))
+ var ret;
+ if(this)
+ {
+ ret = this->~CheckBindCallbackCustomBinding(b);
+ }
+ else if(GetID())
+ {
+ ret = GetID()->~CheckBindCallbackCustomBinding(b);
+ }
+ else
+ {
+ ret = CheckBindCallbackCustomBinding(b);
+ }
+ if(!ret)
{
return false;
}
@@ -321,4 +391,4 @@ global func CheckBindCallbackBinding(array binding)
return true;
}
-global func CheckBindCallbackCustomBinding() { return _inherited(...); }
+global func CheckBindCallbackCustomBinding() { return _inherited(...); } \ No newline at end of file
diff --git a/DTFilterObjects.c b/DTFilterObjects.c
new file mode 100644
index 0000000..77db745
--- /dev/null
+++ b/DTFilterObjects.c
@@ -0,0 +1,318 @@
+#strict 2
+
+// see C4FindObject.h
+static const C4SO_First = 100;
+static const C4SO_Last = 200;
+
+global func CheckObjectFilter(array filter, object obj)
+{
+ obj = obj || this;
+
+ if(filter[0] == C4FO_Action)
+ {
+ return obj->GetAction() == filter[1];
+ }
+ else if(filter[0] == C4FO_ActionTarget)
+ {
+ return obj->GetActionTarget(filter[2]) == filter[1];
+ }
+ else if(filter[0] == C4FO_And)
+ {
+ return CheckObject(filter, obj, 1);
+ }
+ else if(filter[0] == C4FO_AnyContainer)
+ {
+ return obj->Contained();
+ }
+ else if(filter[0] == C4FO_AtPoint)
+ {
+ var x = filter[1], y = filter[2];
+ var shape = GetShape(obj);
+ shape[0] += obj->GetX();
+ shape[1] += obj->GetY();
+
+ return InRect([x, y], shape);
+ }
+ else if(filter[0] == C4FO_AtRect)
+ {
+ var shape = GetShape(obj);
+ shape[0] += obj->GetX();
+ shape[1] += obj->GetY();
+
+ return shape[0] + shape[2] > filter[1] && shape[0] < filter[1] + filter[3] && shape[1] + shape[3] > filter[2] && shape[1] < filter[2] + filter[4];
+ }
+ else if(filter[0] == C4FO_Category)
+ {
+ return obj->GetCategory() & filter[1];
+ }
+ else if(filter[0] == C4FO_Container)
+ {
+ return obj->Contained() == filter[1];
+ }
+ else if(filter[0] == C4FO_Controller)
+ {
+ return obj->GetController() == filter[1];
+ }
+ else if(filter[0] == C4FO_Distance)
+ {
+ return ((obj->GetX() - filter[1])**2 + (obj->GetY() - filter[2])**2) <= filter[3]**2;
+ }
+ else if(filter[0] == C4FO_Exclude)
+ {
+ return obj != filter[1];
+ }
+ else if(filter[0] == C4FO_Func)
+ {
+ var args = CreateArray(GetLength(filter) - 2);
+ for(var i = 2; i < GetLength(filter); ++i)
+ {
+ args[i - 2] = filter[i];
+ }
+
+ return obj->CallA(filter[1], args, true);
+ }
+ else if(filter[0] == C4FO_ID)
+ {
+ return obj->GetID() == filter[1];
+ }
+ else if(filter[0] == C4FO_InRect)
+ {
+ return InRect([obj->GetX(), obj->GetY()], [filter[1], filter[2], filter[3], filter[4]]);
+ }
+ else if(filter[0] == C4FO_Layer)
+ {
+ return obj->GetObjectLayer() == filter[1];
+ }
+ else if(filter[0] == C4FO_Not)
+ {
+ return !CheckObject([filter[1]], obj);
+ }
+ else if(filter[0] == C4FO_OCF)
+ {
+ return obj->GetOCF() & filter[1];
+ }
+ else if(filter[0] == C4FO_OnLine)
+ {
+ var shape = GetShape(obj);
+ shape[0] += obj->GetX();
+ shape[1] += obj->GetY();
+
+ var x = filter[1], y = filter[2];
+ var x2 = filter[3], y2 = filter[4];
+
+
+ // shape is at the beginning or end of the line
+ if(InRect([x, y], shape) || InRect([x2, y2], shape))
+ {
+ return true;
+ }
+
+ // shape is completely left or above the line
+ if((x < shape[0] && x2 < shape[0]) || (y < shape[1] && y2 < shape[1]))
+ {
+ return false;
+ }
+
+ // shape is completely right or below the line
+ if((x >= shape[0] + shape[2] && x2 >= shape[0] + shape[2]) || (y >= shape[1] + shape[3] && y2 >= shape[1] + shape[3]))
+ {
+ return false;
+ }
+
+ // the line is actually a point and is neither left/right nor above/below, so it must be on that point
+ if (x == x2 || y == y2)
+ {
+ return true;
+ }
+
+ // Check intersection left/right
+ var xI;
+ if(x < shape[0])
+ {
+ xI = shape[0];
+ }
+ else
+ {
+ xI = shape[0] + shape[2];
+ }
+
+ var yI = y + (y2 - y) * (xI - x) / (x2 - x);
+ if(yI >= shape[1] && yI < shape[1] + shape[3])
+ {
+ return true;
+ }
+
+ // Check intersection up/down
+ if(y < shape[1])
+ {
+ yI = shape[1];
+ }
+ else
+ {
+ yI = shape[1] + shape[3];
+ }
+
+ xI = x + (x2 - x) * (yI - y) / (y2 - y);
+ return xI >= shape[0] && xI < shape[0] + shape[2];
+ }
+ else if(filter[0] == C4FO_Or)
+ {
+ for(var i = 1; i < GetLength(filter); ++i)
+ {
+ var orFilter = filter[i];
+ if(!orFilter)
+ {
+ continue;
+ }
+ if(CheckObjectFilter(orFilter, obj))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if(filter[0] == C4FO_Owner)
+ {
+ return obj->GetOwner() == filter[1];
+ }
+ else
+ {
+ return true;
+ }
+}
+
+global func CheckObject(array filters, object obj, int filtersOffset)
+{
+ obj = obj || this;
+
+ for(var i = filtersOffset; i < GetLength(filters); ++i)
+ {
+ var filter = filters[i];
+ if(!filter)
+ {
+ continue;
+ }
+ if(!CheckObjectFilter(filter, obj))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+global func CompareObjects(object a, object b, array sorting)
+{
+ if(sorting[0] == C4SO_Reverse)
+ {
+ return CompareObjects(b, a, sorting[1]);
+ }
+ else if(sorting[0] == C4SO_Multiple)
+ {
+ return SortObjectsCallback(a, b, sorting, 1);
+ }
+ else if(sorting[0] == C4SO_Distance)
+ {
+ return ((a->GetX() - sorting[1])**2 + (a->GetY() - sorting[2])**2) - ((b->GetX() - sorting[1])**2 + (b->GetY() - sorting[2])**2);
+ }
+ else if(sorting[0] == C4SO_Random)
+ {
+ return Random65536 - Random(65536);
+ }
+ else if(sorting[0] == C4SO_Speed)
+ {
+ return (GetXDir(a, 65536)**2 + GetYDir(b, 65536)**2) - (GetXDir(b, 65536)**2 + GetYDir(b, 65536)**2);
+ }
+ else if(sorting[0] == C4SO_Mass)
+ {
+ return GetMass(a) - GetMass(b);
+ }
+ else if(sorting[0] == C4SO_Value)
+ {
+ return GetValue(a) - GetValue(b);
+ }
+ else if(sorting[0] == C4SO_Func)
+ {
+ var args = CreateArray(GetLength(sorting) - 2);
+ for(var i = 2; i < GetLength(sorting); ++i)
+ {
+ args[i - 2] = sorting[i];
+ }
+ return a->CallA(sorting[1], args, true) - b->CallA(sorting[1], args, true);
+ }
+
+ return 0;
+}
+
+global func SortObjectsCallback(object a, object b, array sortings, int offset)
+{
+ for(var i = offset; i < GetLength(sortings); ++i)
+ {
+ var ret = CompareObjects(a, b, sortings[i]);
+ if(ret != 0)
+ {
+ return ret;
+ }
+ }
+ return 0;
+}
+
+global func SortObjects(array& objects, array sortings)
+{
+ QSort(objects, GlobalCallback("SortObjectsCallback"), sortings);
+}
+
+global func FilterObjects(array objects, array filtersSortings, int limit)
+{
+ var filters = [], sortings = [];
+
+ for(var filterSorting in filtersSortings)
+ {
+ if(!filterSorting)
+ {
+ continue;
+ }
+
+ if(Inside(filterSorting[0], C4SO_First, C4SO_Last))
+ {
+ ArrayAppend(sortings, filterSorting);
+ }
+ else
+ {
+ ArrayAppend(filters, filterSorting);
+ }
+ }
+
+ var realLimit = limit;
+ if(GetLength(sortings) > 0)
+ {
+ realLimit = 0;
+ }
+
+ var ret = [];
+ for(var obj in objects)
+ {
+ if(!obj)
+ {
+ continue;
+ }
+
+ if(CheckObject(filters, obj))
+ {
+ ArrayAppend(ret, obj);
+
+ if(realLimit && realLimit <= GetLength(ret))
+ {
+ return ret;
+ }
+ }
+ }
+
+ SortObjects(ret, sortings);
+
+ if(GetLength(sortings) > 0 && limit)
+ {
+ SetLength(ret, limit);
+ }
+
+ return ret;
+} \ No newline at end of file
diff --git a/DTMenuCompatibility.c b/DTMenuCompatibility.c
index 0401b95..41331dc 100644
--- a/DTMenuCompatibility.c
+++ b/DTMenuCompatibility.c
@@ -18,3 +18,49 @@ global func Menu_SubMenu(caption, symbol, string infoCaption, array menuEntries_
return inherited([Menu_Entry_Caption(caption), Menu_Entry_Symbol(symbol), Menu_Entry_Count(count), Menu_Entry_InfoCaption(infoCaption), Menu_Entry_Extra(extra), Menu_Entry_XPar1(XPar1), Menu_Entry_XPar2(XPar2)], menuEntries_Settings);
}
}
+
+global func Menu_Entry(caption, callback, symbol, count, infoCaption, args, extra, XPar1, XPar2)
+{
+ if(GetType(caption) == C4V_String)
+ {
+ var settings = [];
+ if(caption)
+ {
+ ArrayAppend(settings, Menu_Entry_Caption(caption));
+ }
+ if(callback)
+ {
+ ArrayAppend(settings, Menu_Entry_Callbacks([callback]));
+ ArrayAppend(settings, Menu_Entry_Args(args));
+ }
+ if(symbol)
+ {
+ ArrayAppend(settings, Menu_Entry_Symbol(symbol));
+ }
+ if(count)
+ {
+ ArrayAppend(settings, Menu_Entry_Count(count));
+ }
+ if(infoCaption && infoCaption != "")
+ {
+ ArrayAppend(settings, Menu_Entry_InfoCaption(infoCaption));
+ }
+ if(extra)
+ {
+ ArrayAppend(settings, Menu_Entry_Extra(extra));
+ }
+ if(XPar1)
+ {
+ ArrayAppend(settings, XPar1);
+ }
+ if(XPar2)
+ {
+ ArrayAppend(settings, XPar2);
+ }
+ return inherited(settings);
+ }
+ else
+ {
+ return inherited(caption, callback, symbol, count, infoCaption, args, extra, XPar1, XPar2);
+ }
+}
diff --git a/DTObjectSerializing.c b/DTObjectSerializing.c
index bd68ddc..8633f8c 100644
--- a/DTObjectSerializing.c
+++ b/DTObjectSerializing.c
@@ -39,8 +39,8 @@ static const Object_Dir = 35;
static const Object_ComDir = 36;
static const Object_Origin = 37;
static const Object_Custom = 38;
-static const Object_Count = 39;
-//_enum(Object_, Status, Name, Owner, Controller, Killer, Category, Position, Speed, Con, OwnMass, Damage, Energy, MagicEnergy, Alive, Breath, ColorDw, Shape, Vertices, SolidMask, Picture, Entrance, Physicals, Action, Components, Contents, PlrViewRange, Visibility, BlitMode, CrewEnabled, ObjectLayer, Locals, Graphics, Effects, ID, ContactDensity, Dir, ComDir, Origin, Custom, Count)
+static const Object_CrewPlayer = 39;
+static const Object_Count = 40;
// DONT KNOW: OnFire, Commands
global func& LocalX(name, object obj)
@@ -62,12 +62,12 @@ global func GetEffectVarCount(object target, int effectNumber) // WARNING: this
var prio = GetEffect(0, target, effectNumber, 2);
var timer = GetEffect(0, target, effectNumber, 3);
var lifeTime = GetEffect(0, target, effectNumber, 6);
-
+
if(!name)
{
return -1;
}
-
+
// determine offset for this effect within GetObjectVal
for(var i = 0; ; ++i)
{
@@ -85,7 +85,7 @@ global func GetEffectVarCount(object target, int effectNumber) // WARNING: this
return 0;
}
}
-
+
}
return GetType(count) == C4V_Int && count;
}
@@ -96,6 +96,7 @@ global func GetObjectSaveData(object obj)
{
obj = obj || this;
var id = GetID(obj);
+ var owner = GetOwner(obj);
var ret = CreateArray(Object_Count);
ret[Object_ID] = id;
ret[Object_Origin] = obj;
@@ -104,7 +105,7 @@ global func GetObjectSaveData(object obj)
{
ret[Object_Name] = GetName(obj);
}
- ret[Object_Owner] = GetOwner(obj);
+ ret[Object_Owner] = owner;
ret[Object_Controller] = GetController(obj);
ret[Object_Killer] = GetKiller(obj);
ret[Object_Category] = GetCategory(obj);
@@ -119,7 +120,7 @@ global func GetObjectSaveData(object obj)
ret[Object_Breath] = GetBreath(obj);
ret[Object_ColorDw] = GetColorDw(obj);
ret[Object_Shape] = [GetObjectVal("Offset", 0, obj, 0), GetObjectVal("Offset", 0, obj, 1), GetObjectVal("Width", 0, obj), GetObjectVal("Height", 0, obj)];
-
+
if(GetObjectVal("OwnVertices", 0, obj))
{
var vertexNum = GetVertexNum(obj);
@@ -130,12 +131,30 @@ global func GetObjectSaveData(object obj)
}
ret[Object_Vertices] = vertices;
}
-
+
+ var crewPlayer = NO_OWNER;
+
+ if(CrewMember(obj))
+ {
+ for(var i = 0; i < GetCrewCount(owner); ++i)
+ {
+ if(GetCrew(owner, i) == obj)
+ {
+ crewPlayer = owner;
+ break;
+ }
+ }
+ }
+
+ ret[Object_CrewPlayer] = crewPlayer;
+
ret[Object_SolidMask] = GetSolidMask(obj);
ret[Object_Picture] = [GetObjectVal("Picture", 0, obj, 0), GetObjectVal("Picture", 0, obj, 1), GetObjectVal("Picture", 0, obj, 2), GetObjectVal("Picture", 0, obj, 3)];
ret[Object_Entrance] = GetEntrance(obj);
- ret[Object_Action] = [GetAction(obj), GetPhase(obj), GetActionTarget(0, obj), GetActionTarget(1, obj), GetObjectVal("ActionData", 0, obj)];
-
+
+ var action = GetAction(obj);
+ ret[Object_Action] = [action, GetPhase(obj), GetActionTarget(0, obj), GetActionTarget(1, obj), GetObjectVal("ActionData", 0, obj)];
+
var defComponents = [], objComponents = [];
for(var i = 0, componentID; componentID = GetComponent(0, i, 0, id); ++i)
{
@@ -153,7 +172,7 @@ global func GetObjectSaveData(object obj)
objComponents[GetLength(objComponents)] = [componentID, cnt];
}
}
-
+
var diffComponents = [];
for(var i = 0; i < GetLength(defComponents); ++i)
{
@@ -168,19 +187,19 @@ global func GetObjectSaveData(object obj)
break;
}
}
-
+
if(cnt != defCnt)
{
diffComponents[GetLength(diffComponents)] = [defID, cnt];
}
}
ArrayAppendArray(diffComponents, objComponents);
-
+
if(GetLength(diffComponents) != 0)
{
ret[Object_Components] = diffComponents;
}
-
+
var contents = [];
for(var content in obj->GetContents())
{
@@ -195,7 +214,7 @@ global func GetObjectSaveData(object obj)
ret[Object_Dir] = GetDir(obj);
ret[Object_ComDir] = GetComDir(obj);
ret[Object_ContactDensity] = GetObjectVal("ContactDensity", 0, obj);
-
+
var locals = [];
for(var f in [0, 1])
{
@@ -206,9 +225,9 @@ global func GetObjectSaveData(object obj)
locals[GetLength(locals)] = [name, LocalX(name, obj)];
}
}
-
+
ret[Object_Locals] = locals;
-
+
var overlays = [[GetGraphics(1, obj, 0), GetGraphics(0, obj, 0), 0, GetGraphics(2, obj, 0), GetGraphics(3, obj, 0), GetGraphics(4, obj, 0), 0, obj->GetObjDrawTransform(0), GetClrModulation(obj, 0)]];
var offset = 0, diffIndex = 0;
while((offset = obj->GetOverlayValueByIndex(diffIndex, offset)) >= 0)
@@ -217,8 +236,12 @@ global func GetObjectSaveData(object obj)
overlays[GetLength(overlays)] = [obj->GetOverlayValueByIndex(0, offset, 4), obj->GetOverlayValueByIndex(0, offset, 3), overlayID, obj->GetOverlayValueByIndex(0, offset, 2), obj->GetOverlayValueByIndex(0, offset, 5), obj->GetOverlayValueByIndex(0, offset, 6), Object(obj->GetOverlayValueByIndex(0, offset, 8)), obj->GetObjDrawTransform(-1, offset), GetClrModulation(obj, overlayID)];
diffIndex = 1;
}
+ if(GetActMapVal("FlipDir", action, id) && GetDir(obj) == DIR_Right)
+ {
+ overlays[0][7][0] *= -1;
+ }
ret[Object_Graphics] = overlays;
-
+
var physicals = []; // TODO: Think about StackTemporary? What about Effects? Maybe pop the whole stack while saving and restore afterwards
for(var physical in ["Energy", "Breath", "Walk", "Jump", "Scale", "Hangle", "Dig", "Swim", "Throw", "Push", "Fight", "Magic", "Float", "CanScale", "CanHangle", "CanDig", "CanConstruct", "CanChop", "CanSwimDig", "CanFly", "CorrosionResist", "BreatheWater"])
{
@@ -232,7 +255,7 @@ global func GetObjectSaveData(object obj)
{
ret[Object_Physicals] = physicals;
}
-
+
var effects = [];
for(var i = 0, index; index = GetEffect("*", obj, i, 0); ++i)
{
@@ -248,9 +271,9 @@ global func GetObjectSaveData(object obj)
{
ret[Object_Effects] = effects;
}
-
+
// TODO: Custom
-
+
return ret;
}
@@ -271,16 +294,22 @@ global func ApplyObjectSaveData(array data, object obj)
}
obj->DoEnergy(data[Object_Energy] - GetObjectVal("Energy", 0, obj), obj, true);
}
-
+
for(var content in data[Object_Contents])
{
var temp = obj->CreateContents(ROCK);
temp->ApplyObjectSaveData(content);
}
-
+
obj->ChangeDef(data[Object_ID]);
-
+
// the following changes should not call Callbacks anymore
+
+ if(data[Object_CrewPlayer] != NO_OWNER)
+ {
+ MakeCrewMember(obj, data[Object_CrewPlayer]);
+ }
+
obj->SetName(data[Object_Name]);
obj->SetController(data[Object_Controller]);
obj->SetKiller(data[Object_Killer]);
@@ -307,7 +336,7 @@ global func ApplyObjectSaveData(array data, object obj)
{
obj->AddVertex();
}
-
+
var i = 0;
for(var vertex in data[Object_Vertices])
{
@@ -318,13 +347,13 @@ global func ApplyObjectSaveData(array data, object obj)
++i;
}
}
-
+
var id = data[Object_ID];
for(var physical in ["Energy", "Breath", "Walk", "Jump", "Scale", "Hangle", "Dig", "Swim", "Throw", "Push", "Fight", "Magic", "Float", "CanScale", "CanHangle", "CanDig", "CanConstruct", "CanChop", "CanSwimDig", "CanFly", "CorrosionResist", "BreatheWater"])
{
obj->SetPhysical(physical, GetPhysical(physical, 0, 0, id), PHYS_Temporary);
}
-
+
if(data[Object_Physicals]) // TODO: Update for StackTemporary and try to represent right mode
{
for(var physical in data[Object_Physicals])
@@ -332,12 +361,12 @@ global func ApplyObjectSaveData(array data, object obj)
obj->SetPhysical(physical[0], physical[1], PHYS_Temporary);
}
}
-
+
for(var localVar in data[Object_Locals])
{
LocalX(localVar[0]) = localVar[1];
}
-
+
if(data[Object_Components])
{
for(var component in data[Object_Components])
@@ -352,19 +381,19 @@ global func ApplyObjectSaveData(array data, object obj)
obj->SetObjectLayer(data[Object_ObjectLayer]);
obj->SetContactDensity(data[Object_ContactDensity]);
obj->SetComDir(data[Object_ComDir]);
-
+
// unfortunately there is no SetAction without triggering CallCallbacks
// SetAction at last, so the important stuff is setup already
obj->SetAction(data[Object_Action][0], data[Object_Action][2], data[Object_Action][3], true);
obj->SetPhase(data[Object_Action][1]);
obj->SetActionData(data[Object_Action][4]);
-
+
obj->SetDir(data[Object_Dir]); // Set Dir after Action because Dirs are enabled per action
-
+
for(var graphic in data[Object_Graphics])
{
SetGraphics(graphic[0], obj, graphic[1], graphic[2], graphic[3], graphic[4], graphic[5], graphic[6]);
-
+
var transform = graphic[7];
if(GetLength(transform) == 6)
{
@@ -375,26 +404,26 @@ global func ApplyObjectSaveData(array data, object obj)
SetObjDrawTransform(1000, 0, 0, 0, 1000, 0, obj, graphic[2]);
obj->SetObjDrawTransform2(transform[0], transform[1], transform[2], transform[3], transform[4], transform[5], transform[6], transform[7], transform[8], graphic[2]);
}
-
+
SetClrModulation(graphic[8], obj, graphic[2]);
}
-
+
if(data[Object_Effects])
{
// WARNING: Can't restore lifetime
for(var effect in data[Object_Effects])
{
var temp = AddEffect("ApplyEffectDummy", obj, effect[1], effect[2], effect[3], effect[4]);
-
+
for(var i = 0; i < GetLength(effect[6]); ++i)
{
EffectVar(i, obj, temp) = effect[6][i];
}
-
+
ChangeEffect(0, obj, temp, effect[0], -1);
}
}
-
+
// TODO: Custom
}
@@ -403,4 +432,4 @@ global func InstantiateObjectSaveData(array data)
var ret = CreateObject(ROCK);
ret->ApplyObjectSaveData(data);
return ret;
-}
+} \ No newline at end of file
diff --git a/DTPlayers.c b/DTPlayers.c
index ab75aef..5a688e6 100644
--- a/DTPlayers.c
+++ b/DTPlayers.c
@@ -2,12 +2,12 @@
#strict 2
static const Player_Number = 0;
-static const Player_ID = 0 + 1;
-static const Player_Name = 0 + 1 + 1;
-static const Player_TaggedName = 0 + 1 + 1 + 1;
-static const Player_Color = 0 + 1 + 1 + 1 + 1;
-static const Player_Team = 0 + 1 + 1 + 1 + 1 + 1;
-static const Player_Type = 0 + 1 + 1 + 1 + 1 + 1 + 1;
+static const Player_ID = 1;
+static const Player_Name = 2;
+static const Player_TaggedName = 3;
+static const Player_Color = 4;
+static const Player_Team = 5;
+static const Player_Type = 6;
global func GetPlayers(int team, bool exclude)
{
@@ -50,10 +50,10 @@ global func GetTaggedTeamName(int team)
}
static const Team_ID = 0;
-static const Team_Name = 0 + 1;
-static const Team_TaggedName = 0 + 1 + 1;
-static const Team_Color = 0 + 1 + 1 + 1;
-static const Team_Players = 0 + 1 + 1 + 1 + 1;
+static const Team_Name = 1;
+static const Team_TaggedName = 2;
+static const Team_Color = 3;
+static const Team_Players = 4;
global func GetTeams()
{
@@ -79,4 +79,4 @@ global func GetTeamIDs()
ret[GetLength(ret)] = team;;
}
return ret;
-}
+} \ No newline at end of file
diff --git a/DTQuickSort.c b/DTQuickSort.c
index 7434263..8f480ca 100644
--- a/DTQuickSort.c
+++ b/DTQuickSort.c
@@ -17,17 +17,17 @@ global func SortNumericInverse(int a, int b)
return -SortNumeric(a, b);
}
-global func QSort(array& data, callback) // WARNING: Can cause stack-overflow with too much data
+global func QSort(array& data, callback, callbackArgs) // WARNING: Can cause stack-overflow with too much data
{
if(callback == true)
{
callback = GlobalCallback("SortNumericInverse");
}
- QSort_Part(data, callback || GlobalCallback("SortNumeric"), 0, GetLength(data) - 1);
+ QSort_Part(data, callback || GlobalCallback("SortNumeric"), 0, GetLength(data) - 1, callbackArgs);
return data;
}
-global func QSort_Part(array& data, callback, int left, int right)
+global func QSort_Part(array& data, callback, int left, int right, callbackArgs)
{
if(left < right)
{
@@ -35,16 +35,16 @@ global func QSort_Part(array& data, callback, int left, int right)
var pPos = RandomX(left, right);
var p = data[pPos];
var tmp;
-
+
tmp = data[pPos];
data[pPos] = data[right];
data[right] = tmp;
pPos = right;
-
+
var i = left - 1;
for(var j = left; j <= right; ++j)
{
- if(Call(callback, data[j], p) < 0)
+ if(Call(callback, data[j], p, callbackArgs) < 0)
{
++i;
tmp = data[i];
@@ -52,15 +52,15 @@ global func QSort_Part(array& data, callback, int left, int right)
data[j] = tmp;
}
}
-
+
++i;
-
+
tmp = data[i];
data[i] = data[pPos];
data[pPos] = tmp;
// -----
-
- QSort_Part(data, callback, left, i - 1);
- QSort_Part(data, callback, i + 1, right);
+
+ QSort_Part(data, callback, left, i - 1, callbackArgs);
+ QSort_Part(data, callback, i + 1, right, callbackArgs);
}
}
diff --git a/DTScopedVars.c b/DTScopedVars.c
index f64ccdc..0cde670 100644
--- a/DTScopedVars.c
+++ b/DTScopedVars.c
@@ -1,5 +1,4 @@
#strict 2
-
// TODO: ScopedVars with temporary target (like a reference to a function local var)
static const ScopedVar_Global = 1;
@@ -49,11 +48,22 @@ global func &ScopedVar(array variable)
}
else
{
- return ScopedVar(CustomScopedVar(variable));
+ if(this)
+ {
+ return ScopedVar(this->~CustomScopedVar(variable));
+ }
+ else if(GetID())
+ {
+ return ScopedVar(GetID()->~CustomScopedVar(variable));
+ }
+ else
+ {
+ return ScopedVar(CustomScopedVar(variable));
+ }
}
}
-global func &CustomScopedVar() { return _inherited(...); } // this allows "overloading" this function even if the "overloading" function is loaded before
+global func CustomScopedVar() { return _inherited(...); } // this allows "overloading" this function even if the "overloading" function is loaded before
global func CheckScopedVar(array variable)
{
@@ -81,7 +91,18 @@ global func CheckScopedVar(array variable)
}
}
- return CheckCustomScopedVar(variable);
+ if(this)
+ {
+ return this->~CheckCustomScopedVar(variable);
+ }
+ else if(GetID())
+ {
+ return GetID()->~CheckCustomScopedVar(variable);
+ }
+ else
+ {
+ return CheckCustomScopedVar(variable);
+ }
}
-global func CheckCustomScopedVar() { return _inherited(...); }
+global func CheckCustomScopedVar() { return _inherited(...); } \ No newline at end of file
diff --git a/DTTransform.c b/DTTransform.c
index 07206c2..d155827 100644
--- a/DTTransform.c
+++ b/DTTransform.c
@@ -5,7 +5,7 @@ global func ResetTransform(overlays)
for(var overlay in TransformOverlays(overlays))
{
if(!overlay) SetObjDrawTransform(0, 0, 0, 0, 0, 0, this, overlay);
- else SetObjDrawTransform(1000, 0, 0, 0, 1000, 0, this, overlay);
+ else SetObjDrawTransform(1000, 0, 0, 0, 1000, 0, this, overlay);
}
}
@@ -76,7 +76,7 @@ global func TransformOverlays(overlays)
}
last = overlay;
}
-
+
return ret;
}
else
@@ -90,10 +90,10 @@ global func Rotate() { return RotateZ(...); }
global func RotateX(int phi, int prec)
{
prec = prec || 1;
-
+
var cos = Cos(phi, 1000, prec);
var sin = Sin(phi, 1000, prec);
-
+
return
[
[1000, 0, 0],
@@ -105,10 +105,10 @@ global func RotateX(int phi, int prec)
global func RotateY(int phi, int prec)
{
prec = prec || 1;
-
+
var cos = Cos(phi, 1000, prec);
var sin = Sin(phi, 1000, prec);
-
+
return
[
[ cos, 0, sin],
@@ -120,10 +120,10 @@ global func RotateY(int phi, int prec)
global func RotateZ(int phi, int prec)
{
prec = prec || 1;
-
+
var cos = Cos(phi, 1000, prec);
var sin = Sin(phi, 1000, prec);
-
+
return
[
[cos, -sin, 0],
@@ -182,16 +182,6 @@ global func MirrorY()
];
}
-global func MirrorZ() // useless?
-{
- return
- [
- [1000, 0, 0],
- [ 0, 1000, 0],
- [ 0, 0, -1000]
- ];
-}
-
global func Skew2D(int x, int y)
{
return
@@ -209,13 +199,15 @@ global func Matrix3x3Multiply(array a, array b, int precision)
{
return
[
- [(a[0][2] * b[2][0] + a[0][1] * b[1][0] + a[0][0] * b[0][0]) / precision, (a[0][2] * b[2][1] + a[0][1] * b[1][1] + a[0][0] * b[0][1]) / precision, (a[0][2] * b[2][2] + a[0][1] * b[1][2] + a[0][0] * b[0][2]) / precision],
- [(a[1][2] * b[2][0] + a[1][1] * b[1][0] + a[1][0] * b[0][0]) / precision, (a[1][2] * b[2][1] + a[1][1] * b[1][1] + a[1][0] * b[0][1]) / precision, (a[1][2] * b[2][2] + a[1][1] * b[1][2] + a[1][0] * b[0][2]) / precision],
- [(a[2][2] * b[2][0] + a[2][1] * b[1][0] + a[2][0] * b[0][0]) / precision, (a[2][2] * b[2][1] + a[2][1] * b[1][1] + a[2][0] * b[0][1]) / precision, (a[2][2] * b[2][2] + a[2][1] * b[1][2] + a[2][0] * b[0][2]) / precision]
+ [(a[2][0] * b[0][2] + a[1][0] * b[0][1] + a[0][0] * b[0][0]) / precision, (a[2][1] * b[0][2] + a[1][1] * b[0][1] + a[0][1] * b[0][0]) / precision, (a[2][2] * b[0][2] + a[1][2] * b[0][1] + a[0][2] * b[0][0]) / precision],
+ [(a[2][0] * b[1][2] + a[1][0] * b[1][1] + a[0][0] * b[1][0]) / precision, (a[2][1] * b[1][2] + a[1][1] * b[1][1] + a[0][1] * b[1][0]) / precision, (a[2][2] * b[1][2] + a[1][2] * b[1][1] + a[0][2] * b[1][0]) / precision],
+ [(a[2][0] * b[2][2] + a[1][0] * b[2][1] + a[0][0] * b[2][0]) / precision, (a[2][1] * b[2][2] + a[1][1] * b[2][1] + a[0][1] * b[2][0]) / precision, (a[2][2] * b[2][2] + a[1][2] * b[2][1] + a[0][2] * b[2][0]) / precision]
];
}
-global func PreTransform(array transforms) // funzt nit
+// Combines several transforms (as used for SetTransform) into one transform. Returns a single transform (like all other transform functions).
+// May be used to cache transforms. For direct application use SetTransform instead, which implicitly uses the native engine implementation of matrix multiplication.
+global func PreTransform(array transforms)
{
if(GetLength(transforms) == 0)
{
@@ -232,9 +224,12 @@ global func PreTransform(array transforms) // funzt nit
}
}
-// Riesenschädl
-// GetCursor(0)->SetTransform([TranslateY(8), RotateX(4), ScaleZ(400), TranslateY(-10)])
+// Examples
+
+// Clonk with giant head:
+// GetCursor0->SetTransform([TranslateY(8), RotateX(4), ScaleZ(400), TranslateY(-10)])
-// Ähnlich Chipakyus Demo
+// 3D-Rotating Hut:
// Schedule("FindObject(HUT2)->SetTransform([TranslateY(-20), RotateZ(++Global(0)), TranslateY(0), RotateX(-1), TranslateY(20)])", 1, 10000)
-// Schedule("GetCursor(0)->SetTransform([TranslateY(-8), RotateZ(++Global(0)), TranslateY(0), RotateX(-2), TranslateY(8)])", 1, 10000)
+// 3D-Rotating Clonk:
+// Schedule("GetCursor(0)->SetTransform([TranslateY(-8), RotateZ(++Global(0)), TranslateY(0), RotateX(-2), TranslateY(8)])", 1, 10000) \ No newline at end of file
diff --git a/DTUtility.c b/DTUtility.c
index a747d33..481ebe9 100644
--- a/DTUtility.c
+++ b/DTUtility.c
@@ -56,14 +56,14 @@ global func EscapeString(string value)
}
else if(c == 92) // \
{
- ret = Format("%s\\\\", ret);
- }
- else
- {
- ret = Format("%s%c", ret, c);
+ ret = Format("%s\\\\", ret);
+ }
+ else
+ {
+ ret = Format("%s%c", ret, c);
+ }
}
-}
-return ret;
+ return ret;
}
global func CreateEnum(string prefix, array enum)
@@ -445,7 +445,7 @@ global func ParseFloat(string float, int precision) // precision = number of dig
// out of precision
break;
}
-
+
var c = GetChar(float, i);
if(i == 0)
{
@@ -479,12 +479,12 @@ global func ParseFloat(string float, int precision) // precision = number of dig
{
decimalPoint = i - 1;
}
-
+
for(; i <= decimalPoint + precision; ++i)
{
ret *= 10;
}
-
+
return ret * (1 - (2 * neg));
}
@@ -514,7 +514,7 @@ global func Find_ProcedureCheck(string proc)
global func GetSolidMask(object obj)
{
obj = obj || this;
- return
+ return
[
GetObjectVal("SolidMask", 0, obj, 0), GetObjectVal("SolidMask", 0, obj, 1),
GetObjectVal("SolidMask", 0, obj, 2), GetObjectVal("SolidMask", 0, obj, 3),
@@ -606,7 +606,7 @@ global func GetOverlayValueByIndex(int index, int startIndex, int getValue, obje
//something went wrong already
return -3;
}
-
+
if(found)
{
if(getValue == 5)
@@ -622,23 +622,23 @@ global func GetOverlayValueByIndex(int index, int startIndex, int getValue, obje
return i + 4;
}
}
-
+
i += 10; // this is either the last row of the Transformation matrix or the Color-Modulation
val = GetObjectVal("GfxOverlay", 0, obj, i);
-
+
if(GetType(val) == C4V_String)
{
// part of the matrix, skip it
i += 3;
}
-
+
if(found && getValue == 8)
{
return GetObjectVal("GfxOverlay", 0, obj, i + 2);
}
-
+
i += 3; // and the rest
-
+
if(++foundIndex == index)
{
if(GetObjectVal("GfxOverlay", 0, obj, i) == 0)
@@ -659,7 +659,7 @@ global func GetOverlayValueByIndex(int index, int startIndex, int getValue, obje
}
}
}
-
+
++i; // skip the next overlay ID
}
}
@@ -667,7 +667,7 @@ global func GetOverlayValueByIndex(int index, int startIndex, int getValue, obje
global func GetOverlayValueOffsetByID(int overlay, object obj)
{
obj = obj || this;
-
+
if(overlay != 0)
{
var offset = 0, diffIndex = 0;
@@ -680,7 +680,7 @@ global func GetOverlayValueOffsetByID(int overlay, object obj)
diffIndex = 1;
}
}
-
+
return -1;
}
@@ -695,7 +695,7 @@ global func GetObjDrawTransform(int overlay, int overlayOffset, object obj)
return [1000, 0, 0, 0, 1000, 0];
}
var ret = [ParseFloat(first, 3), ParseFloat(GetObjectVal("DrawTransform", 0, obj, 1), 3), ParseFloat(GetObjectVal("DrawTransform", 0, obj, 2), 3), ParseFloat(GetObjectVal("DrawTransform", 0, obj, 3), 3), ParseFloat(GetObjectVal("DrawTransform", 0, obj, 4), 3), ParseFloat(GetObjectVal("DrawTransform", 0, obj, 5), 3)];
-
+
var rest = GetObjectVal("DrawTransform", 0, obj, 7); // 6 is left out intentionally, because its only FlipDir (used internally for Actions with FlipDir)
if(GetType(rest) == C4V_String) // the last 3 matrix-values are only decompiled if they are not the default of [0, 0, 1.0]
{
@@ -704,7 +704,7 @@ global func GetObjDrawTransform(int overlay, int overlayOffset, object obj)
ret[7] = ParseFloat(GetObjectVal("DrawTransform", 0, obj, 8), 3);
ret[8] = ParseFloat(GetObjectVal("DrawTransform", 0, obj, 9), 3);
}
-
+
return ret;
}
else
@@ -727,9 +727,9 @@ global func GetObjDrawTransform(int overlay, int overlayOffset, object obj)
{
return index;
}
-
+
var ret = [ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index), 3), ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 1), 3), ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 2), 3), ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 3), 3), ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 4), 3), ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 5), 3)];
-
+
var rest = GetObjectVal("GfxOverlay", 0, obj, index + 7); // 6 is left out intentionally, because its only FlipDir (used internally for Actions with FlipDir)
if(GetType(rest) == C4V_String) // the last 3 matrix-values are only decompiled if they are not the default of [0, 0, 1.0]
{
@@ -738,7 +738,33 @@ global func GetObjDrawTransform(int overlay, int overlayOffset, object obj)
ret[7] = ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 8), 3);
ret[8] = ParseFloat(GetObjectVal("GfxOverlay", 0, obj, index + 9), 3);
}
-
+
return ret;
}
}
+
+global func GetShape(object obj)
+{
+ obj = obj || this;
+ return [GetObjectVal("Offset", 0, obj, 0), GetObjectVal("Offset", 0, obj, 1), GetObjectVal("Width", 0, obj), GetObjectVal("Height", 0, obj)];
+}
+
+global func InRect(array point, array rect)
+{
+ var x = point[0], y = point[1];
+ return rect[0] < x && x < rect[0] + rect[2] && rect[1] < y && y < rect[1] + rect[3];
+}
+
+global func GetPlayerByID(int id)
+{
+ for(var i = 0; i < GetPlayerCount(); ++i)
+ {
+ var plr = GetPlayerByIndex(i);
+ if(GetPlayerID(plr) == id)
+ {
+ return plr;
+ }
+ }
+
+ return NO_OWNER;
+}