diff options
Diffstat (limited to 'System.c4g/DTSelectionContext.c')
| -rw-r--r-- | System.c4g/DTSelectionContext.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/System.c4g/DTSelectionContext.c b/System.c4g/DTSelectionContext.c new file mode 100644 index 0000000..794029c --- /dev/null +++ b/System.c4g/DTSelectionContext.c @@ -0,0 +1,389 @@ +#strict 2 +#appendto CLNK + +global func SetAllCursorsCommand(int player) +{ + var ret; + for(var i = 0, cursor; cursor = GetCursor(player, i); ++i) + { + ret = SetCommand(cursor, ...) || ret; + ExecuteCommand(cursor); + } + return ret; +} + +local selectionObjects, selectMark; + +func FindTreeCriteria() +{ + return Find_And(Find_AtPoint(), Find_OCF(OCF_Chop), Find_Layer(GetObjectLayer())); +} + +func CreateSelectionMenu(string callback, array objects, id symbol, string caption, object callbackObject) +{ + SetComDir(COMD_Stop); + var ret = CreateMenu(symbol, this, callbackObject || this, C4MN_Extra_None, caption, 0, C4MN_Style_Context, 0, SELM); + selectionObjects = objects; + for(var obj in objects) + { + if(GetType(obj) == C4V_C4Object) + { + AddMenuItem(GetName(obj), callback, GetID(obj), this, 0, obj, 0, C4MN_Add_ForceNoDesc | C4MN_Add_ImgObject, obj); + } + else + { + AddMenuItem(obj[1] || GetName(obj[0]), callback, obj[2] || GetID(obj[0]), this, 0, obj[0], 0, C4MN_Add_ForceNoDesc | ((!obj[2]) && C4MN_Add_ImgObject), obj[0]); + } + } + EffectCall(this, AddEffect("IntShowSelection", this, 100, 2, this), "Timer"); + return ret; +} + +func FxIntShowSelectionTimer(object target, int effectNumber) +{ + if(GetMenu(target) != SELM) + { + if(selectMark) + { + RemoveObject(selectMark); + } + return FX_Execute_Kill; + } + else + { + var obj = selectionObjects[GetMenuSelection(target)]; + if(!obj) + { + if(selectMark) + { + RemoveObject(selectMark); + } + } + else + { + selectMark = selectMark || CreateSelectMark(); + if(GetType(obj) == C4V_Array) + { + selectMark->MarkObject(obj[0]); + } + else + { + selectMark->MarkObject(obj); + } + } + } +} + +func ContextChop() +{ + [$CtxChop$|Image=CXCP|Condition=AtTreeToChop] + var objs = FindObjects(FindTreeCriteria()); + if(GetLength(objs) > 1) + { + CreateSelectionMenu("ChopObject", objs, CXCP, "$CtxChop$"); + return true; + } + else + { + return _inherited(...); + } +} + +func ChopObject(id id, object tree) +{ + if(tree) SetAllCursorsCommand(GetController(this), "Chop", tree); +} + +func FindConstructionSiteCriteria() +{ + return Find_And(Find_AtRect(GetDefOffset(GetID(this)), GetDefOffset(GetID(this), 1), GetObjWidth(this), GetObjHeight(this) + 10), Find_OCF(OCF_Construct)); +} + +func AtConstructionSite() { return !Contained() && FindConstructionSite(); } + +func ContextConstructionSite() +{ + [$CtxConstructionSite$|Image=CXCM|Condition=AtConstructionSite] + var objs = FindObjects(FindConstructionSiteCriteria()); + if(GetLength(objs) > 1) + { + CreateSelectionMenu("ConstructionSiteMenu", objs, CXCM, "$CtxConstructionSite$"); + } + else + { + ConstructionSiteMenu(0, FindConstructionSite()); + } +} + +func ConstructionSiteMenu(id id, object site) +{ + if(ObjectCount(CNMT)) + { + SetComDir(COMD_Stop); + CreateMenu(GetID(site), this, this, C4MN_Extra_None, GetName(site), 0, C4MN_Style_Context, 0); + AddMenuItem("$CtxConstructionMaterial$", "ConstructionSiteMat", CXCM, this, 0, site, 0, C4MN_Add_ForceNoDesc); + AddMenuItem("$CtxConstructionContinue$", "ConstructionSiteContinue", CXCN, this, 0, site, 0, C4MN_Add_ForceNoDesc); + } + else + { + ConstructionSiteContinue(id, site); + } +} + +func ConstructionSiteMat(id id, object site) +{ + if(site) PlayerMessage(GetOwner(), site->GetNeededMatStr(), site); +} + +func ConstructionSiteContinue(id id, object site) +{ + if(site) SetAllCursorsCommand(GetController(this), "Build", site); +} + +func FindGrabbableObjectCriteria() +{ + return Find_And(Find_AtRect(GetDefOffset(GetID(this)), GetDefOffset(GetID(this), 1), GetObjWidth(this), GetObjHeight(this)), Find_OCF(OCF_Grab), Find_NoContainer()); +} + +func AtGrabbableObject() { return !Contained() && FindObject2(FindGrabbableObjectCriteria()); } + +func ContextGrab() +{ + [$CtxGrab$|Image=CXIV|Condition=AtGrabbableObject] + var objs = FindObjects(FindGrabbableObjectCriteria()); + if(GetLength(objs) > 1) + { + if(GetProcedure() == "PUSH") + { + for(var i = 0; i < GetLength(objs) ; ++i) + { + if(GetActionTarget() == objs[i]) + { + objs[i] = [objs[i], "$Release$"]; + } + } + } + CreateSelectionMenu("GrabObject", objs, CXIV, "$CtxGrab$"); + } + else + { + GrabObject(0, objs[0]); + } +} + +func GrabObject(id id, object obj) +{ + if(obj) + { + if(GetProcedure() == "PUSH" && obj == GetActionTarget()) + { + SetAllCursorsCommand(GetController(this), "UnGrab"); + } + else + { + SetAllCursorsCommand(GetController(this), "Grab", obj); + } + } +} + +func FindEnterableObjectCriteria() +{ + return Find_And(Find_AtRect(GetDefOffset(GetID(this)), GetDefOffset(GetID(this), 1), GetObjWidth(this), GetObjHeight(this)), Find_OCF(OCF_Entrance), Find_NoContainer(), Find_Not(Find_Func("HiddenEntrance"))); +} + +func AtEnterableObject() { return !Contained() && FindObject2(FindEnterableObjectCriteria()); } + +func ContextEnter() +{ + [$CtxEnter$|Image=DOOR|Condition=AtEnterableObject] + var objs = FindObjects(FindEnterableObjectCriteria()); + if(GetLength(objs) > 1) + { + CreateSelectionMenu("EnterObject", objs, DOOR, "$CtxEnter$"); + } + else + { + EnterObject(0, objs[0]); + } +} + +func EnterObject(id id, object obj) +{ + if(obj) + { + if(GetProcedure() == "PUSH" && GetActionTarget() && !GetDefNoPushEnter(GetID(GetActionTarget()))) + { + SetAllCursorsCommand(GetController(this), "PushTo", GetActionTarget(), 0, 0, obj); + } + else + { + SetAllCursorsCommand(GetController(this), "Enter", obj); + } + } +} + +func AtObjectWithLines() +{ + return !Contained() && FindConnections(true); +} + +func FindConnections(bool single) +{ + var targets = FindObjects(Find_OCF(OCF_LineConstruct), Find_AtPoint(), Find_Exclude(this)); + var connections = []; + for(var target in targets) + { + var lines = FindObjects(Find_Action("Connect"), Find_Or(Find_ActionTarget(target), Find_ActionTarget2(target))); + for(var line in lines) + { + if(GetID(GetActionTarget(0, line)) == LNKT || GetID(GetActionTarget(1, line)) == LNKT) // not connected on the other side + { + continue; + } + var otherTarget = GetActionTarget(0, line); + if(otherTarget == target) + { + otherTarget = GetActionTarget(1, line); + } + var connection = [target, line, otherTarget]; + if(single) + { + return connection; + } + else + { + connections[GetLength(connections)] = connection; + } + } + } + if(!single) + { + return connections; + } +} + +local lineConnectionSelections; + +func ContextRemoveLine() +{ + [$TxtRemoveLine$|Image=LNKT|Condition=AtObjectWithLines] + lineConnectionSelections = FindConnections(); + if(GetLength(lineConnectionSelections) > 1) + { + SetComDir(COMD_Stop); + CreateMenu(LNKT, this, this, C4MN_Extra_None, "$TxtRemoveLine$", 0, C4MN_Style_Context, 0, SELM); + var i = 0; + for(var connection in lineConnectionSelections) + { + AddMenuItem(Format("%s: %s - %s", GetName(connection[1]), GetName(connection[0]), GetName(connection[2])), "RemoveLineEntry", GetID(connection[1]), this, 0, i++, 0, C4MN_Add_ForceNoDesc); + } + AddEffect("IntShowDoubleSelection", this, 100, 1, this); + } + else + { + return RemoveLineEntry(0, 0); + } + return 1; +} + +local selectMark2; + +func FxIntShowDoubleSelectionTimer(object target, int effectNumber) +{ + if(GetMenu(target) != SELM) + { + if(selectMark) + { + RemoveObject(selectMark); + } + if(selectMark2) + { + RemoveObject(selectMark2); + } + return FX_Execute_Kill; + } + else + { + var obj = lineConnectionSelections[GetMenuSelection(target)]; + if(!obj[0]) + { + if(selectMark) + { + RemoveObject(selectMark); + } + } + else + { + selectMark = selectMark || CreateSelectMark(); + selectMark->MarkObject(obj[0]); + } + if(!obj[2]) + { + if(selectMark2) + { + RemoveObject(selectMark2); + } + } + else + { + selectMark2 = selectMark2 || CreateSelectMark()->Secondary(); + selectMark2->MarkObject(obj[2]); + } + } +} + +func RemoveLineEntry(id id, int pos) +{ + var connection = lineConnectionSelections[pos]; + if(!connection || !GetPhysical("CanConstruct")) + { + return; + } + if((GetActionTarget(0, connection[1]) != connection[0] && GetActionTarget(1, connection[1]) != connection[0]) || (GetActionTarget(0, connection[1]) != connection[2] && GetActionTarget(1, connection[1]) != connection[2])) + { + Message("$AlreadyDisconnected$", this); + Sound("Error"); + return false; + } + + var lnkt = CreateObject(LNKT, 0, 0, GetOwner()); + Collect(lnkt); + Sound("Connect"); + if(GetActionTarget(0, connection[1]) == connection[0]) + { + SetActionTargets(lnkt, connection[2], connection[1]); + } + else + { + SetActionTargets(connection[2], lnkt, connection[1]); + } + Message("$IDS_OBJ_DISCONNECT$", this, GetName(connection[1]), GetName(connection[0])); + return true; +} + +func ControlDigDouble() +{ + var ret = _inherited(...); + if(!ret) + { + if((GetProcedure() == "WALK" || GetProcedure() == "DIG" || GetProcedure() == "SWIM")) + { + if(Contents() && Contents()->~Activate(this)) + { + return true; + } + else if((AtTreeToChop() && GetProcedure() != "SWIM") && ContextChop()) + { + return true; + } + else if(AtObjectWithLines()) + { + if(ContextRemoveLine()) + { + return true; + } + } + } + } + return ret; +} |
