diff options
| -rw-r--r-- | DTCallback.c | 116 | ||||
| -rw-r--r-- | DTFilterObjects.c | 318 | ||||
| -rw-r--r-- | DTMenuCompatibility.c | 46 | ||||
| -rw-r--r-- | DTObjectSerializing.c | 107 | ||||
| -rw-r--r-- | DTPlayers.c | 22 | ||||
| -rw-r--r-- | DTQuickSort.c | 22 | ||||
| -rw-r--r-- | DTScopedVars.c | 31 | ||||
| -rw-r--r-- | DTTransform.c | 47 | ||||
| -rw-r--r-- | DTUtility.c | 76 |
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;
+}
|
