From 926016d90b0f0341612d7de0d7157dde54036457 Mon Sep 17 00:00:00 2001 From: George Tokmaji Date: Wed, 15 Nov 2023 01:56:44 +0100 Subject: [PATCH] Add sections to script contexts and make global effects section-local --- src/C4Aul.h | 8 +- src/C4AulExec.cpp | 29 +++-- src/C4Command.cpp | 6 +- src/C4Console.cpp | 4 +- src/C4Control.cpp | 32 ++++- src/C4Control.h | 39 +++--- src/C4Def.cpp | 26 ++-- src/C4Def.h | 12 +- src/C4DefGraphics.cpp | 2 +- src/C4EditCursor.cpp | 2 +- src/C4Effect.cpp | 45 +++++-- src/C4Effects.h | 5 +- src/C4FindObject.cpp | 4 +- src/C4ForwardDeclarations.h | 1 + src/C4FullScreen.cpp | 2 +- src/C4Game.cpp | 33 ++--- src/C4Game.h | 16 ++- src/C4GameMessage.cpp | 43 ++++--- src/C4GameMessage.h | 13 +- src/C4GameObjects.cpp | 10 +- src/C4GameObjects.h | 2 +- src/C4Gui.h | 4 +- src/C4GuiDialogs.cpp | 16 +-- src/C4InfoCore.cpp | 4 +- src/C4InfoCore.h | 2 +- src/C4Landscape.cpp | 4 +- src/C4MainMenu.cpp | 55 ++++---- src/C4MainMenu.h | 8 +- src/C4MapCreatorS2.cpp | 13 +- src/C4MapCreatorS2.h | 10 +- src/C4Material.cpp | 2 +- src/C4Menu.cpp | 12 +- src/C4Menu.h | 5 +- src/C4MessageInput.cpp | 10 +- src/C4Object.cpp | 65 +++++----- src/C4Object.h | 2 - src/C4ObjectCom.cpp | 2 +- src/C4ObjectMenu.cpp | 33 +++-- src/C4ObjectMenu.h | 2 +- src/C4Player.cpp | 26 ++-- src/C4Player.h | 6 +- src/C4Script.cpp | 246 ++++++++++++++++++------------------ src/C4ScriptHost.cpp | 14 +- src/C4ScriptHost.h | 12 +- src/C4Section.cpp | 31 ++++- src/C4Section.h | 5 + src/C4Viewport.cpp | 4 +- src/C4Wrappers.cpp | 10 +- 48 files changed, 528 insertions(+), 409 deletions(-) diff --git a/src/C4Aul.h b/src/C4Aul.h index 5240b1a31..f00435dee 100644 --- a/src/C4Aul.h +++ b/src/C4Aul.h @@ -251,9 +251,11 @@ struct C4AulContext { C4Object *Obj; C4Def *Def; + C4Section *Section; struct C4AulScriptContext *Caller; bool CalledWithStrictNil() const noexcept; + C4Section &GetSection() const noexcept; }; // execution context @@ -304,7 +306,7 @@ class C4AulFunc virtual const C4V_Type *GetParType() { return nullptr; } virtual C4V_Type GetRetType() { return C4V_Any; } virtual C4Value Exec(C4AulContext *pCallerCtx, const C4Value pPars[], bool fPassErrors = false) { return C4Value(); } // execute func (script call) - virtual C4Value Exec(C4Object *pObj = nullptr, const C4AulParSet &pPars = C4AulParSet{}, bool fPassErrors = false, bool nonStrict3WarnConversionOnly = false, bool convertNilToIntBool = true); // execute func (engine call) + virtual C4Value Exec(C4Section §ion, C4Object *pObj = nullptr, const C4AulParSet &pPars = C4AulParSet{}, bool fPassErrors = false, bool nonStrict3WarnConversionOnly = false, bool convertNilToIntBool = true); // execute func (engine call) virtual void UnLink() { OverloadedBy = NextSNFunc = nullptr; } C4AulFunc *GetLocalSFunc(const char *szIdtf); // find script function in own scope @@ -356,7 +358,7 @@ class C4AulScriptFunc : public C4AulFunc virtual const C4V_Type *GetParType() override { return ParType; } virtual C4V_Type GetRetType() override { return bReturnRef ? C4V_pC4Value : C4V_Any; } virtual C4Value Exec(C4AulContext *pCallerCtx, const C4Value pPars[], bool fPassErrors = false) override; // execute func (script call, should not happen) - virtual C4Value Exec(C4Object *pObj = nullptr, const C4AulParSet &pPars = C4AulParSet{}, bool fPassErrors = false, bool nonStrict3WarnConversionOnly = false, bool convertNilToIntBool = true) override; // execute func (engine call) + virtual C4Value Exec(C4Section §ion, C4Object *pObj = nullptr, const C4AulParSet &pPars = C4AulParSet{}, bool fPassErrors = false, bool nonStrict3WarnConversionOnly = false, bool convertNilToIntBool = true) override; // execute func (engine call) void CopyBody(C4AulScriptFunc &FromFunc); // copy script/code, etc from given func @@ -505,7 +507,7 @@ class C4AulScript C4AulAccess GetAllowedAccess(C4AulFunc *func, C4AulScript *caller); public: - C4Value DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors = false, C4AulScriptStrict Strict = C4AulScriptStrict::MAXSTRICT); // directly parse uncompiled script (WARG! CYCLES!) + C4Value DirectExec(C4Section §ion, C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors = false, C4AulScriptStrict Strict = C4AulScriptStrict::MAXSTRICT); // directly parse uncompiled script (WARG! CYCLES!) void ResetProfilerTimes(); // zero all profiler times of owned functions void CollectProfilerTimes(class C4AulProfiler &rProfiler); diff --git a/src/C4AulExec.cpp b/src/C4AulExec.cpp index c2b879553..14cb73227 100644 --- a/src/C4AulExec.cpp +++ b/src/C4AulExec.cpp @@ -39,9 +39,9 @@ void C4AulExecError::show() const // debug mode object message if (Game.DebugMode) if (cObj) - Game.Messages.New(C4GM_Target, sMessage, cObj, NO_OWNER); + Game.Messages.New(C4GM_Target, sMessage, cObj->Section, cObj, NO_OWNER); else - Game.Messages.New(C4GM_Global, sMessage, nullptr, ANY_OWNER); + Game.Messages.New(C4GM_Global, sMessage, nullptr, nullptr, ANY_OWNER); } bool C4AulContext::CalledWithStrictNil() const noexcept @@ -49,6 +49,11 @@ bool C4AulContext::CalledWithStrictNil() const noexcept return Caller && Caller->Func->HasStrictNil(); } +C4Section &C4AulContext::GetSection() const noexcept +{ + return Obj ? *Obj->Section : *Section; +} + const int MAX_CONTEXT_STACK = 512; const int MAX_VALUE_STACK = 1024; @@ -116,7 +121,7 @@ class C4AulExec C4AulScript *pProfiledScript; public: - C4Value Exec(C4AulScriptFunc *pSFunc, C4Object *pObj, const C4Value pPars[], bool fPassErrors, bool fTemporaryScript = false); + C4Value Exec(C4AulScriptFunc *pSFunc, C4Section §ion, C4Object *pObj, const C4Value pPars[], bool fPassErrors, bool fTemporaryScript = false); C4Value Exec(C4AulBCC *pCPos, bool fPassErrors); void StartTrace(); @@ -315,7 +320,7 @@ class C4AulExec C4AulExec AulExec; -C4Value C4AulExec::Exec(C4AulScriptFunc *pSFunc, C4Object *pObj, const C4Value *pnPars, bool fPassErrors, bool fTemporaryScript) +C4Value C4AulExec::Exec(C4AulScriptFunc *pSFunc, C4Section §ion, C4Object *pObj, const C4Value *pnPars, bool fPassErrors, bool fTemporaryScript) { // Push parameters C4Value *pPars = pCurVal + 1; @@ -338,6 +343,7 @@ C4Value C4AulExec::Exec(C4AulScriptFunc *pSFunc, C4Object *pObj, const C4Value * C4AulScriptContext ctx; ctx.Obj = pObj; ctx.Def = pDef; + ctx.Section = §ion; ctx.Return = nullptr; ctx.Pars = pPars; ctx.Vars = pVars; @@ -1439,6 +1445,7 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4 C4AulScriptContext ctx; ctx.Obj = pObj; ctx.Def = pDef; + ctx.Section = pCurCtx->Section; ctx.Caller = pCurCtx; ctx.Return = pReturn; ctx.Pars = pPars; @@ -1457,6 +1464,7 @@ C4AulBCC *C4AulExec::Call(C4AulFunc *pFunc, C4Value *pReturn, C4Value *pPars, C4 C4AulContext CallCtx; CallCtx.Obj = pObj; CallCtx.Def = pDef; + CallCtx.Section = pCurCtx->Section; CallCtx.Caller = pCurCtx; #ifdef DEBUGREC_SCRIPT @@ -1592,12 +1600,13 @@ void C4AulProfiler::Show() // done! } -C4Value C4AulFunc::Exec(C4Object *pObj, const C4AulParSet &pPars, bool fPassErrors, bool nonStrict3WarnConversionOnly, bool convertNilToIntBool) +C4Value C4AulFunc::Exec(C4Section §ion, C4Object *pObj, const C4AulParSet &pPars, bool fPassErrors, bool nonStrict3WarnConversionOnly, bool convertNilToIntBool) { // construct a dummy caller context C4AulContext ctx; ctx.Obj = pObj; ctx.Def = pObj ? pObj->Def : nullptr; + ctx.Section = §ion; // FIXME: pobj->Section? ctx.Caller = nullptr; const auto sFunc = SFunc(); @@ -1617,10 +1626,10 @@ C4Value C4AulScriptFunc::Exec(C4AulContext *pCtx, const C4Value pPars[], bool fP if (Owner->State != ASS_PARSED) return C4VNull; // execute - return AulExec.Exec(this, pCtx->Obj, pPars, fPassErrors); + return AulExec.Exec(this, *pCtx->Section, pCtx->Obj, pPars, fPassErrors); } -C4Value C4AulScriptFunc::Exec(C4Object *pObj, const C4AulParSet &pPars, bool fPassErrors, bool nonStrict3WarnConversionOnly, bool convertNilToIntBool) +C4Value C4AulScriptFunc::Exec(C4Section §ion, C4Object *pObj, const C4AulParSet &pPars, bool fPassErrors, bool nonStrict3WarnConversionOnly, bool convertNilToIntBool) { // handle easiest case first if (Owner->State != ASS_PARSED) return C4VNull; @@ -1630,7 +1639,7 @@ C4Value C4AulScriptFunc::Exec(C4Object *pObj, const C4AulParSet &pPars, bool fPa if (TryCheckConvertFunctionParameters(pObj, this, pars.Par, !isAtLeastStrict3, isAtLeastStrict3 && convertNilToIntBool, fPassErrors, nonStrict3WarnConversionOnly && !isAtLeastStrict3)) { // execute - return AulExec.Exec(this, pObj, pars.Par, fPassErrors); + return AulExec.Exec(this, section, pObj, pars.Par, fPassErrors); } return C4VNull; } @@ -1640,7 +1649,7 @@ bool C4AulScriptFunc::HasStrictNil() const noexcept return pOrgScript->Strict >= C4AulScriptStrict::STRICT3; } -C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptStrict Strict) +C4Value C4AulScript::DirectExec(C4Section §ion, C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptStrict Strict) { #ifdef DEBUGREC_SCRIPT AddDbgRec(RCT_DirectExec, szScript, strlen(szScript) + 1); @@ -1685,7 +1694,7 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char pFunc->Code = pScript->Code; pScript->State = ASS_PARSED; // Execute. The TemporaryScript-parameter makes sure the script will be deleted later on. - C4Value vRetVal(AulExec.Exec(pFunc, pObj, nullptr, fPassErrors, true)); + C4Value vRetVal(AulExec.Exec(pFunc, section, pObj, nullptr, fPassErrors, true)); // profiler AulExec.StopDirectExec(); return vRetVal; diff --git a/src/C4Command.cpp b/src/C4Command.cpp index 13a53c69b..a4d560ef9 100644 --- a/src/C4Command.cpp +++ b/src/C4Command.cpp @@ -1938,7 +1938,7 @@ void C4Command::Transfer() { C4AulScriptFunc *f; bool fHandled = (f = Target->Def->Script.SFn_ControlTransfer) != nullptr; - if (fHandled) fHandled = f->Exec(Target, {C4VObj(cObj), Tx, C4VInt(Ty)}).getBool(); + if (fHandled) fHandled = f->Exec(*Target->Section, Target, {C4VObj(cObj), Tx, C4VInt(Ty)}).getBool(); if (!fHandled) // Transfer not handled by target: done @@ -2023,7 +2023,7 @@ void C4Command::Buy() return; } // Base owner has not enough funds: fail - if (Game.Players.Get(Target->Base)->Wealth < pDef->GetValue(Target, cObj->Owner)) + if (Game.Players.Get(Target->Base)->Wealth < pDef->GetValue(*Target->Section, Target, cObj->Owner)) { Finish(false, LoadResStr("IDS_PLR_NOWEALTH")); return; } @@ -2237,7 +2237,7 @@ void C4Command::Fail(const char *szFailMessage) // Message (if not empty) if (!failMessage.empty()) { - Game.Messages.Append(C4GM_Target, failMessage.c_str(), l_Obj, NO_OWNER, 0, 0, FWhite, true); + Game.Messages.Append(C4GM_Target, failMessage.c_str(), l_Obj->Section, l_Obj, NO_OWNER, 0, 0, FWhite, true); } // Fail sound StartSoundEffect("CommandFailure*", false, 100, l_Obj); diff --git a/src/C4Console.cpp b/src/C4Console.cpp index 2d4f177ec..a3a44b3a4 100644 --- a/src/C4Console.cpp +++ b/src/C4Console.cpp @@ -252,7 +252,7 @@ INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPara // Remove player if (Inside((int)LOWORD(wParam), IDM_PLAYER_QUIT1, IDM_PLAYER_QUIT2)) { - Game.Control.Input.Add(CID_EliminatePlayer, new C4ControlEliminatePlayer(LOWORD(wParam) - IDM_PLAYER_QUIT1)); + Game.Control.Input.Add(CID_EliminatePlayer, new C4ControlEliminatePlayer(0, LOWORD(wParam) - IDM_PLAYER_QUIT1)); return TRUE; } // Remove client @@ -608,7 +608,7 @@ bool C4Console::In(const char *szText) // editing enabled? if (!EditCursor.EditingOK()) return false; // pass through network queue - Game.Control.DoInput(CID_Script, new C4ControlScript(szText, C4ControlScript::SCOPE_Console, Config.Developer.ConsoleScriptStrictness), CDT_Decide); + Game.Control.DoInput(CID_Script, new C4ControlScript(0, szText, C4ControlScript::SCOPE_Console, Config.Developer.ConsoleScriptStrictness), CDT_Decide); return true; } diff --git a/src/C4Control.cpp b/src/C4Control.cpp index 0e652ebce..0ae062145 100644 --- a/src/C4Control.cpp +++ b/src/C4Control.cpp @@ -274,6 +274,12 @@ void C4ControlScript::Execute() const } } + C4Section *const section{Game.GetSectionByIndex(sectionIndex)}; + if (!section) + { + return; + } + const char *szScript = Script.getData(); // execute C4Object *pObj = nullptr; @@ -287,7 +293,7 @@ void C4ControlScript::Execute() const else // default: Fallback to global context pScript = &Game.ScriptEngine; - C4Value rVal(pScript->DirectExec(pObj, szScript, "console script", false, Strict)); + C4Value rVal(pScript->DirectExec(*section, pObj, szScript, "console script", false, Strict)); // show messages // print script if (pObj) @@ -311,6 +317,7 @@ void C4ControlScript::Execute() const void C4ControlScript::CompileFunc(StdCompiler *pComp) { + pComp->Value(mkNamingAdapt(mkIntPackAdapt(sectionIndex) , "Section", 0)); pComp->Value(mkNamingAdapt(iTargetObj, "TargetObj", -1)); pComp->Value(mkNamingAdapt(Strict, "Strict", C4AulScriptStrict::MAXSTRICT)); @@ -864,9 +871,9 @@ void C4ControlJoinPlayer::CompileFunc(StdCompiler *pComp) // *** C4ControlEMMoveObject -C4ControlEMMoveObject::C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj, +C4ControlEMMoveObject::C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, const std::int32_t sectionIndex, C4Object *pTargetObj, int32_t iObjectNum, int32_t *pObjects, const char *szScript, const C4AulScriptStrict strict) - : eAction(eAction), tx(tx), ty(ty), iTargetObj(Game.ObjectNumber(pTargetObj)), + : eAction(eAction), tx(tx), ty(ty), sectionIndex{sectionIndex}, iTargetObj(Game.ObjectNumber(pTargetObj)), iObjectNum(iObjectNum), Strict{strict}, pObjects(pObjects), Script(szScript, true) {} C4ControlEMMoveObject::~C4ControlEMMoveObject() @@ -918,7 +925,7 @@ void C4ControlEMMoveObject::Execute() const for (int i = 0; i < iObjectNum; ++i) if (pObj = Game.SafeObjectPointer(pObjects[i])) { - pObj = C4Object::GetSection(pObj).CreateObject(pObj->id, pObj, pObj->Owner, pObj->x, pObj->y); + pObj = pObj->Section->CreateObject(pObj->id, pObj, pObj->Owner, pObj->x, pObj->y); if (pObj && fLocalCall) Console.EditCursor.GetSelection().Add(pObj, C4ObjectList::stNone); } // update status @@ -933,7 +940,7 @@ void C4ControlEMMoveObject::Execute() const { if (!pObjects) return; // execute script ... - C4ControlScript ScriptCtrl(Script.getData(), C4ControlScript::SCOPE_Global, Strict); + C4ControlScript ScriptCtrl(sectionIndex, Script.getData(), C4ControlScript::SCOPE_Global, Strict); ScriptCtrl.SetByClient(iByClient); // ... for each object in selection for (int i = 0; i < iObjectNum; ++i) @@ -974,6 +981,7 @@ void C4ControlEMMoveObject::CompileFunc(StdCompiler *pComp) pComp->Value(mkNamingAdapt(mkIntAdaptT(eAction), "Action")); pComp->Value(mkNamingAdapt(tx, "tx", 0)); pComp->Value(mkNamingAdapt(ty, "ty", 0)); + pComp->Value(mkNamingAdapt(mkIntPackAdapt(sectionIndex), "Section", 0)); pComp->Value(mkNamingAdapt(iTargetObj, "TargetObj", -1)); pComp->Value(mkNamingAdapt(mkIntPackAdapt(iObjectNum), "ObjectNum", 0)); pComp->Value(mkNamingAdapt(Strict, "Strict", C4AulScriptStrict::MAXSTRICT)); @@ -1539,6 +1547,12 @@ void C4ControlInternalScriptBase::Execute() const { if (!Allowed()) return; + C4Section *const section{Game.GetSectionByIndex(sectionIndex)}; + if (!section) + { + return; + } + const auto scope = Scope(); // execute C4Object *pObj = nullptr; @@ -1552,7 +1566,13 @@ void C4ControlInternalScriptBase::Execute() const else // default: Fallback to global context pScript = &Game.ScriptEngine; - pScript->DirectExec(pObj, FormatScript().getData(), "internal script"); + pScript->DirectExec(*section, pObj, FormatScript().getData(), "internal script"); +} + +void C4ControlInternalScriptBase::CompileFunc(StdCompiler *const comp) +{ + comp->Value(mkNamingAdapt(mkIntPackAdapt(sectionIndex), "Section", -1)); + C4ControlPacket::CompileFunc(comp); } void C4ControlInternalPlayerScriptBase::CompileFunc(StdCompiler *pComp) diff --git a/src/C4Control.h b/src/C4Control.h index 343261f8d..480b08617 100644 --- a/src/C4Control.h +++ b/src/C4Control.h @@ -134,10 +134,11 @@ class C4ControlScript : public C4ControlPacket // sync C4ControlScript() : iTargetObj(-1) {} - C4ControlScript(const char *szScript, int32_t iTargetObj = SCOPE_Global, C4AulScriptStrict strict = C4AulScriptStrict::MAXSTRICT) - : iTargetObj(iTargetObj), Strict{strict}, Script(szScript, true) {} + C4ControlScript(const std::int32_t sectionIndex, const char *szScript, int32_t iTargetObj = SCOPE_Global, C4AulScriptStrict strict = C4AulScriptStrict::MAXSTRICT) + : sectionIndex{sectionIndex}, iTargetObj(iTargetObj), Strict{strict}, Script(szScript, true) {} protected: + std::int32_t sectionIndex; int32_t iTargetObj; C4AulScriptStrict Strict; StdStrBuf Script; @@ -345,13 +346,14 @@ class C4ControlEMMoveObject : public C4ControlPacket // sync { public: C4ControlEMMoveObject() : pObjects(nullptr) {} - C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, C4Object *pTargetObj, + C4ControlEMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int32_t ty, std::int32_t sectionIndex, C4Object *pTargetObj, int32_t iObjectNum = 0, int32_t *pObjects = nullptr, const char *szScript = nullptr, C4AulScriptStrict strict = C4AulScriptStrict::MAXSTRICT); ~C4ControlEMMoveObject(); protected: C4ControlEMObjectAction eAction; // action to be performed int32_t tx, ty; // target position + std::int32_t sectionIndex{}; // section index int32_t iTargetObj; // enumerated ptr to target object int32_t iObjectNum; // number of objects moved C4AulScriptStrict Strict; // strictness for the script to execute @@ -498,11 +500,18 @@ class C4ControlVoteEnd : public C4ControlVote class C4ControlInternalScriptBase : public C4ControlPacket { +public: + C4ControlInternalScriptBase() noexcept = default; + C4ControlInternalScriptBase(const std::int32_t sectionIndex) noexcept : sectionIndex(sectionIndex) {} public: virtual int32_t Scope() const { return C4ControlScript::SCOPE_Global; } virtual bool Allowed() const { return true; } virtual StdStrBuf FormatScript() const = 0; - virtual void Execute() const override; + + DECLARE_C4CONTROL_VIRTUALS + +private: + std::int32_t sectionIndex{}; }; class C4ControlEMDropDef : public C4ControlInternalScriptBase @@ -513,7 +522,7 @@ class C4ControlEMDropDef : public C4ControlInternalScriptBase public: C4ControlEMDropDef() {} - C4ControlEMDropDef(C4ID id, int32_t x, int32_t y) : id(id), x(x), y(y) {} + C4ControlEMDropDef(const std::int32_t sectionIndex, C4ID id, int32_t x, int32_t y) : C4ControlInternalScriptBase{sectionIndex}, id(id), x(x), y(y) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual bool Allowed() const override; virtual StdStrBuf FormatScript() const override; @@ -526,7 +535,7 @@ class C4ControlInternalPlayerScriptBase : public C4ControlInternalScriptBase public: C4ControlInternalPlayerScriptBase() {} - C4ControlInternalPlayerScriptBase(int32_t plr) : plr(plr) {} + C4ControlInternalPlayerScriptBase(const std::int32_t sectionIndex, int32_t plr) : C4ControlInternalScriptBase{sectionIndex}, plr(plr) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual bool Allowed() const override; }; @@ -538,7 +547,7 @@ class C4ControlMessageBoardAnswer : public C4ControlInternalPlayerScriptBase public: C4ControlMessageBoardAnswer() {} - C4ControlMessageBoardAnswer(int32_t obj, int32_t plr, const std::string &answer) : obj(obj), answer(answer), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlMessageBoardAnswer(const std::int32_t sectionIndex, int32_t obj, int32_t plr, const std::string &answer) : C4ControlInternalPlayerScriptBase{sectionIndex, plr}, obj(obj), answer(answer) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override; }; @@ -550,7 +559,7 @@ class C4ControlCustomCommand : public C4ControlInternalPlayerScriptBase public: C4ControlCustomCommand() {} - C4ControlCustomCommand(int32_t plr, const std::string &command, const std::string &argument) : command(command), argument(argument), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlCustomCommand(const std::int32_t sectionIndex, int32_t plr, const std::string &command, const std::string &argument) : C4ControlInternalPlayerScriptBase(sectionIndex, plr), command(command), argument(argument) {} virtual bool Allowed() const override; virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override; @@ -562,7 +571,7 @@ class C4ControlInitScenarioPlayer : public C4ControlInternalPlayerScriptBase public: C4ControlInitScenarioPlayer() {} - C4ControlInitScenarioPlayer(int32_t plr, int32_t team) : team(team), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlInitScenarioPlayer(const std::int32_t sectionIndex, int32_t plr, int32_t team) : C4ControlInternalPlayerScriptBase(sectionIndex, plr), team(team) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override { return FormatString("InitScenarioPlayer(%d,%d)", static_cast(plr), static_cast(team)); } }; @@ -571,7 +580,7 @@ class C4ControlActivateGameGoalMenu : public C4ControlInternalPlayerScriptBase { public: C4ControlActivateGameGoalMenu() {} - C4ControlActivateGameGoalMenu(int32_t plr) : C4ControlInternalPlayerScriptBase(plr) {} + C4ControlActivateGameGoalMenu(const std::int32_t sectionIndex, int32_t plr) : C4ControlInternalPlayerScriptBase(sectionIndex, plr) {} virtual StdStrBuf FormatScript() const override { return FormatString("ActivateGameGoalMenu(%d)", plr); } }; @@ -581,7 +590,7 @@ class C4ControlToggleHostility : public C4ControlInternalPlayerScriptBase public: C4ControlToggleHostility() {} - C4ControlToggleHostility(int32_t plr, int32_t opponent) : opponent(opponent), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlToggleHostility(const std::int32_t sectionIndex, int32_t plr, int32_t opponent) : C4ControlInternalPlayerScriptBase(sectionIndex, plr), opponent(opponent) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override { return FormatString("SetHostility(%d,%d,!Hostile(%d,%d,true))", plr, opponent, plr, opponent); } }; @@ -590,7 +599,7 @@ class C4ControlSurrenderPlayer : public C4ControlInternalPlayerScriptBase { public: C4ControlSurrenderPlayer() {} - C4ControlSurrenderPlayer(int32_t plr) : C4ControlInternalPlayerScriptBase(plr) {} + C4ControlSurrenderPlayer(const std::int32_t sectionIndex, int32_t plr) : C4ControlInternalPlayerScriptBase(sectionIndex, plr) {} virtual StdStrBuf FormatScript() const override { return FormatString("SurrenderPlayer(%d)", plr); } }; @@ -600,7 +609,7 @@ class C4ControlActivateGameGoalRule : public C4ControlInternalPlayerScriptBase public: C4ControlActivateGameGoalRule() {} - C4ControlActivateGameGoalRule(int32_t plr, int32_t obj) : obj(obj), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlActivateGameGoalRule(const std::int32_t sectionIndex, int32_t plr, int32_t obj) : C4ControlInternalPlayerScriptBase(sectionIndex, plr), obj(obj) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override { return FormatString("Activate(%d)", plr); } virtual int32_t Scope() const override { return obj; } @@ -612,7 +621,7 @@ class C4ControlSetPlayerTeam : public C4ControlInternalPlayerScriptBase public: C4ControlSetPlayerTeam() {} - C4ControlSetPlayerTeam(int32_t plr, int32_t team) : team(team), C4ControlInternalPlayerScriptBase(plr) {} + C4ControlSetPlayerTeam(const std::int32_t sectionIndex, int32_t plr, int32_t team) : C4ControlInternalPlayerScriptBase(sectionIndex, plr), team(team) {} virtual void CompileFunc(StdCompiler *pComp) override; virtual StdStrBuf FormatScript() const override { return FormatString("SetPlayerTeam(%d,%d)", static_cast(plr), static_cast(team)); } }; @@ -621,7 +630,7 @@ class C4ControlEliminatePlayer : public C4ControlInternalPlayerScriptBase { public: C4ControlEliminatePlayer() {} - C4ControlEliminatePlayer(int32_t plr) : C4ControlInternalPlayerScriptBase(plr) {} + C4ControlEliminatePlayer(const std::int32_t sectionIndex, int32_t plr) : C4ControlInternalPlayerScriptBase(sectionIndex, plr) {} virtual bool Allowed() const override { return HostControl(); } virtual StdStrBuf FormatScript() const override { return FormatString("EliminatePlayer(%d)", plr); } }; diff --git a/src/C4Def.cpp b/src/C4Def.cpp index 9bfa5de84..1d0953ee8 100644 --- a/src/C4Def.cpp +++ b/src/C4Def.cpp @@ -834,14 +834,14 @@ void C4Def::Draw(C4Facet &cgo, bool fSelected, uint32_t iColor, C4Object *pObj, pGfxOvrl->DrawPicture(cgo, pObj); } -int32_t C4Def::GetValue(C4Object *pInBase, int32_t iBuyPlayer) +int32_t C4Def::GetValue(C4Section §ion, C4Object *pInBase, int32_t iBuyPlayer) { // CalcDefValue defined? C4AulFunc *pCalcValueFn = Script.GetSFunc(PSF_CalcDefValue, AA_PROTECTED); int32_t iValue; if (pCalcValueFn) // then call it! - iValue = pCalcValueFn->Exec(nullptr, {C4VObj(pInBase), C4VInt(iBuyPlayer)}).getInt(); + iValue = pCalcValueFn->Exec(section, nullptr, {C4VObj(pInBase), C4VInt(iBuyPlayer)}).getInt(); else // otherwise, use default value iValue = Value; @@ -850,12 +850,12 @@ int32_t C4Def::GetValue(C4Object *pInBase, int32_t iBuyPlayer) { C4AulFunc *pFn; if (pFn = pInBase->Def->Script.GetSFunc(PSF_CalcBuyValue, AA_PROTECTED)) - iValue = pFn->Exec(pInBase, {C4VID(id), C4VInt(iValue)}).getInt(); + iValue = pFn->Exec(*pInBase->Section, pInBase, {C4VID(id), C4VInt(iValue)}).getInt(); } return iValue; } -C4PhysicalInfo *C4Def::GetFairCrewPhysicals() +C4PhysicalInfo *C4Def::GetFairCrewPhysicals(C4Section §ion) { // if fair crew physicals have been created, assume they are valid if (!pFairCrewPhysical) @@ -867,7 +867,7 @@ C4PhysicalInfo *C4Def::GetFairCrewPhysicals() if (pRankNames) pRankSys = pRankNames; int32_t iRank = pRankSys->RankByExperience(iExpGain); // promote physicals for rank - pFairCrewPhysical->PromotionUpdate(iRank, true, this); + pFairCrewPhysical->PromotionUpdate(iRank, true, §ion, this); } return pFairCrewPhysical; } @@ -1261,23 +1261,23 @@ bool C4Def::LoadPortraits(C4Group &hGroup) return true; } -C4ValueArray *C4Def::GetCustomComponents(C4Value *pvArrayHolder, C4Object *pBuilder, C4Object *pObjInstance) +C4ValueArray *C4Def::GetCustomComponents(C4Value *pvArrayHolder, C4Section §ion, C4Object *pBuilder, C4Object *pObjInstance) { // return custom components array if script function is defined and returns an array if (Script.SFn_CustomComponents) { - *pvArrayHolder = Script.SFn_CustomComponents->Exec(pObjInstance, {C4VObj(pBuilder)}); + *pvArrayHolder = Script.SFn_CustomComponents->Exec(section, pObjInstance, {C4VObj(pBuilder)}); return pvArrayHolder->getArray(); } return nullptr; } -int32_t C4Def::GetComponentCount(C4ID idComponent, C4Object *pBuilder) +int32_t C4Def::GetComponentCount(C4ID idComponent, C4Section §ion, C4Object *pBuilder) { // script overload? C4Value vArrayHolder; - C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, pBuilder); + C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, section, pBuilder); if (pArray) { int32_t iCount = 0; @@ -1290,11 +1290,11 @@ int32_t C4Def::GetComponentCount(C4ID idComponent, C4Object *pBuilder) return Component.GetIDCount(idComponent); } -C4ID C4Def::GetIndexedComponent(int32_t idx, C4Object *pBuilder) +C4ID C4Def::GetIndexedComponent(int32_t idx, C4Section §ion, C4Object *pBuilder) { // script overload? C4Value vArrayHolder; - C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, pBuilder); + C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, section, pBuilder); if (pArray) { // assume that components are always returned ordered ([a, a, b], but not [a, b, a]) @@ -1317,13 +1317,13 @@ C4ID C4Def::GetIndexedComponent(int32_t idx, C4Object *pBuilder) return Component.GetID(idx); } -void C4Def::GetComponents(C4IDList *pOutList, C4Object *pObjInstance, C4Object *pBuilder) +void C4Def::GetComponents(C4IDList *pOutList, C4Section §ion, C4Object *pObjInstance, C4Object *pBuilder) { assert(pOutList); assert(!pOutList->GetNumberOfIDs()); // script overload? C4Value vArrayHolder; - C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, pBuilder, pObjInstance); + C4ValueArray *pArray = GetCustomComponents(&vArrayHolder, section, pBuilder, pObjInstance); if (pArray) { // transform array into IDList diff --git a/src/C4Def.h b/src/C4Def.h index 4cbab0726..6d061020b 100644 --- a/src/C4Def.h +++ b/src/C4Def.h @@ -348,8 +348,8 @@ class C4Def : public C4DefCore class C4SoundSystem *pSoundSystem = nullptr); void Draw(C4Facet &cgo, bool fSelected = false, uint32_t iColor = 0, C4Object *pObj = nullptr, int32_t iPhaseX = 0, int32_t iPhaseY = 0); inline C4Facet &GetMainFace(C4DefGraphics *pGraphics, uint32_t dwClr = 0) { MainFace.Surface = pGraphics->GetBitmap(dwClr); return MainFace; } - int32_t GetValue(C4Object *pInBase, int32_t iBuyPlayer); // get value of def; calling script functions if defined - C4PhysicalInfo *GetFairCrewPhysicals(); // get fair crew physicals at current fair crew strength + int32_t GetValue(C4Section §ion, C4Object *pInBase, int32_t iBuyPlayer); // get value of def; calling script functions if defined + C4PhysicalInfo *GetFairCrewPhysicals(C4Section §ion); // get fair crew physicals at current fair crew strength void ClearFairCrewPhysicals(); // remove cached fair crew physicals, will be created fresh on demand void Synchronize(); const char *GetDesc() { return Desc.GetData(); } @@ -361,13 +361,13 @@ class C4Def : public C4DefCore void CrossMapActMap(); private: - C4ValueArray *GetCustomComponents(C4Value *pvArrayHolder, C4Object *pBuilder, C4Object *pObjInstance = nullptr); + C4ValueArray *GetCustomComponents(C4Value *pvArrayHolder, C4Section §ion, C4Object *pBuilder, C4Object *pObjInstance = nullptr); public: // return def components - may be overloaded by script callback - int32_t GetComponentCount(C4ID idComponent, C4Object *pBuilder = nullptr); - C4ID GetIndexedComponent(int32_t idx, C4Object *pBuilder = nullptr); - void GetComponents(C4IDList *pOutList, C4Object *pObjInstance = nullptr, C4Object *pBuilder = nullptr); + int32_t GetComponentCount(C4ID idComponent, C4Section §ion, C4Object *pBuilder = nullptr); + C4ID GetIndexedComponent(int32_t idx, C4Section §ion, C4Object *pBuilder = nullptr); + void GetComponents(C4IDList *pOutList, C4Section §ion, C4Object *pObjInstance = nullptr, C4Object *pBuilder = nullptr); void IncludeDefinition(C4Def *pIncludeDef); // inherit components from other definition void ResetIncludeDependencies(); // resets all pointers into foreign definitions caused by include chains diff --git a/src/C4DefGraphics.cpp b/src/C4DefGraphics.cpp index a2d7a8ed8..4916e42f2 100644 --- a/src/C4DefGraphics.cpp +++ b/src/C4DefGraphics.cpp @@ -392,7 +392,7 @@ void C4DefGraphicsPtrBackup::AssignUpdate(C4DefGraphics *pNewGraphics) // update menu frame decorations - may do multiple updates to the same deco if multiple menus share it... if (C4GUI::FrameDecoration *pDeco = pObj->Menu->GetFrameDecoration(); pDeco && pDeco->idSourceDef == pDef->id) { - if (!pDeco->UpdateGfx()) + if (!pDeco->UpdateGfx(*pObj->Section)) { pObj->Menu->SetFrameDeco(nullptr); } diff --git a/src/C4EditCursor.cpp b/src/C4EditCursor.cpp index a739e4ae8..957818907 100644 --- a/src/C4EditCursor.cpp +++ b/src/C4EditCursor.cpp @@ -737,7 +737,7 @@ void C4EditCursor::EMMoveObject(C4ControlEMObjectAction eAction, int32_t tx, int } // execute control - EMControl(CID_EMMoveObj, new C4ControlEMMoveObject(eAction, tx, ty, pTargetObj, iObjCnt, pObjIDs, szScript, Config.Developer.ConsoleScriptStrictness)); + EMControl(CID_EMMoveObj, new C4ControlEMMoveObject(eAction, tx, ty, Game.GetSectionIndex(*Section), pTargetObj, iObjCnt, pObjIDs, szScript, Config.Developer.ConsoleScriptStrictness)); } void C4EditCursor::EMControl(C4PacketType eCtrlType, C4ControlPacket *pCtrl) diff --git a/src/C4Effect.cpp b/src/C4Effect.cpp index 26ba731e5..e29e6cd16 100644 --- a/src/C4Effect.cpp +++ b/src/C4Effect.cpp @@ -56,9 +56,11 @@ C4AulScript *C4Effect::GetCallbackScript() return pSrcScript; } -C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber, bool passErrors) - : EffectVars(0) +C4Effect::C4Effect(C4Section §ion, C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber, bool passErrors) + : EffectVars(0), section{§ion} { + this->section.Enumerate(); + C4Effect *pPrev, *pCheck; // assign values SCopy(szName, Name, C4MaxDefString); @@ -71,7 +73,7 @@ C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t idCommandTarget = idCmdTarget; AssignCallbackFunctions(); // get effect target - C4Effect **ppEffectList = pForObj ? &pForObj->pEffects : &Game.pGlobalEffects; + C4Effect **ppEffectList = pForObj ? &pForObj->pEffects : §ion.GlobalEffects; // assign a unique number for that object iNumber = 1; for (pCheck = *ppEffectList; pCheck; pCheck = pCheck->pNext) @@ -126,7 +128,7 @@ C4Effect::C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t if (pForObj && !pForObj->Status) return; // this will be invalid! iPriority = iPrio; // validate effect now if (pFnStart) - if (pFnStart->Exec(pCommandTarget, {C4VObj(pForObj), C4VInt(iNumber), C4VInt(0), rVal1, rVal2, rVal3, rVal4}, true, true).getInt() == C4Fx_Start_Deny) + if (pFnStart->Exec(section, pCommandTarget, {C4VObj(pForObj), C4VInt(iNumber), C4VInt(0), rVal1, rVal2, rVal3, rVal4}, true, true).getInt() == C4Fx_Start_Deny) // the effect denied to start: assume it hasn't, and mark it dead SetDead(); if (fRemoveUpper && pNext && pFnStart) @@ -181,6 +183,8 @@ void C4Effect::EnumeratePointers() pEff->pCommandTarget.Enumerate(); // effect var denumeration: not necessary, because this is done while saving } while (pEff = pEff->pNext); + + section.Enumerate(); } void C4Effect::DenumeratePointers() @@ -196,6 +200,8 @@ void C4Effect::DenumeratePointers() // assign any callback functions pEff->AssignCallbackFunctions(); } while (pEff = pEff->pNext); + + section.Denumerate(); } void C4Effect::ClearPointers(C4Object *pObj) @@ -279,7 +285,7 @@ int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iP { if (!pCheck->IsDead() && pCheck->pFnEffect && pCheck->iPriority >= iPrio) { - int32_t iResult = pCheck->pFnEffect->Exec(pCheck->pCommandTarget, {C4VString(szCheckEffect), C4VObj(pForObj), C4VInt(pCheck->iNumber), C4Value(), rVal1, rVal2, rVal3, rVal4}, passErrors, true).getInt(); + int32_t iResult = pCheck->pFnEffect->Exec(**pCheck->section, pCheck->pCommandTarget, {C4VString(szCheckEffect), C4VObj(pForObj), C4VInt(pCheck->iNumber), C4Value(), rVal1, rVal2, rVal3, rVal4}, passErrors, true).getInt(); if (iResult == C4Fx_Effect_Deny) // effect denied return C4Fx_Effect_Deny; @@ -319,7 +325,7 @@ int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect, int32_t iP void C4Effect::Execute(C4Object *pObj) { // get effect list - C4Effect **ppEffectList = pObj ? &pObj->pEffects : &Game.pGlobalEffects; + C4Effect **ppEffectList = pObj ? &pObj->pEffects : §ion->GlobalEffects; // execute all effects not marked as dead C4Effect *pEffect = this, **ppPrevEffect = ppEffectList; do @@ -342,7 +348,7 @@ void C4Effect::Execute(C4Object *pObj) if (pEffect->iIntervall && !(pEffect->iTime % pEffect->iIntervall)) if (pEffect->pFnTimer) { - if (pEffect->pFnTimer->Exec(pEffect->pCommandTarget, {C4VObj(pObj), C4VInt(pEffect->iNumber), C4VInt(pEffect->iTime)}, false, true).getInt() == C4Fx_Execute_Kill) + if (pEffect->pFnTimer->Exec(**pEffect->section, pEffect->pCommandTarget, {C4VObj(pObj), C4VInt(pEffect->iNumber), C4VInt(pEffect->iTime)}, false, true).getInt() == C4Fx_Execute_Kill) { // safety: this class got deleted! if (pObj && !pObj->Status) return; @@ -372,11 +378,11 @@ void C4Effect::Kill(C4Object *pObj) else // otherwise: temp reactivate before real removal // this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call - if (pFnStart && iPriority != 1) pFnStart->Exec(pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(C4FxCall_TempAddForRemoval)}, false, true); + if (pFnStart && iPriority != 1) pFnStart->Exec(**section, pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(C4FxCall_TempAddForRemoval)}, false, true); // remove this effect int32_t iPrevPrio = iPriority; SetDead(); if (pFnStop) - if (pFnStop->Exec(pCommandTarget, {C4VObj(pObj), C4VInt(iNumber)}, false, true).getInt() == C4Fx_Stop_Deny) + if (pFnStop->Exec(**section, pCommandTarget, {C4VObj(pObj), C4VInt(iNumber)}, false, true).getInt() == C4Fx_Stop_Deny) // effect denied to be removed: recover iPriority = iPrevPrio; // reactivate other effects @@ -393,7 +399,7 @@ void C4Effect::ClearAll(C4Object *pObj, int32_t iClearFlag) int32_t iPrevPrio = iPriority; SetDead(); if (pFnStop) - if (pFnStop->Exec(pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(iClearFlag)}, false, true).getInt() == C4Fx_Stop_Deny) + if (pFnStop->Exec(**section, pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(iClearFlag)}, false, true).getInt() == C4Fx_Stop_Deny) { // this stop-callback might have deleted the object and then denied its own removal // must not modify self in this case... @@ -410,7 +416,7 @@ void C4Effect::DoDamage(C4Object *pObj, int32_t &riDamage, int32_t iDamageType, do { if (!pEff->IsDead() && pEff->pFnDamage) - riDamage = pEff->pFnDamage->Exec(pEff->pCommandTarget, {C4VObj(pObj), C4VInt(pEff->iNumber), C4VInt(riDamage), C4VInt(iDamageType), C4VInt(iCausePlr)}, false, true).getInt(); + riDamage = pEff->pFnDamage->Exec(**pEff->section, pEff->pCommandTarget, {C4VObj(pObj), C4VInt(pEff->iNumber), C4VInt(riDamage), C4VInt(iDamageType), C4VInt(iCausePlr)}, false, true).getInt(); if (pObj && !pObj->Status) return; } while ((pEff = pEff->pNext) && riDamage); } @@ -435,7 +441,7 @@ C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, const C4Value &rVal1, // call it C4AulFunc *pFn = pSrcScript->GetFuncRecursive(fn); if (!pFn) return C4Value(); - return pFn->Exec(pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7}, passErrors, true, convertNilToIntBool); + return pFn->Exec(**section, pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7}, passErrors, true, convertNilToIntBool); } void C4Effect::OnObjectChangedDef(C4Object *pObj) @@ -468,7 +474,7 @@ void C4Effect::TempRemoveUpperEffects(C4Object *pObj, bool fTempRemoveThis, C4Ef { FlipActive(); // temp callbacks only for higher priority effects - if (pFnStop && iPriority != 1) pFnStop->Exec(pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(C4FxCall_Temp), C4VBool(true)}, false, true); + if (pFnStop && iPriority != 1) pFnStop->Exec(**section, pCommandTarget, {C4VObj(pObj), C4VInt(iNumber), C4VInt(C4FxCall_Temp), C4VBool(true)}, false, true); if (!*ppLastRemovedEffect) *ppLastRemovedEffect = this; } } @@ -484,7 +490,7 @@ void C4Effect::TempReaddUpperEffects(C4Object *pObj, C4Effect *pLastReaddEffect) if (pEff->IsInactiveAndNotDead()) { pEff->FlipActive(); - if (pEff->pFnStart && pEff->iPriority != 1) pEff->pFnStart->Exec(pEff->pCommandTarget, {C4VObj(pObj), C4VInt(pEff->iNumber), C4VInt(C4FxCall_Temp)}, false, true); + if (pEff->pFnStart && pEff->iPriority != 1) pEff->pFnStart->Exec(**pEff->section, pEff->pCommandTarget, {C4VObj(pObj), C4VInt(pEff->iNumber), C4VInt(C4FxCall_Temp)}, false, true); } // done? if (pEff == pLastReaddEffect) break; @@ -507,6 +513,17 @@ void C4Effect::CompileFunc(StdCompiler *pComp) pComp->Value(pCommandTarget); pComp->Separator(); // read ID pComp->Value(mkC4IDAdapt(idCommandTarget)); + + // read section + if (pComp->Separator()) + { + pComp->Value(section); + } + else + { + assert(pComp->isCompiler()); + } + pComp->Separator(StdCompiler::SEP_END); // ')' // read variables if (pComp->isCompiler() || EffectVars.GetSize() > 0) diff --git a/src/C4Effects.h b/src/C4Effects.h index 6df5771f0..b6a041f03 100644 --- a/src/C4Effects.h +++ b/src/C4Effects.h @@ -25,6 +25,7 @@ #include "C4Aul.h" #include "C4Constants.h" #include "C4EnumeratedObjectPtr.h" +#include "C4Section.h" #include "C4ValueList.h" typedef unsigned long C4ID; @@ -85,6 +86,8 @@ class C4Effect int32_t iTime, iIntervall; // effect time; effect callback intervall int32_t iNumber; // effect number for addressing + C4Section::EnumeratedPtr section; + C4Effect *pNext; // next effect in linked list protected: @@ -97,7 +100,7 @@ class C4Effect void AssignCallbackFunctions(); // resolve callback function names public: - C4Effect(C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber, bool passErrors = false); + C4Effect(C4Section §ion, C4Object *pForObj, const char *szName, int32_t iPrio, int32_t iTimerIntervall, C4Object *pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, bool fDoCalls, int32_t &riStoredAsNumber, bool passErrors = false); C4Effect(StdCompiler *pComp); // ctor: compile ~C4Effect(); // dtor - deletes all following effects diff --git a/src/C4FindObject.cpp b/src/C4FindObject.cpp index 5fac50252..36f041d16 100644 --- a/src/C4FindObject.cpp +++ b/src/C4FindObject.cpp @@ -672,7 +672,7 @@ bool C4FindObjectFunc::Check(C4Object *pObj) C4AulFunc *pCallFunc = pFunc->FindSameNameFunc(pObj->Def); if (!pCallFunc) return false; // Call - return static_cast(pCallFunc->Exec(pObj, Pars, true)); + return static_cast(pCallFunc->Exec(*pObj->Section, pObj, Pars, true)); } bool C4FindObjectFunc::IsImpossible() @@ -919,5 +919,5 @@ int32_t C4SortObjectFunc::CompareGetValue(C4Object *pObj) C4AulFunc *pCallFunc = pFunc->FindSameNameFunc(pObj->Def); if (!pCallFunc) return false; // Call - return pCallFunc->Exec(pObj, Pars, true).getInt(); + return pCallFunc->Exec(*pObj->Section, pObj, Pars, true).getInt(); } diff --git a/src/C4ForwardDeclarations.h b/src/C4ForwardDeclarations.h index 09564a4fe..c74b5c226 100644 --- a/src/C4ForwardDeclarations.h +++ b/src/C4ForwardDeclarations.h @@ -18,6 +18,7 @@ class C4AulFunc; class C4Def; class C4DefList; +class C4Effect; class C4Facet; class C4FacetEx; class C4FacetExSurface; diff --git a/src/C4FullScreen.cpp b/src/C4FullScreen.cpp index dccfea31d..94a3937e7 100644 --- a/src/C4FullScreen.cpp +++ b/src/C4FullScreen.cpp @@ -576,7 +576,7 @@ bool C4FullScreen::ActivateMenuMain() CloseMenu(); // Open menu pMenu = new C4MainMenu(); - return pMenu->ActivateMain(NO_OWNER); + return pMenu->ActivateMain(*Game.Sections.front(), NO_OWNER); // FIXME } void C4FullScreen::CloseMenu() diff --git a/src/C4Game.cpp b/src/C4Game.cpp index 1d42212c8..4e8ee007e 100644 --- a/src/C4Game.cpp +++ b/src/C4Game.cpp @@ -577,7 +577,6 @@ void C4Game::Clear() C4S.Clear(); GraphicsSystem.Clear(); Defs.Clear(); - delete pGlobalEffects; pGlobalEffects = nullptr; Particles.Clear(); GraphicsResource.Clear(); Messages.Clear(); @@ -790,10 +789,6 @@ bool C4Game::Execute() // Returns true if the game is over // Game std::ranges::for_each(Sections, &C4Section::ExecObjects); - - if (pGlobalEffects) - EXEC_S_DR(pGlobalEffects->Execute(nullptr);, GEStats, "GEEx\0"); - std::ranges::for_each(Sections, &C4Section::Execute); EXEC_S_DR(Players.Execute();, PlayersStat, "PlrEx") @@ -873,14 +868,15 @@ void C4Game::ClearPointers(C4Object *pObj) MessageInput.ClearPointers(pObj); Console.ClearPointers(pObj); MouseControl.ClearPointers(pObj); - - if (pGlobalEffects) - pGlobalEffects->ClearPointers(pObj); } void C4Game::UpdateScriptPointers() { - std::ranges::for_each(Sections, &C4ObjectList::UpdateScriptPointers, &C4Section::Objects); + for (const auto §ion : Sections) + { + section->Objects.UpdateScriptPointers(*section); + } + UpdateMaterialScriptPointers(); } @@ -989,7 +985,7 @@ C4ID DefFileGetID(const char *szFilename) return DefCore.id; } -bool C4Game::DropFile(const char *szFilename, int32_t iX, int32_t iY) +bool C4Game::DropFile(C4Section §ion, const char *szFilename, int32_t iX, int32_t iY) { C4ID c_id; C4Def *cdef; // Drop def to create object @@ -1001,7 +997,7 @@ bool C4Game::DropFile(const char *szFilename, int32_t iX, int32_t iY) if ((cdef = Game.Defs.ID2Def(c_id)) || (Defs.Load(szFilename, C4D_Load_RX, Config.General.LanguageEx, &*Application.SoundSystem) && (cdef = Game.Defs.ID2Def(c_id)))) { - return DropDef(c_id, iX, iY); + return DropDef(section, c_id, iX, iY); } // Failure Console.Out(FormatString(LoadResStr("IDS_CNS_DROPNODEF"), GetFilename(szFilename)).getData()); @@ -1010,12 +1006,12 @@ bool C4Game::DropFile(const char *szFilename, int32_t iX, int32_t iY) return false; } -bool C4Game::DropDef(C4ID id, int32_t iX, int32_t iY) +bool C4Game::DropDef(C4Section §ion, C4ID id, int32_t iX, int32_t iY) { // def exists? if (Game.Defs.ID2Def(id)) { - Control.DoInput(CID_EMDropDef, new C4ControlEMDropDef(id, iX, iY), CDT_Decide); + Control.DoInput(CID_EMDropDef, new C4ControlEMDropDef(GetSectionIndex(section), id, iX, iY), CDT_Decide); return true; } else @@ -1096,7 +1092,6 @@ void C4Game::Default() pGUI = nullptr; pScenarioSections = pCurrentScenarioSection = nullptr; *CurrentScenarioSection = 0; - pGlobalEffects = nullptr; fResortAnyObject = false; pNetworkStatistics = nullptr; IsMusicEnabled = false; @@ -1250,7 +1245,7 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp) pComp->Value(mkNamingAdapt(Sections[0]->Landscape.Sky, "Sky")); } - pComp->Value(mkNamingAdapt(mkNamingPtrAdapt(pGlobalEffects, "GlobalEffects"), "Effects")); + pComp->Value(mkNamingAdapt(mkNamingPtrAdapt(Sections[0]->GlobalEffects, "GlobalEffects"), "Effects")); // scoreboard compiles into main level [Scoreboard] if (!comp.fScenarioSection && comp.fExact) @@ -1334,7 +1329,7 @@ bool C4Game::SaveData(C4Group &hGroup, bool fSaveSection, bool fInitial, bool fS { Players.EnumeratePointers(); ScriptEngine.Strings.EnumStrings(); - if (pGlobalEffects) pGlobalEffects->EnumeratePointers(); + std::ranges::for_each(Sections, &C4Section::EnumeratePointers); } // Decompile @@ -1347,7 +1342,7 @@ bool C4Game::SaveData(C4Group &hGroup, bool fSaveSection, bool fInitial, bool fS { ScriptEngine.DenumerateVariablePointers(); Players.DenumeratePointers(); - if (pGlobalEffects) pGlobalEffects->DenumeratePointers(); + std::ranges::for_each(Sections, &C4Section::DenumeratePointers); } // Initial? @@ -1758,7 +1753,7 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSky) // Denumerate game data pointers ScriptEngine.DenumerateVariablePointers(); - if (pGlobalEffects) pGlobalEffects->DenumeratePointers(); + std::ranges::for_each(Sections, &C4Section::DenumeratePointers); // Check object enumeration if (!std::ranges::all_of(Sections, &C4Section::CheckObjectEnumeration)) @@ -1915,7 +1910,7 @@ bool C4Game::InitGameFinal() } // Script constructor call - if (!C4S.Head.SaveGame) Script.Call(PSF_Initialize); + if (!C4S.Head.SaveGame) Script.Call(*Sections.front(), PSF_Initialize); // FIXME if (std::ranges::any_of(Sections, [objectCount](C4GameObjects &objects) { return objects.ObjectCount() != objectCount; }, &C4Section::Objects)) { fScriptCreatedObjects = true; diff --git a/src/C4Game.h b/src/C4Game.h index a794985b1..cba173944 100644 --- a/src/C4Game.h +++ b/src/C4Game.h @@ -120,7 +120,6 @@ class C4Game C4Extra Extra; C4GUI::Screen *pGUI; C4ScenarioSection *pScenarioSections, *pCurrentScenarioSection; - C4Effect *pGlobalEffects; #ifndef USE_CONSOLE // We don't need fonts when we don't have graphics C4FontLoader FontLoader; @@ -211,9 +210,9 @@ class C4Game void Synchronize(bool fSavePlayerFiles); void SyncClearance(); // Editing - bool DropFile(const char *szFilename, int32_t iX, int32_t iY); + bool DropFile(C4Section §ion, const char *szFilename, int32_t iX, int32_t iY); bool CreateViewport(int32_t iPlayer, bool fSilent = false); - bool DropDef(C4ID id, int32_t iX, int32_t iY); + bool DropDef(C4Section §ion, C4ID id, int32_t iX, int32_t iY); void ReloadFile(const char *path); bool ReloadDef(C4ID id, uint32_t reloadWhat = C4D_Load_RX); bool ReloadParticle(const char *szName); @@ -295,6 +294,17 @@ class C4Game std::ranges::for_each(Sections, &C4ObjectList::SortByCategory, &C4Section::Objects); } + void OnObjectChangedDef(C4Object *const obj) + { + for (const auto §ion : Sections) + { + if (section->GlobalEffects) + { + section->GlobalEffects->OnObjectChangedDef(obj); + } + } + } + bool LoadScenarioSection(const char *szSection, uint32_t dwFlags); bool DrawTextSpecImage(C4FacetExSurface &fctTarget, const char *szSpec, uint32_t dwClr = 0xff); diff --git a/src/C4GameMessage.cpp b/src/C4GameMessage.cpp index f4e9a1f70..dad1a3c4e 100644 --- a/src/C4GameMessage.cpp +++ b/src/C4GameMessage.cpp @@ -35,12 +35,13 @@ C4GameMessage::~C4GameMessage() delete pFrameDeco; } -void C4GameMessage::Init(int32_t iType, const StdStrBuf &sText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int width) +void C4GameMessage::Init(int32_t iType, const StdStrBuf &sText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int width) { // safety! if (pTarget && !pTarget->Status) pTarget = nullptr; // Set data Text.Copy(sText); + Section = section; Target = pTarget; X = iX; Y = iY; Wdt = width; Player = iPlayer; @@ -62,7 +63,7 @@ void C4GameMessage::Init(int32_t iType, const StdStrBuf &sText, C4Object *pTarge if (DecoID) { pFrameDeco = new C4GUI::FrameDecoration(); - if (!pFrameDeco->SetByDef(DecoID)) + if (!pFrameDeco->SetByDef(*Section, DecoID)) { delete pFrameDeco; pFrameDeco = nullptr; @@ -95,7 +96,7 @@ int32_t DrawMessageOffset = -35; // For finding the optimum place to draw startu int32_t PortraitWidth = 64; int32_t PortraitIndent = 10; -void C4GameMessage::Draw(C4FacetEx &cgo, int32_t iPlayer, C4Section &viewSection) +void C4GameMessage::Draw(C4FacetEx &cgo, int32_t iPlayer) { int32_t alignment = dwFlags & C4GM_ALeft ? ALeft : dwFlags & C4GM_ACenter ? ACenter : dwFlags & C4GM_ARight ? ARight : 0; @@ -176,7 +177,7 @@ void C4GameMessage::Draw(C4FacetEx &cgo, int32_t iPlayer, C4Section &viewSection } } // Positioned - else if ((Type == C4GM_Target || ((Type == C4GM_TargetPlayer) && (iPlayer == Player))) && (Target->Section == &viewSection)) + else if ((Type == C4GM_Target || ((Type == C4GM_TargetPlayer) && (iPlayer == Player)))) { // adjust position by object; care about parallaxity int32_t iMsgX, iMsgY; @@ -234,7 +235,7 @@ void C4GameMessage::UpdateDef(C4ID idUpdDef) // frame deco might be using updated/deleted def if (pFrameDeco) { - if (!pFrameDeco->UpdateGfx()) + if (!pFrameDeco->UpdateGfx(*Section)) { delete pFrameDeco; pFrameDeco = nullptr; @@ -273,21 +274,23 @@ void C4GameMessageList::Execute() }), Messages.end()); } -bool C4GameMessageList::New(int32_t iType, const char *szText, +bool C4GameMessageList::New(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol) { - return New(iType, StdStrBuf::MakeRef(szText), pTarget, iPlayer, iX, iY, 0xff000000 | Application.DDraw->Pal.GetClr(FColors[bCol])); + return New(iType, StdStrBuf::MakeRef(szText), section, pTarget, iPlayer, iX, iY, 0xff000000 | Application.DDraw->Pal.GetClr(FColors[bCol])); } -bool C4GameMessageList::New(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int32_t width) +bool C4GameMessageList::New(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int32_t width) { - return New(iType, StdStrBuf::MakeRef(szText), pTarget, iPlayer, iX, iY, dwClr, idDecoID, szPortraitDef, dwFlags, width); + return New(iType, StdStrBuf::MakeRef(szText), section, pTarget, iPlayer, iX, iY, dwClr, idDecoID, szPortraitDef, dwFlags, width); } -bool C4GameMessageList::New(int32_t iType, const StdStrBuf &sText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int32_t width) +bool C4GameMessageList::New(int32_t iType, const StdStrBuf &sText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int32_t width) { + if (iType != C4GM_Global && !section) return false; + if (!(dwFlags & C4GM_Multiple)) { // Clear messages with same target @@ -304,26 +307,27 @@ bool C4GameMessageList::New(int32_t iType, const StdStrBuf &sText, C4Object *pTa if (!sText.getLength()) return true; // Add new message - C4GameMessage *msgNew = new C4GameMessage; - msgNew->Init(iType, sText, pTarget, iPlayer, iX, iY, dwClr, idDecoID, szPortraitDef, dwFlags, width); + C4GameMessage *msgNew = new C4GameMessage(); + msgNew->Init(iType, sText, section, pTarget, iPlayer, iX, iY, dwClr, idDecoID, szPortraitDef, dwFlags, width); Messages.emplace_back(msgNew); return true; } -bool C4GameMessageList::Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol, bool fNoDuplicates) +bool C4GameMessageList::Append(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol, bool fNoDuplicates) { - if (const auto &msg = std::find_if(Messages.begin(), Messages.end(), [iType, pTarget, iPlayer](const auto &msg) + if (const auto &msg = std::find_if(Messages.begin(), Messages.end(), [section, iType, pTarget, iPlayer](const auto &msg) { - return (iType == C4GM_Target && msg->Target == pTarget) - || ((iType == C4GM_Global || iType == C4GM_GlobalPlayer) && msg->Player == iPlayer); + return msg->Section == section + && ((iType == C4GM_Target && msg->Target == pTarget) + || ((iType == C4GM_Global || iType == C4GM_GlobalPlayer) && msg->Player == iPlayer)); }); msg != Messages.end() && (*msg)->Target == pTarget) { (*msg)->Append(szText, fNoDuplicates); } else { - New(iType, szText, pTarget, iPlayer, iX, iY, bCol); + New(iType, szText, section, pTarget, iPlayer, iX, iY, bCol); } return true; } @@ -348,6 +352,9 @@ void C4GameMessageList::Draw(C4FacetEx &cgo, int32_t iPlayer, C4Section &viewSec { for (const auto &it : Messages) { - it->Draw(cgo, iPlayer, viewSection); + if (!it->Section || it->Section == &viewSection) + { + it->Draw(cgo, iPlayer); + } } } diff --git a/src/C4GameMessage.h b/src/C4GameMessage.h index 2318b3944..1943a71c9 100644 --- a/src/C4GameMessage.h +++ b/src/C4GameMessage.h @@ -56,7 +56,7 @@ class C4GameMessage friend class C4GameMessageList; public: - void Draw(C4FacetEx &cgo, int32_t iPlayer, C4Section &viewSection); + void Draw(C4FacetEx &cgo, int32_t iPlayer); C4GameMessage(); ~C4GameMessage(); @@ -66,6 +66,7 @@ class C4GameMessage uint32_t ColorDw; int32_t Player; int32_t Type; + C4Section *Section{nullptr}; C4Object *Target; StdStrBuf Text; C4ID DecoID; StdStrBuf PortraitDef; @@ -73,7 +74,7 @@ class C4GameMessage uint32_t dwFlags; protected: - void Init(int32_t iType, const StdStrBuf &Text, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwCol, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int width); + void Init(int32_t iType, const StdStrBuf &Text, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwCol, C4ID idDecoID, const char *szPortraitDef, uint32_t dwFlags, int width); void Append(const char *szText, bool fNoDuplicates = false); bool Execute(); void UpdateDef(C4ID idUpdDef); @@ -98,10 +99,10 @@ class C4GameMessageList void ClearPlayers(int32_t iPlayer, int32_t dwPositioningFlags); void ClearPointers(C4Object *pObj); void UpdateDef(C4ID idUpdDef); // called after reloaddef - bool New(int32_t iType, const StdStrBuf &Text, C4Object *pTarget, int32_t iPlayer, int32_t iX = -1, int32_t iY = -1, uint32_t dwClr = 0xffFFFFFF, C4ID idDecoID = C4ID_None, const char *szPortraitDef = nullptr, uint32_t dwFlags = 0u, int32_t width = 0); - bool New(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol); - bool New(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID = C4ID_None, const char *szPortraitDef = nullptr, uint32_t dwFlags = 0u, int32_t width = 0); - bool Append(int32_t iType, const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol, bool fNoDuplicates = false); + bool New(int32_t iType, const StdStrBuf &Text, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX = -1, int32_t iY = -1, uint32_t dwClr = 0xffFFFFFF, C4ID idDecoID = C4ID_None, const char *szPortraitDef = nullptr, uint32_t dwFlags = 0u, int32_t width = 0); + bool New(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol); + bool New(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint32_t dwClr, C4ID idDecoID = C4ID_None, const char *szPortraitDef = nullptr, uint32_t dwFlags = 0u, int32_t width = 0); + bool Append(int32_t iType, const char *szText, C4Section *section, C4Object *pTarget, int32_t iPlayer, int32_t iX, int32_t iY, uint8_t bCol, bool fNoDuplicates = false); }; void GameMsgObject(const char *szText, C4Object *pTarget, int32_t iFCol = FWhite); diff --git a/src/C4GameObjects.cpp b/src/C4GameObjects.cpp index 339ce2f69..882da0882 100644 --- a/src/C4GameObjects.cpp +++ b/src/C4GameObjects.cpp @@ -430,7 +430,7 @@ void C4ObjResort::SortObject() if (!(pObj2->Category & pSortObj->Category)) break; // perform the check Pars[0].Set(C4VObj(pObj2)); - iResult = OrderFunc->Exec(nullptr, Pars).getInt(); + iResult = OrderFunc->Exec(*pObj2->Section, nullptr, Pars).getInt(); if (iResult > 0) break; if (iResult < 0) pMoveLink = pLnk; } @@ -458,7 +458,7 @@ void C4ObjResort::SortObject() if (!(pObj2->Category & pSortObj->Category)) break; // perform the check Pars[1].Set(C4VObj(pObj2)); - iResult = OrderFunc->Exec(nullptr, Pars).getInt(); + iResult = OrderFunc->Exec(*pObj2->Section, nullptr, Pars).getInt(); if (iResult > 0) break; if (iResult < 0) pMoveLink = pLnk; } @@ -503,7 +503,7 @@ void C4ObjResort::Sort(C4ObjectLink *pFirst, C4ObjectLink *pLast) while (!pCurr2->Obj->Status) pCurr2 = pCurr2->Prev; // perform the check Pars[0].Set(C4VObj(pCurr->Obj)); Pars[1].Set(C4VObj(pCurr2->Obj)); - if (OrderFunc->Exec(nullptr, Pars).getInt() < 0) + if (OrderFunc->Exec(*pCurr->Obj->Section, nullptr, Pars).getInt() < 0) { // so there's something to be reordered: swap the links // FIXME: Inform C4ObjectList about this reorder @@ -725,13 +725,13 @@ bool C4GameObjects::Save(C4Section §ion, const char *szFilename, bool fSaveG return Buffer.SaveToFile(szFilename); } -void C4GameObjects::UpdateScriptPointers() +void C4GameObjects::UpdateScriptPointers(C4Section §ion) { // call in sublists C4ObjectList::UpdateScriptPointers(); InactiveObjects.UpdateScriptPointers(); // adjust global effects - if (Game.pGlobalEffects) Game.pGlobalEffects->ReAssignAllCallbackFunctions(); + if (section.GlobalEffects) section.GlobalEffects->ReAssignAllCallbackFunctions(); } void C4GameObjects::UpdatePos(C4Object *pObj) diff --git a/src/C4GameObjects.h b/src/C4GameObjects.h index 6a35830f5..822afd0b5 100644 --- a/src/C4GameObjects.h +++ b/src/C4GameObjects.h @@ -68,7 +68,7 @@ class C4GameObjects : public C4NotifyingObjectList bool Save(C4Section §ion, const char *szFilename, bool fSaveGame, bool fSaveInactive); bool Save(C4Section §ion, C4Group &hGroup, bool fSaveGame, bool fSaveInactive); - void UpdateScriptPointers(); // update pointers to C4AulScript * + void UpdateScriptPointers(C4Section §ion); // update pointers to C4AulScript * void UpdatePos(C4Object *pObj); void UpdatePosResort(C4Object *pObj); diff --git a/src/C4Gui.h b/src/C4Gui.h index 996965ecf..fda572310 100644 --- a/src/C4Gui.h +++ b/src/C4Gui.h @@ -1534,8 +1534,8 @@ class FrameDecoration void Clear(); // zero data // create from ActMap and graphics of a definition (does some script callbacks to get parameters) - bool SetByDef(C4ID idSourceDef); - bool UpdateGfx(); // update Surface, e.g. after def reload + bool SetByDef(C4Section §ion, C4ID idSourceDef); + bool UpdateGfx(C4Section §ion); // update Surface, e.g. after def reload void Ref() { ++iRefCount; } void Deref() { if (!--iRefCount) delete this; } diff --git a/src/C4GuiDialogs.cpp b/src/C4GuiDialogs.cpp index d2326ec56..0105ba62f 100644 --- a/src/C4GuiDialogs.cpp +++ b/src/C4GuiDialogs.cpp @@ -106,7 +106,7 @@ bool FrameDecoration::SetFacetByAction(C4Def *pOfDef, C4FacetEx &rfctTarget, con return true; } -bool FrameDecoration::SetByDef(C4ID idSourceDef) +bool FrameDecoration::SetByDef(C4Section §ion, C4ID idSourceDef) { // get source def C4Def *pSrcDef = Game.Defs.ID2Def(idSourceDef); @@ -117,11 +117,11 @@ bool FrameDecoration::SetByDef(C4ID idSourceDef) Clear(); this->idSourceDef = idSourceDef; // query values - dwBackClr = pSrcDef->Script.Call(FormatString(PSF_FrameDecoration, "BackClr").getData()).getInt(); - iBorderTop = pSrcDef->Script.Call(FormatString(PSF_FrameDecoration, "BorderTop").getData()).getInt(); - iBorderLeft = pSrcDef->Script.Call(FormatString(PSF_FrameDecoration, "BorderLeft").getData()).getInt(); - iBorderRight = pSrcDef->Script.Call(FormatString(PSF_FrameDecoration, "BorderRight").getData()).getInt(); - iBorderBottom = pSrcDef->Script.Call(FormatString(PSF_FrameDecoration, "BorderBottom").getData()).getInt(); + dwBackClr = pSrcDef->Script.Call(section, FormatString(PSF_FrameDecoration, "BackClr").getData()).getInt(); + iBorderTop = pSrcDef->Script.Call(section, FormatString(PSF_FrameDecoration, "BorderTop").getData()).getInt(); + iBorderLeft = pSrcDef->Script.Call(section, FormatString(PSF_FrameDecoration, "BorderLeft").getData()).getInt(); + iBorderRight = pSrcDef->Script.Call(section, FormatString(PSF_FrameDecoration, "BorderRight").getData()).getInt(); + iBorderBottom = pSrcDef->Script.Call(section, FormatString(PSF_FrameDecoration, "BorderBottom").getData()).getInt(); // get gfx SetFacetByAction(pSrcDef, fctTop, "Top"); SetFacetByAction(pSrcDef, fctTopRight, "TopRight"); @@ -140,10 +140,10 @@ bool FrameDecoration::SetByDef(C4ID idSourceDef) return true; } -bool FrameDecoration::UpdateGfx() +bool FrameDecoration::UpdateGfx(C4Section §ion) { // simply re-set by def - return SetByDef(idSourceDef); + return SetByDef(section, idSourceDef); } void FrameDecoration::Draw(C4FacetEx &cgo, C4Rect &rcBounds) diff --git a/src/C4InfoCore.cpp b/src/C4InfoCore.cpp index a3b13f989..758b6ba82 100644 --- a/src/C4InfoCore.cpp +++ b/src/C4InfoCore.cpp @@ -199,7 +199,7 @@ struct C4PhysInfoNameMap_t { const char *szName; C4PhysicalInfo::Offset off; } C { nullptr, nullptr } }; -void C4PhysicalInfo::PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysicals, C4Def *pTrainDef) +void C4PhysicalInfo::PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysicals, C4Section *section, C4Def *pTrainDef) { if (iRank >= 0) { CanDig = 1; CanChop = 1; CanConstruct = 1; } if (iRank >= 0) { CanScale = 1; } @@ -218,7 +218,7 @@ void C4PhysicalInfo::PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysica for (int32_t iPhysIdx = 0; szPhysName = GetNameByIndex(iPhysIdx, &PhysOff); ++iPhysIdx) { C4Value PhysVal(this->*PhysOff, C4V_Int); - if (pTrainDef->Script.Call(PSF_GetFairCrewPhysical, {C4VString(szPhysName), C4VInt(iRank), C4VRef(&PhysVal)})) + if (pTrainDef->Script.Call(*section, PSF_GetFairCrewPhysical, {C4VString(szPhysName), C4VInt(iRank), C4VRef(&PhysVal)})) { this->*PhysOff = PhysVal.getInt(); } diff --git a/src/C4InfoCore.h b/src/C4InfoCore.h index f31fb2c9c..3b766df0e 100644 --- a/src/C4InfoCore.h +++ b/src/C4InfoCore.h @@ -63,7 +63,7 @@ class C4PhysicalInfo public: void Default(); - void PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysicals = false, class C4Def *pTrainDef = nullptr); + void PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysicals = false, C4Section *section = nullptr, class C4Def *pTrainDef = nullptr); void CompileFunc(StdCompiler *pComp); // conversion of physical names to member pointers and vice versa diff --git a/src/C4Landscape.cpp b/src/C4Landscape.cpp index bc6c56309..3a17f2443 100644 --- a/src/C4Landscape.cpp +++ b/src/C4Landscape.cpp @@ -572,7 +572,7 @@ CSurface8 *C4Landscape::CreateMapS2(C4Group &ScenFile) // create map creator if (!pMapCreator) - pMapCreator = new C4MapCreatorS2(&Section.C4S.Landscape, &Section.TextureMap, &Section.Material, Game.Parameters.StartupPlayerCount); + pMapCreator = new C4MapCreatorS2(Section, &Section.C4S.Landscape, &Section.TextureMap, &Section.Material, Game.Parameters.StartupPlayerCount); // read file pMapCreator->ReadFile(C4CFN_DynLandscape, &ScenFile); @@ -2700,7 +2700,7 @@ bool C4Landscape::DrawMap(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, co FakeLS.MapWdt.Set(iMapWdt, 0, iMapWdt, iMapWdt); FakeLS.MapHgt.Set(iMapHgt, 0, iMapHgt, iMapHgt); // create map creator - C4MapCreatorS2 MapCreator(&FakeLS, &Section.TextureMap, &Section.Material, Game.Parameters.StartupPlayerCount); + C4MapCreatorS2 MapCreator(Section, &FakeLS, &Section.TextureMap, &Section.Material, Game.Parameters.StartupPlayerCount); // read file MapCreator.ReadScript(szMapDef); // render map diff --git a/src/C4MainMenu.cpp b/src/C4MainMenu.cpp index eabe95684..d70c9bb63 100644 --- a/src/C4MainMenu.cpp +++ b/src/C4MainMenu.cpp @@ -40,16 +40,16 @@ void C4MainMenu::Default() Player = NO_OWNER; } -bool C4MainMenu::Init(C4FacetExSurface &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) +bool C4MainMenu::Init(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) { - if (!DoInit(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; + if (!DoInit(fctSymbol, section, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; Player = iPlayer; return true; } -bool C4MainMenu::InitRefSym(const C4FacetEx &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) +bool C4MainMenu::InitRefSym(const C4FacetEx &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) { - if (!DoInitRefSym(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; + if (!DoInitRefSym(fctSymbol, section, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; Player = iPlayer; return true; } @@ -66,7 +66,7 @@ bool C4MainMenu::ActivateNewPlayer(int32_t iPlayer) // Menu symbol/init if (GfxR->fctPlayerClr.Surface) GfxR->fctPlayerClr.Surface->SetClr(0xff); - InitRefSym(GfxR->fctPlayerClr, LoadResStr("IDS_MENU_NOPLRFILES"), iPlayer); + InitRefSym(GfxR->fctPlayerClr, *section, LoadResStr("IDS_MENU_NOPLRFILES"), iPlayer); for (DirectoryIterator iter(Config.General.PlayerPath); *iter; ++iter) if (WildcardMatch("*.c4p", *iter)) { @@ -328,7 +328,7 @@ void C4MainMenu::OnClosed(bool ok) C4Menu::OnClosed(ok); } -bool C4MainMenu::ActivateGoals(int32_t iPlayer, bool fDoActivate) +bool C4MainMenu::ActivateGoals(C4Section §ion, int32_t iPlayer, bool fDoActivate) { const auto symbolSize = GetSymbolSize(); @@ -338,7 +338,7 @@ bool C4MainMenu::ActivateGoals(int32_t iPlayer, bool fDoActivate) if (fDoActivate) { // Menu symbol/init - InitRefSym(GfxR->fctMenu.GetPhase(4), LoadResStr("IDS_MENU_CPGOALS"), iPlayer); + InitRefSym(GfxR->fctMenu.GetPhase(4), section, LoadResStr("IDS_MENU_CPGOALS"), iPlayer); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); const auto scale = Application.GetScale(); const auto starWidth = Game.GraphicsResource.fctCaptain.Wdt * scale; @@ -386,7 +386,7 @@ bool C4MainMenu::ActivateRules(int32_t iPlayer) // Menu symbol/init char Command[256]; C4FacetExSurface fctSymbol; - InitRefSym(GfxR->fctMenu.GetPhase(5), LoadResStr("IDS_MENU_CPRULES"), iPlayer); + InitRefSym(GfxR->fctMenu.GetPhase(5), *section, LoadResStr("IDS_MENU_CPRULES"), iPlayer); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(false); // Items @@ -432,7 +432,7 @@ bool C4MainMenu::ActivateSavegame(int32_t iPlayer) char DirPath[_MAX_PATH + 1]; char ScenName[_MAX_PATH + 1]; *ScenName = 0; - InitRefSym(GfxR->fctMenu.GetPhase(0), LoadResStr("IDS_MENU_CPSAVEGAME"), iPlayer); + InitRefSym(GfxR->fctMenu.GetPhase(0), *section, LoadResStr("IDS_MENU_CPSAVEGAME"), iPlayer); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(true); @@ -507,7 +507,7 @@ bool C4MainMenu::ActivateSavegame(int32_t iPlayer) bool C4MainMenu::ActivateHost(int32_t iPlayer) { // Menu symbol/init - InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTCLIENT"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), *section, LoadResStr("IDS_MENU_DISCONNECTCLIENT"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(true); // Clients @@ -531,7 +531,7 @@ bool C4MainMenu::ActivateClient(int32_t iPlayer) // Menu symbol/init C4FacetExSurface fctSymbol; - InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTFROMSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), *section, LoadResStr("IDS_MENU_DISCONNECTFROMSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); fctSymbol.Create(symbolSize, symbolSize); GfxR->fctOKCancel.Draw(fctSymbol, true, 3, 0); Add(LoadResStr("IDS_BTN_YES"), fctSymbol, "Part"); @@ -546,7 +546,7 @@ bool C4MainMenu::ActivateSurrender(int32_t iPlayer) const auto symbolSize = GetSymbolSize(); C4FacetExSurface fctSymbol; - InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), LoadResStr("IDS_MENU_SURRENDER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), *section, LoadResStr("IDS_MENU_SURRENDER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); fctSymbol.Create(symbolSize, symbolSize); GfxR->fctOKCancel.Draw(fctSymbol, true, 3, 0); Add(LoadResStr("IDS_BTN_YES"), fctSymbol, "Surrender"); @@ -559,7 +559,7 @@ bool C4MainMenu::ActivateSurrender(int32_t iPlayer) bool C4MainMenu::ActivateOptions(int32_t iPlayer, int32_t selection) { // Menu symbol/init - InitRefSym(GfxR->fctOptions.GetPhase(0), LoadResStr("IDS_MNU_OPTIONS"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + InitRefSym(GfxR->fctOptions.GetPhase(0), *section, LoadResStr("IDS_MNU_OPTIONS"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(true); // Sound @@ -588,7 +588,7 @@ bool C4MainMenu::ActivateOptions(int32_t iPlayer, int32_t selection) bool C4MainMenu::ActivateDisplay(int32_t iPlayer, int32_t selection) { // Menu symbol/init - InitRefSym(GfxR->fctMenu.GetPhase(8), LoadResStr("IDS_MENU_DISPLAY"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + InitRefSym(GfxR->fctMenu.GetPhase(8), *section, LoadResStr("IDS_MENU_DISPLAY"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(true); // Crew player names @@ -638,7 +638,7 @@ bool C4MainMenu::ActivateDisplay(int32_t iPlayer, int32_t selection) return true; } -bool C4MainMenu::ActivateMain(int32_t iPlayer) +bool C4MainMenu::ActivateMain(C4Section §ion, int32_t iPlayer) { const auto symbolSize = GetSymbolSize(); @@ -648,7 +648,7 @@ bool C4MainMenu::ActivateMain(int32_t iPlayer) C4FacetExSurface fctSymbol; fctSymbol.Create(symbolSize, symbolSize); GfxR->fctOKCancel.Draw(fctSymbol, true, 1, 1); - Init(fctSymbol, LoadResStr(pPlr ? "IDS_MENU_CPMAIN" : "IDS_MENU_OBSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); + Init(fctSymbol, section, LoadResStr(pPlr ? "IDS_MENU_CPMAIN" : "IDS_MENU_OBSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); // Goals+Rules (player menu only) // Goal menu can't be shown because of script callbacks @@ -720,7 +720,7 @@ bool C4MainMenu::ActivateHostility(int32_t iPlayer) C4FacetExSurface fctSymbol; fctSymbol.Create(symbolSize, symbolSize); GfxR->fctMenu.GetPhase(7).Draw(fctSymbol); - Init(fctSymbol, LoadResStr("IDS_MENU_CPATTACK"), iPlayer, C4MN_Extra_None, 0, C4MN_Hostility); + Init(fctSymbol, *section, LoadResStr("IDS_MENU_CPATTACK"), iPlayer, C4MN_Extra_None, 0, C4MN_Hostility); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetPermanent(true); Refill(); @@ -737,12 +737,12 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) if (SEqual2(szCommand, "ActivateMenu:")) { if (C4GameOverDlg::IsShown()) return false; // no new menus during game over dlg - if (SEqual(szCommand + 13, "Main")) return ActivateMain(Player); + if (SEqual(szCommand + 13, "Main")) return ActivateMain(*section, Player); if (SEqual(szCommand + 13, "Hostility")) return ActivateHostility(Player); if (SEqual(szCommand + 13, "NewPlayer")) return ActivateNewPlayer(Player); if (SEqual(szCommand + 13, "Goals")) { - Game.Control.DoInput(CID_ActivateGameGoalMenu, new C4ControlActivateGameGoalMenu(Player), CDT_Queue); + Game.Control.DoInput(CID_ActivateGameGoalMenu, new C4ControlActivateGameGoalMenu(Game.GetSectionIndex(*section), Player), CDT_Queue); return true; } if (SEqual(szCommand + 13, "Rules")) return ActivateRules(Player); @@ -751,7 +751,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) if (SEqual(szCommand + 13, "Options")) return ActivateOptions(Player); if (SEqual(szCommand + 13, "Display")) return ActivateDisplay(Player); if (SEqual(szCommand + 13, "Save:Game")) return ActivateSavegame(Player); - if (SEqual(szCommand + 13, "TeamSel")) return pPlr ? pPlr->ActivateMenuTeamSelection(true) : false; + if (SEqual(szCommand + 13, "TeamSel")) return pPlr ? pPlr->ActivateMenuTeamSelection(*section, true) : false; if (SEqual(szCommand + 13, "Surrender")) return ActivateSurrender(Player); if (SEqual(szCommand + 13, "Observer")) return ActivateObserver(); } @@ -776,7 +776,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) int32_t iOpponent; sscanf(szCommand + 13, "%i", &iOpponent); C4Player *pOpponent = Game.Players.Get(iOpponent); if (!pOpponent || pOpponent->GetType() != C4PT_User) return false; - Game.Input.Add(CID_ToggleHostility, new C4ControlToggleHostility(Player, iOpponent)); + Game.Input.Add(CID_ToggleHostility, new C4ControlToggleHostility(Game.GetSectionIndex(*section), Player, iOpponent)); return true; } // Abort @@ -788,7 +788,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) // Surrender if (SEqual2(szCommand, "Surrender")) { - Game.Control.DoInput(CID_SurrenderPlayer, new C4ControlSurrenderPlayer(Player), CDT_Queue); + Game.Control.DoInput(CID_SurrenderPlayer, new C4ControlSurrenderPlayer(Game.GetSectionIndex(*section), Player), CDT_Queue); return true; } // Save game @@ -888,7 +888,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) // TODO! C4Object *pObj; C4ID idItem = C4Id(szCommand + 12); if (pObj = Game.FindFirstInAllObjects([idItem](C4GameObjects &objects) { return objects.FindInternal(idItem); })) - Game.Control.DoInput(CID_ActivateGameGoalRule, new C4ControlActivateGameGoalRule(Player, pObj->Number), CDT_Queue); + Game.Control.DoInput(CID_ActivateGameGoalRule, new C4ControlActivateGameGoalRule(Game.GetSectionIndex(*pObj->Section), Player, pObj->Number), CDT_Queue); else return false; return true; @@ -900,7 +900,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) int32_t idTeam = atoi(szCommand + 8); // OK, join this team - if (pPlr) pPlr->DoTeamSelection(idTeam); + if (pPlr) pPlr->DoTeamSelection(*section, idTeam); return true; } // Team switch @@ -912,7 +912,7 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) // check if it's still allowed if (!Game.Teams.IsTeamSwitchAllowed()) return false; // OK, join this team - Game.Control.DoInput(CID_SetPlayerTeam, new C4ControlSetPlayerTeam(Player, idTeam), CDT_Queue); + Game.Control.DoInput(CID_SetPlayerTeam, new C4ControlSetPlayerTeam(Game.GetSectionIndex(*section), Player, idTeam), CDT_Queue); return true; } // Observe @@ -948,9 +948,10 @@ bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) bool C4MainMenu::ActivateObserver() { // Safety: Viewport lost? - if (!Game.GraphicsSystem.GetViewport(NO_OWNER)) return false; + C4Viewport *const viewport{Game.GraphicsSystem.GetViewport(NO_OWNER)}; + if (!viewport) return false; // Menu symbol/init - InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), LoadResStr("IDS_TEXT_VIEW"), NO_OWNER, C4MN_Extra_None, 0, C4MN_Observer, C4MN_Style_Context); + InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), viewport->GetViewSection(), LoadResStr("IDS_TEXT_VIEW"), NO_OWNER, C4MN_Extra_None, 0, C4MN_Observer, C4MN_Style_Context); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); // Players added in Refill Refill(); diff --git a/src/C4MainMenu.h b/src/C4MainMenu.h index 35696fa62..e0044d530 100644 --- a/src/C4MainMenu.h +++ b/src/C4MainMenu.h @@ -42,13 +42,13 @@ class C4MainMenu : public C4Menu int32_t Player; public: - bool Init(C4FacetExSurface &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); - bool InitRefSym(const C4FacetEx &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); + bool Init(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iPlayer, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); + bool InitRefSym(const C4FacetEx &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iPlayer, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); - bool ActivateMain(int32_t iPlayer); + bool ActivateMain(C4Section §ion, int32_t iPlayer); bool ActivateNewPlayer(int32_t iPlayer); bool ActivateHostility(int32_t iPlayer); - bool ActivateGoals(int32_t iPlayer, bool fDoActivate); + bool ActivateGoals(C4Section §ion, int32_t iPlayer, bool fDoActivate); bool ActivateRules(int32_t iPlayer); bool ActivateSavegame(int32_t iPlayer); bool ActivateHost(int32_t iPlayer); diff --git a/src/C4MapCreatorS2.cpp b/src/C4MapCreatorS2.cpp index 4067aa1c3..99a659300 100644 --- a/src/C4MapCreatorS2.cpp +++ b/src/C4MapCreatorS2.cpp @@ -70,7 +70,7 @@ void C4MCCallbackArray::EnablePixel(int32_t iX, int32_t iY) // done } -void C4MCCallbackArray::Execute(int32_t iMapZoom) +void C4MCCallbackArray::Execute(C4Section §ion, int32_t iMapZoom) { // safety if (!pSF || !pMap) return; @@ -85,7 +85,7 @@ void C4MCCallbackArray::Execute(int32_t iMapZoom) Pars[0] = C4VInt((iIndex % iWdt) * iMapZoom - (iMapZoom / 2)); Pars[1] = C4VInt((iIndex / iWdt) * iMapZoom - (iMapZoom / 2)); // call - pSF->Exec(nullptr, Pars); + pSF->Exec(section, nullptr, Pars); } // done } @@ -117,11 +117,11 @@ void C4MCCallbackArrayList::Clear() pFirst = nullptr; } -void C4MCCallbackArrayList::Execute(int32_t iMapZoom) +void C4MCCallbackArrayList::Execute(C4Section §ion, int32_t iMapZoom) { // execute all arrays for (C4MCCallbackArray *pArray = pFirst; pArray; pArray = pArray->pNext) - pArray->Execute(iMapZoom); + pArray->Execute(section, iMapZoom); } // C4MCNode @@ -679,7 +679,8 @@ void C4MCMap::SetSize(int32_t iWdt, int32_t iHgt) // map creator -C4MapCreatorS2::C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount) : C4MCNode(nullptr) +C4MapCreatorS2::C4MapCreatorS2(C4Section §ion, C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount) + : C4MCNode(nullptr), section{section} { // me r b creator MapCreator = this; @@ -1447,7 +1448,7 @@ bool AlgoScript(C4MCOverlay *pOvrl, int32_t iX, int32_t iY) // catch error (damn insecure C4Aul) try { - return static_cast(pFunc->Exec(nullptr, Pars)); + return static_cast(pFunc->Exec(pOvrl->Owner->MapCreator->GetSection(), nullptr, Pars)); } catch (const C4AulError &) { diff --git a/src/C4MapCreatorS2.h b/src/C4MapCreatorS2.h index b59f13606..52c595067 100644 --- a/src/C4MapCreatorS2.h +++ b/src/C4MapCreatorS2.h @@ -123,7 +123,7 @@ class C4MCCallbackArray public: void EnablePixel(int32_t iX, int32_t iY); // enable pixel in map; create map if necessary - void Execute(int32_t iMapZoom); // evaluate the array + void Execute(C4Section §ion, int32_t iMapZoom); // evaluate the array friend class C4MCCallbackArrayList; }; @@ -141,7 +141,7 @@ class C4MCCallbackArrayList public: void Add(C4MCCallbackArray *pNewArray); // add given array to list void Clear(); // clear the list - void Execute(int32_t iMapZoom); // execute all arrays + void Execute(C4Section §ion, int32_t iMapZoom); // execute all arrays }; // generic map creator tree node @@ -348,7 +348,7 @@ class C4MCMap : public C4MCOverlay class C4MapCreatorS2 : public C4MCNode { public: - C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount); + C4MapCreatorS2(C4Section §ion, C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount); ~C4MapCreatorS2(); void Default(); // set default data @@ -361,8 +361,10 @@ class C4MapCreatorS2 : public C4MCNode public: CSurface8 *Render(const char *szMapName); // create map surface + C4Section &GetSection() const noexcept { return section; } protected: + C4Section §ion; C4SLandscape *Landscape; // landsape presets C4TextureMap *TexMap; // texture map C4MaterialMap *MatMap; // material map @@ -376,7 +378,7 @@ class C4MapCreatorS2 : public C4MCNode bool GlobalScope() override { return true; } // it's the global node public: - void ExecuteCallbacks(int32_t iMapZoom) { CallbackArrays.Execute(iMapZoom); } + void ExecuteCallbacks(int32_t iMapZoom) { CallbackArrays.Execute(section, iMapZoom); } friend class C4MCOverlay; friend class C4MCMap; diff --git a/src/C4Material.cpp b/src/C4Material.cpp index 4d744b340..cbdbb6525 100644 --- a/src/C4Material.cpp +++ b/src/C4Material.cpp @@ -807,7 +807,7 @@ bool C4MaterialMap::mrfScript(C4MaterialReaction *pReaction, C4Section §ion, int32_t iXDir1, iYDir1, iXDir2, iYDir2; auto parX = C4VInt(iX), parY = C4VInt(iY), parXDir = C4VInt(iXDir1 = fixtoi(fXDir, 100)), parYDir = C4VInt(iYDir1 = fixtoi(fYDir, 100)), parPxsMat = C4VInt(iPxsMat); const C4AulParSet pars{parX.GetRef(), parY.GetRef(), C4VInt(iLSPosX), C4VInt(iLSPosY), parXDir.GetRef(), parYDir.GetRef(), parPxsMat.GetRef(), C4VInt(iLsMat), C4VInt(evEvent)}; - if (pReaction->pScriptFunc->Exec(nullptr, pars, false)) + if (pReaction->pScriptFunc->Exec(section, nullptr, pars, false)) { // PXS shall be killed! return true; diff --git a/src/C4Menu.cpp b/src/C4Menu.cpp index 822eedc94..373172592 100644 --- a/src/C4Menu.cpp +++ b/src/C4Menu.cpp @@ -93,7 +93,7 @@ C4MenuItem::C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption, if (idID) { C4Def *pDef = Game.Defs.ID2Def(idID); - if (pDef) pDef->GetComponents(&Components, nullptr, pMenu ? pMenu->GetParentObject() : nullptr); + if (pDef) pDef->GetComponents(&Components, *pMenu->section, nullptr, pMenu ? pMenu->GetParentObject() : nullptr); } } @@ -300,6 +300,7 @@ void C4Menu::Default() fEqualIconItemHeight = false; CloseCommand.Clear(); fActive = false; + section = nullptr; } void C4Menu::Clear() @@ -308,6 +309,7 @@ void C4Menu::Clear() Symbol.Clear(); ClearItems(); ClearFrameDeco(); + section = nullptr; fActive = false; } @@ -331,17 +333,19 @@ bool C4Menu::TryClose(bool fOK, bool fControl) return true; } -bool C4Menu::DoInit(C4FacetExSurface &fctSymbol, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) +bool C4Menu::DoInit(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) { Clear(); Default(); Symbol.GrabFrom(fctSymbol); + this->section = §ion; return InitMenu(szEmpty, iExtra, iExtraData, iId, iStyle); } -bool C4Menu::DoInitRefSym(const C4FacetEx &fctSymbol, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) +bool C4Menu::DoInitRefSym(const C4FacetEx &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) { Clear(); Default(); Symbol.Set(fctSymbol); + this->section = §ion; return InitMenu(szEmpty, iExtra, iExtraData, iId, iStyle); } @@ -834,7 +838,7 @@ void C4Menu::DrawElement(C4FacetEx &cgo) if (pItem && pItem->fOwnValue) iValue = pItem->iValue; else - iValue = pDef->GetValue(nullptr, NO_OWNER); + iValue = pDef->GetValue(*section, nullptr, NO_OWNER); } C4Facet cgoExtra(cgo.Surface, cgo.TargetX + rcBounds.x + 1, cgo.TargetY + rcBounds.y + rcBounds.Hgt - C4MN_SymbolSize - 1, rcBounds.Wdt - 2, C4MN_SymbolSize); diff --git a/src/C4Menu.h b/src/C4Menu.h index 7d31b908f..15cf6aa73 100644 --- a/src/C4Menu.h +++ b/src/C4Menu.h @@ -143,6 +143,7 @@ class C4Menu : public C4GUI::Dialog virtual void Default(); protected: + C4Section *section{nullptr}; bool LocationSet; bool Permanent; bool NeedRefill; @@ -218,8 +219,8 @@ class C4Menu : public C4GUI::Dialog bool InitMenu(const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle); protected: - bool DoInitRefSym(const C4FacetEx &fctSymbol, const char *szEmpty, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); - bool DoInit(C4FacetExSurface &fctSymbol, const char *szEmpty, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); + bool DoInitRefSym(const C4FacetEx &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); + bool DoInit(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal); void AdjustSelection(); void AdjustPosition(); bool RefillInternal(); diff --git a/src/C4MessageInput.cpp b/src/C4MessageInput.cpp index 91bda3909..3180a820a 100644 --- a/src/C4MessageInput.cpp +++ b/src/C4MessageInput.cpp @@ -109,7 +109,7 @@ void C4ChatInputDialog::OnChatCancel() { // there was an associated query - it must be removed on all clients synchronized via queue // do this by calling OnMessageBoardAnswer without an answer - Game.Control.DoInput(CID_MessageBoardAnswer, new C4ControlMessageBoardAnswer(pTarget ? pTarget->Number : 0, iPlr, ""), CDT_Decide); + Game.Control.DoInput(CID_MessageBoardAnswer, new C4ControlMessageBoardAnswer(Game.GetSectionIndex(pTarget ? *pTarget->Section : **pPlr->ViewSection), pTarget ? pTarget->Number : 0, iPlr, ""), CDT_Decide); } } } @@ -149,7 +149,7 @@ C4GUI::InputResult C4ChatInputDialog::OnChatInput(C4GUI::Edit *pEdt, bool fPasti } // then do a script callback, incorporating the input into the answer if (fUppercase) SCapitalize(szInputText); - Game.Control.DoInput(CID_MessageBoardAnswer, new C4ControlMessageBoardAnswer(pTarget ? pTarget->Number : 0, iPlr, szInputText), CDT_Decide); + Game.Control.DoInput(CID_MessageBoardAnswer, new C4ControlMessageBoardAnswer(Game.GetSectionIndex(pTarget ? *pTarget->Section : **pPlr->ViewSection), pTarget ? pTarget->Number : 0, iPlr, szInputText), CDT_Decide); return C4GUI::IR_CloseDlg; } else @@ -469,7 +469,9 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) if (!Game.DebugMode) return false; if (Game.Network.isEnabled() && !Game.Network.isHost()) return false; - Game.Control.DoInput(CID_Script, new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console, Config.Developer.ConsoleScriptStrictness), CDT_Decide); + const auto *const localPlr = Game.Players.GetLocalByIndex(0); + + Game.Control.DoInput(CID_Script, new C4ControlScript(localPlr ? Game.GetSectionIndex(**localPlr->ViewSection) : 0, pCmdPar, C4ControlScript::SCOPE_Console, Config.Developer.ConsoleScriptStrictness), CDT_Decide); return true; } // set runtimte properties @@ -704,7 +706,7 @@ bool C4MessageInput::ProcessCommand(const char *szCommand) const auto *const pLocalPlr = Game.Players.GetLocalByIndex(0); const std::int32_t localPlr = pLocalPlr ? pLocalPlr->Number : NO_OWNER; // add custom command call - Game.Control.DoInput(CID_CustomCommand, new C4ControlCustomCommand(localPlr, szCmdName, pCmdPar), CDT_Decide); + Game.Control.DoInput(CID_CustomCommand, new C4ControlCustomCommand(pLocalPlr ? Game.GetSectionIndex(**pLocalPlr->ViewSection) : 0, localPlr, szCmdName, pCmdPar), CDT_Decide); // ok return true; } diff --git a/src/C4Object.cpp b/src/C4Object.cpp index c70160a19..55689e00b 100644 --- a/src/C4Object.cpp +++ b/src/C4Object.cpp @@ -74,11 +74,6 @@ C4Object::C4Object() Default(); } -C4Section &C4Object::GetSection(C4Object *const obj) noexcept -{ - return obj ? *obj->Section : *Game.Sections.front(); -} - void C4Object::Default() { id = C4ID_None; @@ -879,9 +874,9 @@ bool C4Object::ExecLife() C4AulFunc *pMagicEnergyFn = Game.ScriptEngine.GetFuncRecursive(PSF_DoMagicEnergy); if (pMagicEnergyFn) // should always be true { - if (pMagicEnergyFn->Exec(nullptr, {C4VInt(-transfer), C4VObj(Contained)})) + if (pMagicEnergyFn->Exec(*Section, nullptr, {C4VInt(-transfer), C4VObj(Contained)})) { - pMagicEnergyFn->Exec(nullptr, {C4VInt(+transfer), C4VObj(this)}); + pMagicEnergyFn->Exec(*Section, nullptr, {C4VInt(+transfer), C4VObj(this)}); } } } @@ -1098,7 +1093,7 @@ void C4Object::Execute() { Timer = 0; // TimerCall - if (Def->TimerCall) Def->TimerCall->Exec(this); + if (Def->TimerCall) Def->TimerCall->Exec(*Section, this); } // Menu if (Menu) Menu->Execute(); @@ -1230,7 +1225,7 @@ bool C4Object::ChangeDef(C4ID idNew) SetOCF(); // Any effect callbacks to this object might need to reinitialize their target functions // This is ugly, because every effect there is must be updated... - if (Game.pGlobalEffects) Game.pGlobalEffects->OnObjectChangedDef(this); + Game.OnObjectChangedDef(this); for (C4Object *const obj : Game.GetAllObjects()) { @@ -1251,7 +1246,7 @@ bool C4Object::Incinerate(int32_t iCausedBy, bool fBlasted, C4Object *pIncinerat // add effect int32_t iEffNumber; C4Value Par1 = C4VInt(iCausedBy), Par2 = C4VBool(!!fBlasted), Par3 = C4VObj(pIncineratingObject), Par4; - new C4Effect(this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, nullptr, 0, Par1, Par2, Par3, Par4, true, iEffNumber); + new C4Effect(*Section, this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, nullptr, 0, Par1, Par2, Par3, Par4, true, iEffNumber); return !!iEffNumber; } @@ -1683,7 +1678,7 @@ bool C4Object::Build(int32_t iLevel, C4Object *pBuilder) { // Determine needed components (may be overloaded) C4IDList NeededComponents; - Def->GetComponents(&NeededComponents, nullptr, pBuilder); + Def->GetComponents(&NeededComponents, *Section, nullptr, pBuilder); // Grab any needed components from builder C4ID idMat; @@ -1729,7 +1724,7 @@ bool C4Object::Build(int32_t iLevel, C4Object *pBuilder) // ...tell builder to acquire the material pBuilder->AddCommand(C4CMD_Acquire, nullptr, 0, 0, 50, nullptr, true, NeededMaterial, false, 1); // ...game message if not overloaded - Game.Messages.New(C4GM_Target, GetNeededMatStr(pBuilder), pBuilder, pBuilder->Controller); + Game.Messages.New(C4GM_Target, GetNeededMatStr(pBuilder), pBuilder->Section, pBuilder, pBuilder->Controller); } // Still in need: done/fail return false; @@ -1897,7 +1892,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, pTarget->Def->Draw(fctSymbol, false, pTarget->Color, pTarget); sprintf(szCaption, LoadResStr("IDS_OBJ_EMPTY"), pTarget->GetName()); // Init - Menu->Init(fctSymbol, szCaption, this, C4MN_Extra_None, 0, iMenu); + Menu->Init(fctSymbol, *Section, szCaption, this, C4MN_Extra_None, 0, iMenu); Menu->SetPermanent(true); Menu->SetRefillObject(pTarget); // Success @@ -1910,7 +1905,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, fctSymbol.Create(C4SymbolSize, C4SymbolSize); DrawMenuSymbol(C4MN_Buy, fctSymbol, pTarget->Owner, pTarget); // Init menu - Menu->Init(fctSymbol, LoadResStr("IDS_PLR_NOBUY"), this, C4MN_Extra_Value, 0, iMenu); + Menu->Init(fctSymbol, *Section, LoadResStr("IDS_PLR_NOBUY"), this, C4MN_Extra_Value, 0, iMenu); Menu->SetPermanent(true); Menu->SetRefillObject(pTarget); // Success @@ -1923,7 +1918,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, fctSymbol.Create(C4SymbolSize, C4SymbolSize); DrawMenuSymbol(C4MN_Sell, fctSymbol, pTarget->Owner, pTarget); sprintf(szCaption, LoadResStr("IDS_OBJ_EMPTY"), pTarget->GetName()); - Menu->Init(fctSymbol, szCaption, this, C4MN_Extra_Value, 0, iMenu); + Menu->Init(fctSymbol, *Section, szCaption, this, C4MN_Extra_Value, 0, iMenu); Menu->SetPermanent(true); Menu->SetRefillObject(pTarget); // Success @@ -1939,7 +1934,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, fctSymbol.Create(C4SymbolSize, C4SymbolSize); pTarget->Def->Draw(fctSymbol, false, pTarget->Color, pTarget); sprintf(szCaption, LoadResStr("IDS_OBJ_EMPTY"), pTarget->GetName()); - Menu->Init(fctSymbol, szCaption, this, C4MN_Extra_None, 0, iMenu); + Menu->Init(fctSymbol, *Section, szCaption, this, C4MN_Extra_None, 0, iMenu); Menu->SetPermanent(true); Menu->SetRefillObject(pTarget); // Success @@ -1954,7 +1949,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, pPlayer = Game.Players.Get(pTarget->Owner); fctSymbol.Create(C4SymbolSize, C4SymbolSize); pTarget->Def->Draw(fctSymbol, false, pTarget->Color, pTarget); - Menu->Init(fctSymbol, pTarget->GetName(), this, C4MN_Extra_None, 0, iMenu, C4MN_Style_Context); + Menu->Init(fctSymbol, *Section, pTarget->GetName(), this, C4MN_Extra_None, 0, iMenu, C4MN_Style_Context); Menu->SetPermanent(iMenuData); Menu->SetRefillObject(pTarget); @@ -1973,7 +1968,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, fctSymbol.Create(C4SymbolSize, C4SymbolSize); DrawMenuSymbol(C4MN_Construction, fctSymbol, -1, nullptr); // Init menu - Menu->Init(fctSymbol, FormatString(LoadResStr("IDS_PLR_NOBKNOW"), pPlayer->GetName()).getData(), this, C4MN_Extra_Components, 0, iMenu); + Menu->Init(fctSymbol, *Section, FormatString(LoadResStr("IDS_PLR_NOBKNOW"), pPlayer->GetName()).getData(), this, C4MN_Extra_Components, 0, iMenu); // Add player's structure build knowledge for (cnt = 0; pDef = Game.Defs.ID2Def(pPlayer->Knowledge.GetID(Game.Defs, C4D_Structure, cnt, &iCount)); cnt++) { @@ -1998,7 +1993,7 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect, pPlayer = Game.Players.Get(pTarget->Owner); // Create symbol & init menu fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol, true, 0, 1); - Menu->Init(fctSymbol, pTarget->GetName(), this, C4MN_Extra_None, 0, iMenu, C4MN_Style_Info); + Menu->Init(fctSymbol, *Section, pTarget->GetName(), this, C4MN_Extra_None, 0, iMenu, C4MN_Style_Info); Menu->SetPermanent(true); Menu->SetAlignment(C4MN_Align_Free); C4Viewport *pViewport = Game.GraphicsSystem.GetViewport(Owner); // Hackhackhack!!! @@ -2108,13 +2103,13 @@ int32_t C4Object::GetValue(C4Object *pInBase, int32_t iForPlayer) // value by script? if (C4AulScriptFunc *f = Def->Script.SFn_CalcValue) - iValue = f->Exec(this, {C4VObj(pInBase), C4VInt(iForPlayer)}).getInt(); + iValue = f->Exec(*Section, this, {C4VObj(pInBase), C4VInt(iForPlayer)}).getInt(); else { // get value of def // Caution: Do not pass pInBase here, because the def base value is to be queried // - and not the value if you had to buy the object in this particular base - iValue = Def->GetValue(nullptr, iForPlayer); + iValue = Def->GetValue(*Section, nullptr, iForPlayer); } // Con percentage iValue = iValue * Con / FullCon; @@ -2123,7 +2118,7 @@ int32_t C4Object::GetValue(C4Object *pInBase, int32_t iForPlayer) { C4AulFunc *pFn; if (pFn = pInBase->Def->Script.GetSFunc(PSF_CalcSellValue, AA_PROTECTED)) - iValue = pFn->Exec(pInBase, {C4VObj(this), C4VInt(iValue)}).getInt(); + iValue = pFn->Exec(*pInBase->Section, pInBase, {C4VObj(this), C4VInt(iValue)}).getInt(); } // Return value return iValue; @@ -2138,11 +2133,11 @@ C4PhysicalInfo *C4Object::GetPhysical(bool fPermanent) if (!Game.Parameters.UseFairCrew) return &(Info->Physical); else if (Info->pDef) - return Info->pDef->GetFairCrewPhysicals(); + return Info->pDef->GetFairCrewPhysicals(*Section); else // shouldn't really happen, but who knows. // Maybe some time it will be possible to have crew infos that aren't tied to a specific definition - return Def->GetFairCrewPhysicals(); + return Def->GetFairCrewPhysicals(*Section); // Definition physical return &(Def->Physical); } @@ -2896,7 +2891,7 @@ void C4Object::PostCompileInit() // if on fire but no effect is present (old-style savegames), re-incinerate int32_t iFireNumber; C4Value Par1, Par2, Par3, Par4; - if (OnFire && !pEffects) new C4Effect(this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, nullptr, 0, Par1, Par2, Par3, Par4, false, iFireNumber); + if (OnFire && !pEffects) new C4Effect(*Section, this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, nullptr, 0, Par1, Par2, Par3, Par4, false, iFireNumber); // blit mode not assigned? use definition default then if (!BlitMode) BlitMode = Def->BlitMode; @@ -3269,7 +3264,7 @@ bool C4Object::ContainedControl(uint8_t byCom) C4Player *pPlr = Game.Players.Get(Controller); if (fCallSfEarly) { - if (sf && sf->Exec(Contained, {C4VObj(this)})) result = true; + if (sf && sf->Exec(*Contained->Section, Contained, {C4VObj(this)})) result = true; // AutoStopControl: Also notify container about controlupdate // Note Contained may be nulled now due to ContainedControl call if (Contained && !(byCom & (COM_Single | COM_Double)) && pPlr->ControlStyle) @@ -3313,7 +3308,7 @@ bool C4Object::ContainedControl(uint8_t byCom) // Call container script if defined for old versions if (!fCallSfEarly) { - if (sf) sf->Exec(Contained, {C4VObj(this)}); + if (sf) sf->Exec(*Contained->Section, Contained, {C4VObj(this)}); if (Contained && !(byCom & (COM_Single | COM_Double)) && pPlr->ControlStyle) { int32_t PressedComs = pPlr->PressedComs; @@ -3775,7 +3770,7 @@ bool C4Object::MenuCommand(const char *szCommand) { // Native script execution if (!Def || !Status) return false; - return static_cast(Def->Script.DirectExec(this, szCommand, "MenuCommand", false, Def->Script.Strict)); + return static_cast(Def->Script.DirectExec(*Section, this, szCommand, "MenuCommand", false, Def->Script.Strict)); } C4Object *C4Object::ComposeContents(C4ID id) @@ -3790,7 +3785,7 @@ C4Object *C4Object::ComposeContents(C4ID id) C4Def *pDef = Game.Defs.ID2Def(id); if (!pDef) return nullptr; // get needed contents C4IDList NeededComponents; - pDef->GetComponents(&NeededComponents, nullptr, this); + pDef->GetComponents(&NeededComponents, *Section, nullptr, this); // Check for sufficient components StdStrBuf Needs; Needs.Format(LoadResStr("IDS_CON_BUILDMATNEED"), pDef->GetName()); for (cnt = 0; c_id = NeededComponents.GetID(cnt); cnt++) @@ -4195,7 +4190,7 @@ bool C4Object::SetAction(int32_t iAct, C4Object *pTarget, C4Object *pTarget2, in if (pAction->StartCall) { C4Def *pOldDef = Def; - pAction->StartCall->Exec(this); + pAction->StartCall->Exec(*Section, this); // abort exeution if def changed if (Def != pOldDef || !Status) return true; } @@ -4209,7 +4204,7 @@ bool C4Object::SetAction(int32_t iAct, C4Object *pTarget, C4Object *pTarget2, in if (pAction->EndCall) { C4Def *pOldDef = Def; - pAction->EndCall->Exec(this); + pAction->EndCall->Exec(*Section, this); // abort exeution if def changed if (Def != pOldDef || !Status) return true; } @@ -4223,7 +4218,7 @@ bool C4Object::SetAction(int32_t iAct, C4Object *pTarget, C4Object *pTarget2, in if (pAction->AbortCall) { C4Def *pOldDef = Def; - pAction->AbortCall->Exec(this, {C4VInt(iLastPhase)}); + pAction->AbortCall->Exec(*Section, this, {C4VInt(iLastPhase)}); // abort exeution if def changed if (Def != pOldDef || !Status) return true; } @@ -5493,7 +5488,7 @@ void C4Object::ExecAction() // Phase call if (pAction->PhaseCall) { - pAction->PhaseCall->Exec(this); + pAction->PhaseCall->Exec(*Section, this); } // Phase end if (Action.Phase >= pAction->Length) @@ -5877,7 +5872,7 @@ bool C4Object::PutAwayUnusedObject(C4Object *pToMakeRoomForObject) C4Object *pUnusedObject; C4AulFunc *pFnObj2Drop; if (pFnObj2Drop = Def->Script.GetSFunc(PSF_GetObject2Drop)) - pUnusedObject = pFnObj2Drop->Exec(this, pToMakeRoomForObject ? C4AulParSet{C4VObj(pToMakeRoomForObject)} : C4AulParSet{}).getObj(); + pUnusedObject = pFnObj2Drop->Exec(*Section, this, pToMakeRoomForObject ? C4AulParSet{C4VObj(pToMakeRoomForObject)} : C4AulParSet{}).getObj(); else { // is there any unused object to put away? @@ -6262,7 +6257,7 @@ StdStrBuf C4Object::GetNeededMatStr(C4Object *pBuilder) StdStrBuf NeededMats; C4IDList NeededComponents; - Def->GetComponents(&NeededComponents, nullptr, pBuilder); + Def->GetComponents(&NeededComponents, *Section, nullptr, pBuilder); C4ID idComponent; diff --git a/src/C4Object.h b/src/C4Object.h index 43592d396..7e10e4b02 100644 --- a/src/C4Object.h +++ b/src/C4Object.h @@ -218,8 +218,6 @@ class C4Object int32_t Audible, AudiblePan; // NoSave // public: - static C4Section &GetSection(C4Object *const obj) noexcept; - void Resort(); void DigOutMaterialCast(bool fRequest); void AddMaterialContents(int32_t iMaterial, int32_t iAmount); diff --git a/src/C4ObjectCom.cpp b/src/C4ObjectCom.cpp index 323053e83..5f4b01787 100644 --- a/src/C4ObjectCom.cpp +++ b/src/C4ObjectCom.cpp @@ -1003,7 +1003,7 @@ bool Buy2Base(int32_t iPlr, C4Object *pBase, C4ID id, bool fShowErrors) GameMsgPlayer(FormatString(LoadResStr("IDS_PLR_HOSTILE"), Game.Players.Get(pBase->Base)->GetName()).getData(), iPlr); return false; } // buy - if (!(pThing = Game.Players.Get(pBase->Base)->Buy(id, fShowErrors, iPlr, pBase))) return false; + if (!(pThing = Game.Players.Get(pBase->Base)->Buy(id, fShowErrors, iPlr, *pBase->Section, pBase))) return false; // Object enter target object pThing->Enter(pBase); // Success diff --git a/src/C4ObjectMenu.cpp b/src/C4ObjectMenu.cpp index dd5772319..3e55a2a4f 100644 --- a/src/C4ObjectMenu.cpp +++ b/src/C4ObjectMenu.cpp @@ -66,7 +66,7 @@ bool C4ObjectMenu::IsCloseDenied() if (Object) fResult = static_cast(Object->Call(PSF_MenuQueryCancel, pars)); } else if (eCallbackType == CB_Scenario) - fResult = static_cast(Game.Script.Call(PSF_MenuQueryCancel, pars)); + fResult = static_cast(Game.Script.Call(*section, PSF_MenuQueryCancel, pars)); CloseQuerying = false; if (fResult) return true; } @@ -79,12 +79,19 @@ void C4ObjectMenu::LocalInit(C4Object *pObject, bool fUserMenu) Object = pObject; UserMenu = fUserMenu; ParentObject = GetParentObject(); - if (pObject) eCallbackType = CB_Object; else eCallbackType = CB_Scenario; + if (pObject) + { + eCallbackType = CB_Object; + } + else + { + eCallbackType = CB_Scenario; + } } -bool C4ObjectMenu::Init(C4FacetExSurface &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle, bool fUserMenu) +bool C4ObjectMenu::Init(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, C4Object *pObject, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle, bool fUserMenu) { - if (!DoInit(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; + if (!DoInit(fctSymbol, section, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; LocalInit(pObject, fUserMenu); return true; } @@ -98,7 +105,7 @@ void C4ObjectMenu::OnSelectionChanged(int32_t iNewSelection) if (eCallbackType == CB_Object && Object) Object->Call(PSF_MenuSelection, pars); else if (eCallbackType == CB_Scenario) - Game.Script.Call(PSF_MenuSelection, pars); + Game.Script.Call(*section, PSF_MenuSelection, pars); } } @@ -226,7 +233,7 @@ bool C4ObjectMenu::DoRefillInternal(bool &rfRefilled) sprintf(szCommand, "AppendCommand(this,\"Buy\",Object(%d),%d,0,,0,%s)&&ExecuteCommand()", pTarget->Number, 1, C4IdText(pDef->id)); sprintf(szCommand2, "AppendCommand(this,\"Buy\",Object(%d),%d,0,,0,%s)&&ExecuteCommand()", pTarget->Number, iCount, C4IdText(pDef->id)); // Buying value - int32_t iBuyValue = pDef->GetValue(pTarget, pPlayer->Number); + int32_t iBuyValue = pDef->GetValue(*pTarget->Section, pTarget, pPlayer->Number); // Add menu item Add(szCaption, fctSymbol, szCommand, iCount, nullptr, pDef->GetDesc(), pDef->id, szCommand2, true, iBuyValue); } @@ -522,7 +529,7 @@ bool C4ObjectMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) case CB_Scenario: // Object menu with scenario script callback - Game.Script.DirectExec(nullptr, szCommand, "MenuCommand", false, Game.Script.Strict); + Game.Script.DirectExec(*section, nullptr, szCommand, "MenuCommand", false, Game.Script.Strict); break; case CB_None: @@ -556,7 +563,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) if (cObj = pTarget->Action.Target) for (iFunction = 0; pFunction = cObj->Def->Script.GetSFunc(iFunction, "ActionContext"); iFunction++) if (!pFunction->OverloadedBy) - if (!pFunction->Condition || pFunction->Condition->Exec(cObj, {C4VObj(Object), C4VID(pFunction->idImage), C4VObj(pTarget)})) + if (!pFunction->Condition || pFunction->Condition->Exec(*cObj->Section, cObj, {C4VObj(Object), C4VID(pFunction->idImage), C4VObj(pTarget)})) if (!fCountOnly) { sprintf(szCommand, "ProtectedCall(Object(%d),\"%s\",this,Object(%d))", cObj->Number, pFunction->Name, pTarget->Number); @@ -576,7 +583,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) if (pEffScript) for (iFunction = 0; pFunction = pEffScript->GetSFunc(iFunction, sPattern.getData()); iFunction++) if (!pFunction->OverloadedBy) - if (!pFunction->Condition || pFunction->Condition->Exec(pEff->pCommandTarget, {C4VObj(pTarget), C4VInt(pEff->iNumber), C4VObj(Object), C4VID(pFunction->idImage)})) + if (!pFunction->Condition || pFunction->Condition->Exec(**pEff->section, pEff->pCommandTarget, {C4VObj(pTarget), C4VInt(pEff->iNumber), C4VObj(Object), C4VID(pFunction->idImage)})) if (!fCountOnly) { sprintf(szCommand, "ProtectedCall(Object(%d),\"%s\",Object(%d),%d,Object(%d),%s)", pEff->pCommandTarget->Number, pFunction->Name, pTarget->Number, static_cast(pEff->iNumber), Object->Number, C4IdText(pFunction->idImage)); @@ -596,7 +603,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) if (cObj->Def->ActMap[cObj->Action.Act].Procedure == DFA_ATTACH) for (iFunction = 0; pFunction = cObj->Def->Script.GetSFunc(iFunction, "AttachContext"); iFunction++) if (!pFunction->OverloadedBy) - if (!pFunction->Condition || pFunction->Condition->Exec(cObj, {C4VObj(Object), C4VID(pFunction->idImage), C4VObj(pTarget)})) + if (!pFunction->Condition || pFunction->Condition->Exec(*cObj->Section, cObj, {C4VObj(Object), C4VID(pFunction->idImage), C4VObj(pTarget)})) if (!fCountOnly) { sprintf(szCommand, "ProtectedCall(Object(%d),\"%s\",this,Object(%d))", cObj->Number, pFunction->Name, pTarget->Number); @@ -618,7 +625,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) // Find function not overloaded if (!pFunction->OverloadedBy) // Function condition valid - if (!pFunction->Condition || pFunction->Condition->Exec(pTarget, {C4VObj(Object), C4VID(pFunction->idImage)})) + if (!pFunction->Condition || pFunction->Condition->Exec(*pTarget->Section, pTarget, {C4VObj(Object), C4VID(pFunction->idImage)})) { // Get function text strDescText = pFunction->DescText.getData() ? pFunction->DescText.getData() : pTarget->GetName(); @@ -626,7 +633,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) bool fDouble = false; for (iFunction = 0; pFunction2 = pTarget->Def->Script.GetSFunc(iFunction, "Context"); iFunction++) if (!pFunction2->OverloadedBy) - if (!pFunction2->Condition || pFunction2->Condition->Exec(pTarget, {C4VObj(Object), C4VID(pFunction2->idImage)})) + if (!pFunction2->Condition || pFunction2->Condition->Exec(*pTarget->Section, pTarget, {C4VObj(Object), C4VID(pFunction2->idImage)})) if (SEqual(strDescText, pFunction2->DescText.getData())) fDouble = true; // If so, skip this function to prevent duplicate entries @@ -658,7 +665,7 @@ int32_t C4ObjectMenu::AddContextFunctions(C4Object *pTarget, bool fCountOnly) if (!(pTarget->Category & C4D_Living) || pTarget->GetAlive()) // No dead livings for (iFunction = 0; pFunction = pTarget->Def->Script.GetSFunc(iFunction, "Context"); iFunction++) if (!pFunction->OverloadedBy) - if (!pFunction->Condition || pFunction->Condition->Exec(pTarget, {C4VObj(Object), C4VID(pFunction->idImage)})) + if (!pFunction->Condition || pFunction->Condition->Exec(*pTarget->Section, pTarget, {C4VObj(Object), C4VID(pFunction->idImage)})) if (!fCountOnly) { sprintf(szCommand, "ProtectedCall(Object(%d),\"%s\",this)", pTarget->Number, pFunction->Name); diff --git a/src/C4ObjectMenu.h b/src/C4ObjectMenu.h index f065d317b..c196de47c 100644 --- a/src/C4ObjectMenu.h +++ b/src/C4ObjectMenu.h @@ -69,7 +69,7 @@ class C4ObjectMenu : public C4Menu public: void SetRefillObject(C4Object *pObj); void ClearPointers(C4Object *pObj); - bool Init(C4FacetExSurface &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal, bool fUserMenu = false); + bool Init(C4FacetExSurface &fctSymbol, C4Section §ion, const char *szEmpty, C4Object *pObject, int32_t iExtra = C4MN_Extra_None, int32_t iExtraData = 0, int32_t iId = 0, int32_t iStyle = C4MN_Style_Normal, bool fUserMenu = false); void Execute(); virtual C4Object *GetParentObject() override; diff --git a/src/C4Player.cpp b/src/C4Player.cpp index 7fdcf803c..a52bd3dc8 100644 --- a/src/C4Player.cpp +++ b/src/C4Player.cpp @@ -167,10 +167,10 @@ void C4Player::Execute() if (LocalControl && !Game.Control.isReplay()) { // team selection done through queue because TeamSelection-status may not be in sync (may be TeamSelectionPending!) - DoTeamSelection(idSelectedTeam); + DoTeamSelection(**ViewSection, idSelectedTeam); } } - else if (!Menu.IsActive()) ActivateMenuTeamSelection(false); + else if (!Menu.IsActive()) ActivateMenuTeamSelection(**ViewSection, false); else { // during team selection: Update view to selected team, if it has a position assigned @@ -340,7 +340,7 @@ bool C4Player::Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientNa C4Def *pDefCallback; if (idCallback && (pDefCallback = Game.Defs.ID2Def(idCallback))) { - pDefCallback->Script.Call(PSF_InitializeScriptPlayer, {C4VInt(Number), C4VInt(Team)}); + pDefCallback->Script.Call(**ViewSection, PSF_InitializeScriptPlayer, {C4VInt(Number), C4VInt(Team)}); } } else @@ -828,7 +828,7 @@ void C4Player::SetFoW(bool fEnable) bForceFogOfWar = true; } -C4Object *C4Player::Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Object *pBuyObj) +C4Object *C4Player::Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Section §ion, C4Object *pBuyObj) { int32_t iAvailable; C4Def *pDef; C4Object *pThing; // Base owner eliminated @@ -844,7 +844,7 @@ C4Object *C4Player::Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Object *pB // Object not available if (iAvailable <= 0) return nullptr; // get value - int32_t iValue = pDef->GetValue(pBuyObj, Number); + int32_t iValue = pDef->GetValue(section, pBuyObj, Number); // Not enough wealth (base owner's wealth) if (iValue > Wealth) { @@ -858,7 +858,7 @@ C4Object *C4Player::Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Object *pB // Reduce wealth DoWealth(-iValue); // Create object (for player) - if (!(pThing = (pBuyObj ? *pBuyObj->Section : *Game.Sections.front()).CreateObject(id, pBuyObj, iForPlr))) return nullptr; // FIXME + if (!(pThing = section.CreateObject(id, pBuyObj, iForPlr))) return nullptr; // FIXME // Make crew member if (pDef->CrewMember) if (ValidPlr(iForPlr)) Game.Players.Get(iForPlr)->MakeCrewMember(pThing); @@ -885,7 +885,7 @@ bool C4Player::Sell2Home(C4Object *pObj) C4Def *pSellDef = pObj->Def; if (C4AulScriptFunc *f = pObj->Def->Script.SFn_SellTo) { - id = f->Exec(pObj, {C4VInt(Number)}).getC4ID(); + id = f->Exec(*pObj->Section, pObj, {C4VInt(Number)}).getC4ID(); pSellDef = Game.Defs.ID2Def(id); } // Add to homebase material @@ -1768,11 +1768,11 @@ void C4Player::DefaultRuntimeData() FlashCom = 0; } -bool C4Player::ActivateMenuTeamSelection(bool fFromMain) +bool C4Player::ActivateMenuTeamSelection(C4Section §ion, bool fFromMain) { // Menu symbol/init bool fSwitch = !(Status == PS_TeamSelection); - Menu.InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team), LoadResStr("IDS_MSG_SELTEAM"), Number, C4MN_Extra_None, 0, fSwitch ? C4MN_TeamSwitch : C4MN_TeamSelection); + Menu.InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team), section, LoadResStr("IDS_MSG_SELTEAM"), Number, C4MN_Extra_None, 0, fSwitch ? C4MN_TeamSwitch : C4MN_TeamSelection); Menu.SetAlignment(fSwitch ? C4MN_Align_Left | C4MN_Align_Bottom : 0); Menu.Refill(); // Go back to options menu on close @@ -1780,12 +1780,12 @@ bool C4Player::ActivateMenuTeamSelection(bool fFromMain) return true; } -void C4Player::DoTeamSelection(int32_t idTeam) +void C4Player::DoTeamSelection(C4Section §ion, int32_t idTeam) { // stop team selection. This might close the menu forever if the control gets lost // let's hope it doesn't! Status = PS_TeamSelectionPending; - Game.Control.DoInput(CID_InitScenarioPlayer, new C4ControlInitScenarioPlayer(Number, idTeam), CDT_Queue); + Game.Control.DoInput(CID_InitScenarioPlayer, new C4ControlInitScenarioPlayer(Game.GetSectionIndex(section), Number, idTeam), CDT_Queue); } void C4Player::EnumeratePointers() @@ -1830,7 +1830,7 @@ void C4Player::NotifyOwnedObjects() C4AulFunc *pFn = cobj->Def->Script.GetFuncRecursive(PSF_OnOwnerRemoved); // PSF_OnOwnerRemoved has an internal fallback function assert(pFn); - if (pFn) pFn->Exec(cobj); + if (pFn) pFn->Exec(*section, cobj); } } } @@ -2342,7 +2342,7 @@ bool C4Player::ActivateMenuMain() // Not during game over dialog if (C4GameOverDlg::IsShown()) return false; // Open menu - return !!Menu.ActivateMain(Number); + return !!Menu.ActivateMain(**ViewSection, Number); } void C4Player::SyncHomebaseMaterialToTeam() diff --git a/src/C4Player.h b/src/C4Player.h index 614dc39be..9c15c458c 100644 --- a/src/C4Player.h +++ b/src/C4Player.h @@ -190,7 +190,7 @@ class C4Player : public C4PlayerInfoCore bool Load(const char *szFilename, bool fSavegame, bool fLoadPortraits); static bool Strip(const char *szFilename, bool fAggressive); bool ObjectInCrew(C4Object *tobj); - C4Object *Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Object *pBuyObj = nullptr); // buy object of player's wealth + C4Object *Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Section §ion, C4Object *pBuyObj = nullptr); // buy object of player's wealth bool Sell2Home(C4Object *tobj); bool CanSell(C4Object *obj) const; bool DoWealth(int32_t change); @@ -198,8 +198,8 @@ class C4Player : public C4PlayerInfoCore void CompileFunc(StdCompiler *pComp); bool LoadRuntimeData(C4Group &hGroup); bool ActivateMenuMain(); - bool ActivateMenuTeamSelection(bool fFromMain); - void DoTeamSelection(int32_t idTeam); + bool ActivateMenuTeamSelection(C4Section §ion, bool fFromMain); + void DoTeamSelection(C4Section §ion, int32_t idTeam); C4Object *GetHiRankActiveCrew(bool fSelectedOnly); void SetFoW(bool fEnable); int32_t ActiveCrewCount(); diff --git a/src/C4Script.cpp b/src/C4Script.cpp index c4cedce2f..10e066592 100644 --- a/src/C4Script.cpp +++ b/src/C4Script.cpp @@ -257,7 +257,7 @@ static bool FnIncinerateLandscape(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iX += cthr->Obj->x; iY += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Landscape.Incinerate(iX, iY); + return cthr->GetSection().Landscape.Incinerate(iX, iY); } static bool FnExtinguish(C4AulContext *cthr, C4Object *pObj) @@ -278,12 +278,12 @@ static bool FnSetSolidMask(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iY, C4V static void FnSetGravity(C4AulContext *cthr, C4ValueInt iGravity) { - C4Object::GetSection(cthr->Obj).Landscape.Gravity = itofix(BoundBy(iGravity, -300, 300)) / 500; + cthr->GetSection().Landscape.Gravity = itofix(BoundBy(iGravity, -300, 300)) / 500; } static C4ValueInt FnGetGravity(C4AulContext *cthr) { - return fixtoi(C4Object::GetSection(cthr->Obj).Landscape.Gravity * 500); + return fixtoi(cthr->GetSection().Landscape.Gravity * 500); } static bool FnDeathAnnounce(C4AulContext *cthr) @@ -414,7 +414,7 @@ static bool FnSplit2Components(C4AulContext *cthr, C4Object *pObj) else pThing->Exit(pThing->x, pThing->y); // Destroy the object, create its components C4IDList ObjComponents; - pObj->Def->GetComponents(&ObjComponents, pObj, cthr->Obj); + pObj->Def->GetComponents(&ObjComponents, *pObj->Section, pObj, cthr->Obj); if (pObj->Contained) pObj->Exit(pObj->x, pObj->y); for (cnt = 0; ObjComponents.GetID(cnt); cnt++) { @@ -425,7 +425,7 @@ static bool FnSplit2Components(C4AulContext *cthr, C4Object *pObj) const auto r3 = itofix(Rnd3()); const auto r2 = itofix(Rnd3()); const auto r1 = Random(360); - if (pNew = C4Object::GetSection(pObj).CreateObject(ObjComponents.GetID(cnt), + if (pNew = pObj->Section->CreateObject(ObjComponents.GetID(cnt), pObj, pObj->Owner, pObj->x, pObj->y, @@ -657,9 +657,9 @@ static std::optional FnGetPhysical(C4AulContext *cthr, C4String *szP // In fair crew mode, scripts may not read permanent physical values - fallback to fair def physical instead! if (Game.Parameters.UseFairCrew) if (pObj->Info->pDef) - return {pObj->Info->pDef->GetFairCrewPhysicals()->*off}; + return {pObj->Info->pDef->GetFairCrewPhysicals(*pObj->Section)->*off}; else - return {pObj->Def->GetFairCrewPhysicals()->*off}; + return {pObj->Def->GetFairCrewPhysicals(*pObj->Section)->*off}; // Get physical return {pObj->Info->Physical.*off}; // Temporary physical @@ -748,7 +748,7 @@ static bool FnSetBridgeActionData(C4AulContext *cthr, C4ValueInt iBridgeLength, if (pObj->Action.Act <= ActIdle) return false; if (pObj->Def->ActMap[pObj->Action.Act].Procedure != DFA_BRIDGE) return false; // set data - pObj->Action.SetBridgeData(iBridgeLength, fMoveClonk, fWall, std::min(iBridgeMaterial, C4Object::GetSection(pObj).Material.Num - 1)); + pObj->Action.SetBridgeData(iBridgeLength, fMoveClonk, fWall, std::min(iBridgeMaterial, pObj->Section->Material.Num - 1)); return true; } @@ -1363,7 +1363,7 @@ static std::optional FnGetValue(C4AulContext *cthr, C4Object *pObj, C4Def *pDef; if (idDef) // return Def value or 0 if def unloaded - if (pDef = Game.Defs.ID2Def(idDef)) return pDef->GetValue(pInBase, iForPlayer); else return {}; + if (pDef = Game.Defs.ID2Def(idDef)) return pDef->GetValue(cthr->GetSection(), pInBase, iForPlayer); else return {}; // FIXME // Object value if (!pObj) pObj = cthr->Obj; if (!pObj) return {}; return {pObj->GetValue(pInBase, iForPlayer)}; @@ -1436,7 +1436,7 @@ static bool FnCreateMenu(C4AulContext *cthr, C4ID iSymbol, C4Object *pMenuObj, C // Clear any old menu, init new menu if (!pMenuObj->CloseMenu(false)) return false; if (!pMenuObj->Menu) pMenuObj->Menu = new C4ObjectMenu; else pMenuObj->Menu->ClearItems(true); - pMenuObj->Menu->Init(fctSymbol, FnStringPar(szCaption), pCommandObj, iExtra, iExtraData, idMenuID ? idMenuID : iSymbol, iStyle, true); + pMenuObj->Menu->Init(fctSymbol, *pMenuObj->Section, FnStringPar(szCaption), pCommandObj, iExtra, iExtraData, idMenuID ? idMenuID : iSymbol, iStyle, true); // Set permanent pMenuObj->Menu->SetPermanent(fPermanent); @@ -1734,7 +1734,7 @@ static bool FnSetMenuDecoration(C4AulContext *cthr, C4ID idNewDeco, C4Object *pM { if (!pMenuObj || !pMenuObj->Menu) return false; C4GUI::FrameDecoration *pNewDeco = new C4GUI::FrameDecoration(); - if (!pNewDeco->SetByDef(idNewDeco)) + if (!pNewDeco->SetByDef(cthr->GetSection(), idNewDeco)) { delete pNewDeco; return false; @@ -1871,7 +1871,7 @@ static std::optional FnComponentAll(C4AulContext *cthr, C4Object *pObj, C4 C4ValueInt cnt; if (!pObj) return {}; C4IDList Components; - pObj->Def->GetComponents(&Components, pObj, cthr->Obj); + pObj->Def->GetComponents(&Components, *pObj->Section, pObj, cthr->Obj); for (cnt = 0; Components.GetID(cnt); cnt++) if (Components.GetID(cnt) != c_id) if (Components.GetCount(cnt) > 0) @@ -1890,7 +1890,7 @@ static C4Object *FnCreateObject(C4AulContext *cthr, iOwner = cthr->Obj->Owner; } - C4Object *pNewObj = C4Object::GetSection(cthr->Obj).CreateObject(id, cthr->Obj, iOwner, iXOffset, iYOffset); + C4Object *pNewObj = cthr->GetSection().CreateObject(id, cthr->Obj, iOwner, iXOffset, iYOffset); // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player if (pNewObj && cthr->Obj && cthr->Obj->Controller > NO_OWNER) pNewObj->Controller = cthr->Obj->Controller; @@ -1913,11 +1913,11 @@ static C4Object *FnCreateConstruction(C4AulContext *cthr, // Check site if (fCheckSite) - if (!C4Object::GetSection(cthr->Obj).Landscape.ConstructionCheck(id, iXOffset, iYOffset, cthr->Obj)) + if (!cthr->GetSection().Landscape.ConstructionCheck(id, iXOffset, iYOffset, cthr->Obj)) return nullptr; // Create site object - C4Object *pNewObj = C4Object::GetSection(cthr->Obj).CreateObjectConstruction(id, cthr->Obj, iOwner, iXOffset, iYOffset, iCompletion * FullCon / 100, fTerrain); + C4Object *pNewObj = cthr->GetSection().CreateObjectConstruction(id, cthr->Obj, iOwner, iXOffset, iYOffset, iCompletion * FullCon / 100, fTerrain); // Set initial controller to creating controller, so more complicated cause-effect-chains can be traced back to the causing player if (pNewObj && cthr->Obj && cthr->Obj->Controller > NO_OWNER) pNewObj->Controller = cthr->Obj->Controller; @@ -1957,7 +1957,7 @@ static std::optional FnFindConstructionSite(C4AulContext *cthr, C4ID id, C C4Value &V1 = cthr->Caller->NumVars[iVarX]; C4Value &V2 = cthr->Caller->NumVars[iVarY]; // Construction check at starting position - C4Section §ion{C4Object::GetSection(cthr->Caller->Obj)}; + C4Section §ion{cthr->Caller->GetSection()}; if (section.Landscape.ConstructionCheck(id, V1.getInt(), V2.getInt())) return {true}; // Search for real @@ -1973,7 +1973,7 @@ static std::optional FnFindConstructionSite(C4AulContext *cthr, C4ID id, C static C4Object *FnFindBase(C4AulContext *cthr, C4ValueInt iOwner, C4ValueInt iIndex) { if (!ValidPlr(iOwner)) return nullptr; - return C4Object::GetSection(cthr->Obj).FindBase(iOwner, iIndex); + return cthr->GetSection().FindBase(iOwner, iIndex); } C4FindObject *CreateCriterionsFromPars(const C4Value *pPars, C4FindObject **pFOs, C4SortObject **pSOs) @@ -2033,7 +2033,7 @@ static C4Value FnObjectCount2(C4AulContext *cthr, const C4Value *pPars) if (!pFO) throw C4AulExecError(cthr->Obj, "ObjectCount: No valid search criterions supplied!"); // Search - int32_t iCnt = pFO->Count(C4Object::GetSection(cthr->Obj).Objects, C4Object::GetSection(cthr->Obj).Objects.Sectors); + int32_t iCnt = pFO->Count(cthr->GetSection().Objects, cthr->GetSection().Objects.Sectors); // Free delete pFO; // Return @@ -2050,7 +2050,7 @@ static C4Value FnFindObject2(C4AulContext *cthr, const C4Value *pPars) if (!pFO) throw C4AulExecError(cthr->Obj, "FindObject: No valid search criterions supplied!"); // Search - C4Object *pObj = pFO->Find(C4Object::GetSection(cthr->Obj).Objects, C4Object::GetSection(cthr->Obj).Objects.Sectors); + C4Object *pObj = pFO->Find(cthr->GetSection().Objects, cthr->GetSection().Objects.Sectors); // Free delete pFO; // Return @@ -2067,7 +2067,7 @@ static C4Value FnFindObjects(C4AulContext *cthr, const C4Value *pPars) if (!pFO) throw C4AulExecError(cthr->Obj, "FindObjects: No valid search criterions supplied!"); // Search - C4ValueArray *pResult = pFO->FindMany(C4Object::GetSection(cthr->Obj).Objects, C4Object::GetSection(cthr->Obj).Objects.Sectors); + C4ValueArray *pResult = pFO->FindMany(cthr->GetSection().Objects, cthr->GetSection().Objects.Sectors); // Free delete pFO; // Return @@ -2093,7 +2093,7 @@ static C4ValueInt FnObjectCount(C4AulContext *cthr, C4ID id, C4ValueInt x, C4Val if (vContainer.getInt() == ANY_CONTAINER) pContainer = reinterpret_cast(ANY_CONTAINER); // Find object - return C4Object::GetSection(cthr->Obj).ObjectCount(id, x, y, wdt, hgt, dwOCF, + return cthr->GetSection().ObjectCount(id, x, y, wdt, hgt, dwOCF, FnStringPar(szAction), pActionTarget, cthr->Obj, // Local calls exclude self pContainer, @@ -2117,7 +2117,7 @@ static C4Object *FnFindObject(C4AulContext *cthr, C4ID id, C4ValueInt x, C4Value if (vContainer.getInt() == ANY_CONTAINER) pContainer = reinterpret_cast(ANY_CONTAINER); // Find object - return C4Object::GetSection(cthr->Obj).FindObject(id, x, y, wdt, hgt, dwOCF, + return cthr->GetSection().FindObject(id, x, y, wdt, hgt, dwOCF, FnStringPar(szAction), pActionTarget, cthr->Obj, // Local calls exclude self pContainer, @@ -2144,7 +2144,7 @@ static C4Object *FnFindObjectOwner(C4AulContext *cthr, // Adjust default ocf if (dwOCF == 0) dwOCF = OCF_All; // Find object - return C4Object::GetSection(cthr->Obj).FindObject(id, x, y, wdt, hgt, dwOCF, + return cthr->GetSection().FindObject(id, x, y, wdt, hgt, dwOCF, FnStringPar(szAction), pActionTarget, cthr->Obj, // Local calls exclude self nullptr, @@ -2169,7 +2169,7 @@ static bool FnGrabObjectInfo(C4AulContext *cthr, C4Object *pFrom, C4Object *pTo) static bool FnFlameConsumeMaterial(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; C4ValueInt mat = section.Landscape.GetMat(x, y); if (!section.MatValid(mat)) return false; if (!section.Material.Map[mat].Inflammable) return false; @@ -2180,20 +2180,20 @@ static bool FnFlameConsumeMaterial(C4AulContext *cthr, C4ValueInt x, C4ValueInt static void FnSmoke(C4AulContext *cthr, C4ValueInt tx, C4ValueInt ty, C4ValueInt level, C4ValueInt dwClr) { if (cthr->Obj) { tx += cthr->Obj->x; ty += cthr->Obj->y; } - Smoke(C4Object::GetSection(cthr->Obj), tx, ty, level, dwClr); + Smoke(cthr->GetSection(), tx, ty, level, dwClr); } static void FnBubble(C4AulContext *cthr, C4ValueInt tx, C4ValueInt ty) { if (cthr->Obj) { tx += cthr->Obj->x; ty += cthr->Obj->y; } - BubbleOut(C4Object::GetSection(cthr->Obj), tx, ty); + BubbleOut(cthr->GetSection(), tx, ty); } static C4ValueInt FnExtractLiquid(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; if (!section.Landscape.GBackLiquid(x, y)) return MNone; return section.Landscape.ExtractMaterial(x, y); } @@ -2201,12 +2201,12 @@ static C4ValueInt FnExtractLiquid(C4AulContext *cthr, C4ValueInt x, C4ValueInt y static bool FnInsertMaterial(C4AulContext *cthr, C4ValueInt mat, C4ValueInt x, C4ValueInt y, C4ValueInt vx, C4ValueInt vy) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return !!C4Object::GetSection(cthr->Obj).Landscape.InsertMaterial(mat, x, y, vx, vy); + return !!cthr->GetSection().Landscape.InsertMaterial(mat, x, y, vx, vy); } static C4ValueInt FnGetMaterialCount(C4AulContext *cthr, C4ValueInt iMaterial, bool fReal) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; if (!section.MatValid(iMaterial)) return -1; if (fReal || !section.Material.Map[iMaterial].MinHeightCount) @@ -2218,12 +2218,12 @@ static C4ValueInt FnGetMaterialCount(C4AulContext *cthr, C4ValueInt iMaterial, b static C4ValueInt FnGetMaterial(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Landscape.GetMat(x, y); + return cthr->GetSection().Landscape.GetMat(x, y); } static C4String *FnGetTexture(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; // Get texture int32_t iTex = section.PixCol2Tex(section.Landscape.GetPix(x, y)); if (!iTex) return nullptr; @@ -2237,32 +2237,32 @@ static C4String *FnGetTexture(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) static bool FnGBackSolid(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Landscape.GBackSolid(x, y); + return cthr->GetSection().Landscape.GBackSolid(x, y); } static bool FnGBackSemiSolid(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Landscape.GBackSemiSolid(x, y); + return cthr->GetSection().Landscape.GBackSemiSolid(x, y); } static bool FnGBackLiquid(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Landscape.GBackLiquid(x, y); + return cthr->GetSection().Landscape.GBackLiquid(x, y); } static bool FnGBackSky(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return !C4Object::GetSection(cthr->Obj).Landscape.GBackIFT(x, y); + return !cthr->GetSection().Landscape.GBackIFT(x, y); } static C4ValueInt FnExtractMaterialAmount(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, C4ValueInt mat, C4ValueInt amount){ if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; C4ValueInt extracted = 0; for (; extracted < amount; extracted++) { if (section.Landscape.GetMat(x, y) != mat) return extracted; @@ -2274,7 +2274,7 @@ static C4ValueInt FnExtractMaterialAmount(C4AulContext *cthr, C4ValueInt x, C4Va static void FnBlastObjects(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iY, C4ValueInt iLevel, C4Object *pInObj, C4ValueInt iCausedByPlusOne) { C4ValueInt iCausedBy = iCausedByPlusOne - 1; if (!iCausedByPlusOne && cthr->Obj) iCausedBy = cthr->Obj->Controller; - C4Object::GetSection(cthr->Obj).BlastObjects(iX, iY, iLevel, pInObj, iCausedBy, cthr->Obj); + cthr->GetSection().BlastObjects(iX, iY, iLevel, pInObj, iCausedBy, cthr->Obj); } static bool FnBlastObject(C4AulContext *cthr, C4ValueInt iLevel, C4Object *pObj, C4ValueInt iCausedByPlusOne) @@ -2296,7 +2296,7 @@ static void FnBlastFree(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iY, C4Valu iY += cthr->Obj->y; } C4ValueInt grade = BoundBy((iLevel / 10) - 1, 1, 3); - C4Object::GetSection(cthr->Obj).Landscape.BlastFree(iX, iY, iLevel, grade, iCausedBy); + cthr->GetSection().Landscape.BlastFree(iX, iY, iLevel, grade, iCausedBy); } static bool FnSound(C4AulContext *cthr, C4String *szSound, bool fGlobal, C4Object *pObj, C4ValueInt iLevel, C4ValueInt iAtPlayer, C4ValueInt iLoop, bool fMultiple, C4ValueInt iCustomFalloffDistance) @@ -2441,8 +2441,8 @@ static bool FnAddMessage(C4AulContext *cthr, C4String *szMessage, C4Object *pObj { if (!szMessage) return false; - if (pObj) Game.Messages.Append(C4GM_Target, FnStringFormat(cthr, FnStringPar(szMessage), &iPar0, &iPar1, &iPar2, &iPar3, &iPar4, &iPar5, &iPar6, &iPar7).getData(), pObj, NO_OWNER, 0, 0, FWhite); - else Game.Messages.Append(C4GM_Global, FnStringFormat(cthr, FnStringPar(szMessage), &iPar0, &iPar1, &iPar2, &iPar3, &iPar4, &iPar5, &iPar6, &iPar7).getData(), nullptr, ANY_OWNER, 0, 0, FWhite); + if (pObj) Game.Messages.Append(C4GM_Target, FnStringFormat(cthr, FnStringPar(szMessage), &iPar0, &iPar1, &iPar2, &iPar3, &iPar4, &iPar5, &iPar6, &iPar7).getData(), pObj->Section, pObj, NO_OWNER, 0, 0, FWhite); + else Game.Messages.Append(C4GM_Global, FnStringFormat(cthr, FnStringPar(szMessage), &iPar0, &iPar1, &iPar2, &iPar3, &iPar4, &iPar5, &iPar6, &iPar7).getData(), &cthr->GetSection(), nullptr, ANY_OWNER, 0, 0, FWhite); return true; } @@ -2475,18 +2475,18 @@ static void FnScriptGo(C4AulContext *cthr, bool go) static void FnCastPXS(C4AulContext *cthr, C4String *mat_name, C4ValueInt amt, C4ValueInt level, C4ValueInt tx, C4ValueInt ty) { if (cthr->Obj) { tx += cthr->Obj->x; ty += cthr->Obj->y; } - C4Object::GetSection(cthr->Obj).PXS.Cast(C4Object::GetSection(cthr->Obj).Material.Get(FnStringPar(mat_name)), amt, tx, ty, level); + cthr->GetSection().PXS.Cast(cthr->GetSection().Material.Get(FnStringPar(mat_name)), amt, tx, ty, level); } static void FnCastObjects(C4AulContext *cthr, C4ID id, C4ValueInt amt, C4ValueInt level, C4ValueInt tx, C4ValueInt ty) { if (cthr->Obj) { tx += cthr->Obj->x; ty += cthr->Obj->y; } - C4Object::GetSection(cthr->Obj).CastObjects(id, cthr->Obj, amt, level, tx, ty, cthr->Obj ? cthr->Obj->Owner : NO_OWNER, cthr->Obj ? cthr->Obj->Controller : NO_OWNER); + cthr->GetSection().CastObjects(id, cthr->Obj, amt, level, tx, ty, cthr->Obj ? cthr->Obj->Owner : NO_OWNER, cthr->Obj ? cthr->Obj->Controller : NO_OWNER); } static C4ValueInt FnMaterial(C4AulContext *cthr, C4String *mat_name) { - return C4Object::GetSection(cthr->Obj).Material.Get(FnStringPar(mat_name)); + return cthr->GetSection().Material.Get(FnStringPar(mat_name)); } C4Object *FnPlaceVegetation(C4AulContext *cthr, C4ID id, C4ValueInt iX, C4ValueInt iY, C4ValueInt iWdt, C4ValueInt iHgt, C4ValueInt iGrowth) @@ -2494,17 +2494,17 @@ C4Object *FnPlaceVegetation(C4AulContext *cthr, C4ID id, C4ValueInt iX, C4ValueI // Local call: relative coordinates if (cthr->Obj) { iX += cthr->Obj->x; iY += cthr->Obj->y; } // Place vegetation - return C4Object::GetSection(cthr->Obj).PlaceVegetation(id, iX, iY, iWdt, iHgt, iGrowth); + return cthr->GetSection().PlaceVegetation(id, iX, iY, iWdt, iHgt, iGrowth); } C4Object *FnPlaceAnimal(C4AulContext *cthr, C4ID id) { - return C4Object::GetSection(cthr->Obj).PlaceAnimal(id); + return cthr->GetSection().PlaceAnimal(id); } static void FnDrawVolcanoBranch(C4AulContext *cthr, C4ValueInt mat, C4ValueInt fx, C4ValueInt fy, C4ValueInt tx, C4ValueInt ty, C4ValueInt size) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; C4ValueInt cx, cx2, cy; for (cy = ty; cy < fy; cy++) { @@ -2691,9 +2691,9 @@ static C4Value FnGetComponent(C4AulContext *cthr, C4ID idComponent, C4ValueInt i C4Def *pDef = Game.Defs.ID2Def(idDef); if (!pDef) return C4VNull; // Component count - if (idComponent) return C4VInt(pDef->GetComponentCount(idComponent, cthr->Obj)); + if (idComponent) return C4VInt(pDef->GetComponentCount(idComponent, cthr->GetSection(), cthr->Obj)); // Indexed component - return C4VID(pDef->GetIndexedComponent(iIndex, cthr->Obj)); + return C4VID(pDef->GetIndexedComponent(iIndex, cthr->GetSection(), cthr->Obj)); } // Object component else @@ -3001,52 +3001,52 @@ static C4ValueInt FnSetCrewStatus(C4AulContext *cthr, C4ValueInt iPlr, bool fInC static C4ValueInt FnGetWind(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, bool fGlobal) { // global wind - if (fGlobal) return C4Object::GetSection(cthr->Obj).Weather.Wind; + if (fGlobal) return cthr->GetSection().Weather.Wind; // local wind if (cthr->Obj) { x += cthr->Obj->x; y += cthr->Obj->y; } - return C4Object::GetSection(cthr->Obj).Weather.GetWind(x, y); + return cthr->GetSection().Weather.GetWind(x, y); } static void FnSetWind(C4AulContext *cthr, C4ValueInt iWind) { - C4Object::GetSection(cthr->Obj).Weather.SetWind(iWind); + cthr->GetSection().Weather.SetWind(iWind); } static void FnSetTemperature(C4AulContext *cthr, C4ValueInt iTemperature) { - C4Object::GetSection(cthr->Obj).Weather.SetTemperature(iTemperature); + cthr->GetSection().Weather.SetTemperature(iTemperature); } static C4ValueInt FnGetTemperature(C4AulContext *cthr) { - return C4Object::GetSection(cthr->Obj).Weather.GetTemperature(); + return cthr->GetSection().Weather.GetTemperature(); } static void FnSetSeason(C4AulContext *cthr, C4ValueInt iSeason) { - return C4Object::GetSection(cthr->Obj).Weather.SetSeason(iSeason); + return cthr->GetSection().Weather.SetSeason(iSeason); } static C4ValueInt FnGetSeason(C4AulContext *cthr) { - return C4Object::GetSection(cthr->Obj).Weather.GetSeason(); + return cthr->GetSection().Weather.GetSeason(); } static void FnSetClimate(C4AulContext *cthr, C4ValueInt iClimate) { - C4Object::GetSection(cthr->Obj).Weather.SetClimate(iClimate); + cthr->GetSection().Weather.SetClimate(iClimate); } static C4ValueInt FnGetClimate(C4AulContext *cthr) { - return C4Object::GetSection(cthr->Obj).Weather.GetClimate(); + return cthr->GetSection().Weather.GetClimate(); } static void FnSetSkyFade(C4AulContext *cthr, C4ValueInt iFromRed, C4ValueInt iFromGreen, C4ValueInt iFromBlue, C4ValueInt iToRed, C4ValueInt iToGreen, C4ValueInt iToBlue) { // newgfx: set modulation - uint32_t dwBack, dwMod = GetClrModulation(C4Object::GetSection(cthr->Obj).Landscape.Sky.FadeClr1, C4RGB(iFromRed, iFromGreen, iFromBlue), dwBack); - C4Object::GetSection(cthr->Obj).Landscape.Sky.SetModulation(dwMod, dwBack); + uint32_t dwBack, dwMod = GetClrModulation(cthr->GetSection().Landscape.Sky.FadeClr1, C4RGB(iFromRed, iFromGreen, iFromBlue), dwBack); + cthr->GetSection().Landscape.Sky.SetModulation(dwMod, dwBack); } static void FnSetSkyColor(C4AulContext *cthr, C4ValueInt iIndex, C4ValueInt iRed, C4ValueInt iGreen, C4ValueInt iBlue) @@ -3054,8 +3054,8 @@ static void FnSetSkyColor(C4AulContext *cthr, C4ValueInt iIndex, C4ValueInt iRed // set first index only if (iIndex) return; // get color difference - uint32_t dwBack, dwMod = GetClrModulation(C4Object::GetSection(cthr->Obj).Landscape.Sky.FadeClr1, C4RGB(iRed, iGreen, iBlue), dwBack); - C4Object::GetSection(cthr->Obj).Landscape.Sky.SetModulation(dwMod, dwBack); + uint32_t dwBack, dwMod = GetClrModulation(cthr->GetSection().Landscape.Sky.FadeClr1, C4RGB(iRed, iGreen, iBlue), dwBack); + cthr->GetSection().Landscape.Sky.SetModulation(dwMod, dwBack); // success } @@ -3064,8 +3064,8 @@ static C4ValueInt FnGetSkyColor(C4AulContext *cthr, C4ValueInt iIndex, C4ValueIn // relict from OldGfx if (iIndex || !Inside(iRGB, 0, 2)) return 0; - uint32_t dwClr = C4Object::GetSection(cthr->Obj).Landscape.Sky.FadeClr1; - BltAlpha(dwClr, C4Object::GetSection(cthr->Obj).Landscape.Sky.FadeClr2 | ((iIndex * 0xff / 19) << 24)); + uint32_t dwClr = cthr->GetSection().Landscape.Sky.FadeClr1; + BltAlpha(dwClr, cthr->GetSection().Landscape.Sky.FadeClr2 | ((iIndex * 0xff / 19) << 24)); switch (iRGB) { case 0: return (dwClr >> 16) & 0xff; @@ -3077,22 +3077,22 @@ static C4ValueInt FnGetSkyColor(C4AulContext *cthr, C4ValueInt iIndex, C4ValueIn static C4ValueInt FnLandscapeWidth(C4AulContext *cthr) { - return C4Object::GetSection(cthr->Obj).Landscape.Width; + return cthr->GetSection().Landscape.Width; } static C4ValueInt FnLandscapeHeight(C4AulContext *cthr) { - return C4Object::GetSection(cthr->Obj).Landscape.Height; + return cthr->GetSection().Landscape.Height; } static C4ValueInt FnLaunchLightning(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, C4ValueInt xdir, C4ValueInt xrange, C4ValueInt ydir, C4ValueInt yrange, bool fDoGamma) { - return C4Object::GetSection(cthr->Obj).Weather.LaunchLightning(x, y, xdir, xrange, ydir, yrange, fDoGamma); + return cthr->GetSection().Weather.LaunchLightning(x, y, xdir, xrange, ydir, yrange, fDoGamma); } static C4ValueInt FnLaunchVolcano(C4AulContext *cthr, C4ValueInt x) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; return section.Weather.LaunchVolcano( section.Material.Get("Lava"), x, section.Landscape.Height - 1, @@ -3101,47 +3101,47 @@ static C4ValueInt FnLaunchVolcano(C4AulContext *cthr, C4ValueInt x) static void FnLaunchEarthquake(C4AulContext *cthr, C4ValueInt x, C4ValueInt y) { - C4Object::GetSection(cthr->Obj).Weather.LaunchEarthquake(x, y); + cthr->GetSection().Weather.LaunchEarthquake(x, y); } static void FnShakeFree(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, C4ValueInt rad) { - C4Object::GetSection(cthr->Obj).Landscape.ShakeFree(x, y, rad); + cthr->GetSection().Landscape.ShakeFree(x, y, rad); } static void FnShakeObjects(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, C4ValueInt rad) { - C4Object::GetSection(cthr->Obj).ShakeObjects(x, y, rad, cthr->Obj); + cthr->GetSection().ShakeObjects(x, y, rad, cthr->Obj); } static void FnDigFree(C4AulContext *cthr, C4ValueInt x, C4ValueInt y, C4ValueInt rad, bool fRequest) { - C4Object::GetSection(cthr->Obj).Landscape.DigFree(x, y, rad, fRequest, cthr->Obj); + cthr->GetSection().Landscape.DigFree(x, y, rad, fRequest, cthr->Obj); } static void FnDigFreeRect(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iY, C4ValueInt iWdt, C4ValueInt iHgt, bool fRequest) { - C4Object::GetSection(cthr->Obj).Landscape.DigFreeRect(iX, iY, iWdt, iHgt, fRequest, cthr->Obj); + cthr->GetSection().Landscape.DigFreeRect(iX, iY, iWdt, iHgt, fRequest, cthr->Obj); } static void FnFreeRect(C4AulContext *cthr, C4ValueInt iX, C4ValueInt iY, C4ValueInt iWdt, C4ValueInt iHgt, C4ValueInt iFreeDensity) { if (iFreeDensity) - C4Object::GetSection(cthr->Obj).Landscape.ClearRectDensity(iX, iY, iWdt, iHgt, iFreeDensity); + cthr->GetSection().Landscape.ClearRectDensity(iX, iY, iWdt, iHgt, iFreeDensity); else - C4Object::GetSection(cthr->Obj).Landscape.ClearRect(iX, iY, iWdt, iHgt); + cthr->GetSection().Landscape.ClearRect(iX, iY, iWdt, iHgt); } static bool FnPathFree(C4AulContext *cthr, C4ValueInt X1, C4ValueInt Y1, C4ValueInt X2, C4ValueInt Y2) { - return !!C4Object::GetSection(cthr->Obj).Landscape.PathFree(X1, Y1, X2, Y2); + return !!cthr->GetSection().Landscape.PathFree(X1, Y1, X2, Y2); } static bool FnPathFree2(C4AulContext *cthr, C4Value *X1, C4Value *Y1, C4ValueInt X2, C4ValueInt Y2) { int32_t x = -1, y = -1; // Do not use getInt on the references, because it destroys them. - bool r = C4Object::GetSection(cthr->Obj).Landscape.PathFree(X1->GetRefVal().getInt(), Y1->GetRefVal().getInt(), X2, Y2, &x, &y); + bool r = cthr->GetSection().Landscape.PathFree(X1->GetRefVal().getInt(), Y1->GetRefVal().getInt(), X2, Y2, &x, &y); if (!r) { *X1 = C4VInt(x); @@ -3447,7 +3447,7 @@ static C4Value FnObjectCall(C4AulContext *cthr, C4AulParSet Pars; Copy2ParSet8(Pars, par); // exec - return f->Exec(pObj, Pars, true, true, !cthr->CalledWithStrictNil()); + return f->Exec(*pObj->Section, pObj, Pars, true, true, !cthr->CalledWithStrictNil()); } static C4Value FnDefinitionCall(C4AulContext *cthr, @@ -3465,7 +3465,7 @@ static C4Value FnDefinitionCall(C4AulContext *cthr, C4AulParSet Pars; Copy2ParSet8(Pars, par); // Call - return pDef->Script.Call(szFunc2, Pars, true, !cthr->CalledWithStrictNil()); + return pDef->Script.Call(cthr->GetSection(), szFunc2, Pars, true, !cthr->CalledWithStrictNil()); } static C4Value FnGameCall(C4AulContext *cthr, @@ -3480,7 +3480,7 @@ static C4Value FnGameCall(C4AulContext *cthr, C4AulParSet Pars; Copy2ParSet9(Pars, par); // Call - return Game.Script.Call(szFunc2, Pars, true, !cthr->CalledWithStrictNil()); + return Game.Script.Call(cthr->GetSection(), szFunc2, Pars, true, !cthr->CalledWithStrictNil()); } static C4Value FnGameCallEx(C4AulContext *cthr, @@ -3512,7 +3512,7 @@ static C4Value FnProtectedCall(C4AulContext *cthr, C4AulParSet Pars; Copy2ParSet8(Pars, par); // exec - return f->Exec(pObj, Pars, true, !cthr->CalledWithStrictNil()); + return f->Exec(*pObj->Section, pObj, Pars, true, !cthr->CalledWithStrictNil()); } static C4Value FnPrivateCall(C4AulContext *cthr, @@ -3529,7 +3529,7 @@ static C4Value FnPrivateCall(C4AulContext *cthr, C4AulParSet Pars; Copy2ParSet8(Pars, par); // exec - return f->Exec(pObj, Pars, true, !cthr->CalledWithStrictNil()); + return f->Exec(*pObj->Section, pObj, Pars, true, !cthr->CalledWithStrictNil()); } static C4Object *FnEditCursor(C4AulContext *cth) @@ -3733,7 +3733,7 @@ static C4Object *FnBuy(C4AulContext *cthr, C4ID idBuyObj, C4ValueInt iForPlr, C4 if (!ValidPlr(iForPlr) || !ValidPlr(iPayPlr)) return nullptr; // buy C4Object *pThing; - if (!(pThing = Game.Players.Get(iPayPlr)->Buy(idBuyObj, fShowErrors, iForPlr, pToBase ? pToBase : cthr->Obj))) return nullptr; + if (!(pThing = Game.Players.Get(iPayPlr)->Buy(idBuyObj, fShowErrors, iForPlr, cthr->GetSection(), pToBase ? pToBase : cthr->Obj))) return nullptr; // enter object, if supplied if (pToBase) { @@ -4244,7 +4244,7 @@ static C4Value FnGetScenarioVal(C4AulContext *cthr, C4String *strEntry, C4String const char *strSection = FnStringPar(section); if (strSection && !*strSection) strSection = nullptr; - return GetValByStdCompiler(FnStringPar(strEntry), strSection, iEntryNr, mkParAdapt(C4Object::GetSection(cthr->Obj).C4S, false)); + return GetValByStdCompiler(FnStringPar(strEntry), strSection, iEntryNr, mkParAdapt(cthr->GetSection().C4S, false)); } static C4Value FnGetPlayerVal(C4AulContext *cthr, C4String *strEntry, C4String *section, C4ValueInt iPlr, C4ValueInt iEntryNr) @@ -4283,7 +4283,7 @@ static C4Value FnGetMaterialVal(C4AulContext *cthr, C4String *strEntry, C4String const char *strSection = FnStringPar(section); if (strSection && !*strSection) strSection = nullptr; - C4MaterialMap &material{C4Object::GetSection(cthr->Obj).Material}; + C4MaterialMap &material{cthr->GetSection().Material}; if (iMat < 0 || iMat >= material.Num) return C4VNull; @@ -4327,7 +4327,7 @@ static bool FnResortObjects(C4AulContext *cthr, C4String *szFunc, C4ValueInt Cat if (!pFn) throw C4AulExecError(cthr->Obj, FormatString("ResortObjects: Resort function %s not found", FnStringPar(szFunc)).getData()); // create object resort - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; C4ObjResort *pObjRes = new C4ObjResort(section.Objects); pObjRes->Category = Category; pObjRes->OrderFunc = pFn; @@ -4349,7 +4349,7 @@ static bool FnResortObject(C4AulContext *cthr, C4String *szFunc, C4Object *pObj) if (!pFn) throw C4AulExecError(cthr->Obj, FormatString("ResortObjects: Resort function %s not found", FnStringPar(szFunc)).getData()); // create object resort - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; C4ObjResort *pObjRes = new C4ObjResort(section.Objects); pObjRes->OrderFunc = pFn; pObjRes->pSortObj = pObj; @@ -4452,7 +4452,7 @@ static std::optional FnGetDefBottom(C4AulContext *cthr, C4Object *pO static bool FnSetMaterialColor(C4AulContext *cthr, C4ValueInt iMat, C4ValueInt iClr1R, C4ValueInt iClr1G, C4ValueInt iClr1B, C4ValueInt iClr2R, C4ValueInt iClr2G, C4ValueInt iClr2B, C4ValueInt iClr3R, C4ValueInt iClr3G, C4ValueInt iClr3B) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; // get mat if (!section.MatValid(iMat)) return false; C4Material *pMat = §ion.Material.Map[iMat]; @@ -4468,7 +4468,7 @@ static bool FnSetMaterialColor(C4AulContext *cthr, C4ValueInt iMat, C4ValueInt i static std::optional FnGetMaterialColor(C4AulContext *cthr, C4ValueInt iMat, C4ValueInt iNum, C4ValueInt iChannel) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; // get mat if (!section.MatValid(iMat)) return {}; C4Material *pMat = §ion.Material.Map[iMat]; @@ -4478,7 +4478,7 @@ static std::optional FnGetMaterialColor(C4AulContext *cthr, C4ValueI static C4String *FnMaterialName(C4AulContext *cthr, C4ValueInt iMat) { - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; // mat valid? if (!section.MatValid(iMat)) return nullptr; // return mat name @@ -4510,11 +4510,11 @@ static C4Value FnEval(C4AulContext *cthr, C4String *strScript) if (cthr->Caller) Strict = cthr->Caller->Func->pOrgScript->Strict; if (cthr->Obj) - return cthr->Obj->Def->Script.DirectExec(cthr->Obj, FnStringPar(strScript), "eval", true, Strict); + return cthr->Obj->Def->Script.DirectExec(cthr->GetSection(), cthr->Obj, FnStringPar(strScript), "eval", true, Strict); else if (cthr->Def) - return cthr->Def->Script.DirectExec(nullptr, FnStringPar(strScript), "eval", true, Strict); + return cthr->Def->Script.DirectExec(cthr->GetSection(), nullptr, FnStringPar(strScript), "eval", true, Strict); else - return Game.Script.DirectExec(nullptr, FnStringPar(strScript), "eval", true, Strict); + return Game.Script.DirectExec(cthr->GetSection(), nullptr, FnStringPar(strScript), "eval", true, Strict); } static bool FnLocateFunc(C4AulContext *cthr, C4String *funcname, C4Object *pObj, C4ID idDef) @@ -4625,25 +4625,25 @@ static C4Value FnGlobalN(C4AulContext *cthr, C4String *name) static void FnSetSkyAdjust(C4AulContext *cthr, C4ValueInt dwAdjust, C4ValueInt dwBackClr) { // set adjust - C4Object::GetSection(cthr->Obj).Landscape.Sky.SetModulation(dwAdjust, dwBackClr); + cthr->GetSection().Landscape.Sky.SetModulation(dwAdjust, dwBackClr); } static void FnSetMatAdjust(C4AulContext *cthr, C4ValueInt dwAdjust) { // set adjust - C4Object::GetSection(cthr->Obj).Landscape.SetModulation(dwAdjust); + cthr->GetSection().Landscape.SetModulation(dwAdjust); } static C4ValueInt FnGetSkyAdjust(C4AulContext *cthr, bool fBackColor) { // get adjust - return C4Object::GetSection(cthr->Obj).Landscape.Sky.GetModulation(!!fBackColor); + return cthr->GetSection().Landscape.Sky.GetModulation(!!fBackColor); } static C4ValueInt FnGetMatAdjust(C4AulContext *cthr) { // get adjust - return C4Object::GetSection(cthr->Obj).Landscape.GetModulation(); + return cthr->GetSection().Landscape.GetModulation(); } static C4ValueInt FnAnyContainer(C4AulContext *) { return ANY_CONTAINER; } @@ -4806,7 +4806,7 @@ static C4Value FnGetCrewExtraData(C4AulContext *cthr, C4Object *pCrew, C4String static C4ValueInt FnDrawMatChunks(C4AulContext *cctx, C4ValueInt tx, C4ValueInt ty, C4ValueInt twdt, C4ValueInt thgt, C4ValueInt icntx, C4ValueInt icnty, C4String *strMaterial, C4String *strTexture, bool bIFT) { - return C4Object::GetSection(cctx->Obj).Landscape.DrawChunks(tx, ty, twdt, thgt, icntx, icnty, FnStringPar(strMaterial), FnStringPar(strTexture), bIFT != 0); + return cctx->GetSection().Landscape.DrawChunks(tx, ty, twdt, thgt, icntx, icnty, FnStringPar(strMaterial), FnStringPar(strTexture), bIFT != 0); } static std::optional FnGetCrewEnabled(C4AulContext *cctx, C4Object *pObj) @@ -4856,13 +4856,13 @@ static bool FnUnselectCrew(C4AulContext *cctx, C4ValueInt iPlayer) static C4ValueInt FnDrawMap(C4AulContext *cctx, C4ValueInt iX, C4ValueInt iY, C4ValueInt iWdt, C4ValueInt iHgt, C4String *szMapDef) { // draw it! - return C4Object::GetSection(cctx->Obj).Landscape.DrawMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef)); + return cctx->GetSection().Landscape.DrawMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef)); } static C4ValueInt FnDrawDefMap(C4AulContext *cctx, C4ValueInt iX, C4ValueInt iY, C4ValueInt iWdt, C4ValueInt iHgt, C4String *szMapDef) { // draw it! - return C4Object::GetSection(cctx->Obj).Landscape.DrawDefMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef)); + return cctx->GetSection().Landscape.DrawDefMap(iX, iY, iWdt, iHgt, FnStringPar(szMapDef)); } static bool FnCreateParticle(C4AulContext *cthr, C4String *szName, C4ValueInt iX, C4ValueInt iY, C4ValueInt iXDir, C4ValueInt iYDir, C4ValueInt a, C4ValueInt b, C4Object *pObj, bool fBack) @@ -4879,7 +4879,7 @@ static bool FnCreateParticle(C4AulContext *cthr, C4String *szName, C4ValueInt iX C4ParticleDef *pDef = Game.Particles.GetDef(FnStringPar(szName)); if (!pDef) return false; // create - C4Object::GetSection(pObj ? pObj : cthr->Obj).Particles.Create(pDef, static_cast(iX), static_cast(iY), static_cast(iXDir) / 10.0f, static_cast(iYDir) / 10.0f, static_cast(a) / 10.0f, b, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : nullptr, pObj); + (pObj ? *pObj->Section : cthr->GetSection()).Particles.Create(pDef, static_cast(iX), static_cast(iY), static_cast(iXDir) / 10.0f, static_cast(iYDir) / 10.0f, static_cast(a) / 10.0f, b, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : nullptr, pObj); // success, even if not created return true; } @@ -4898,7 +4898,7 @@ static bool FnCastAParticles(C4AulContext *cthr, C4String *szName, C4ValueInt iA C4ParticleDef *pDef = Game.Particles.GetDef(FnStringPar(szName)); if (!pDef) return false; // cast - C4Object::GetSection(pObj ? pObj : cthr->Obj).Particles.Cast(pDef, iAmount, static_cast(iX), static_cast(iY), iLevel, static_cast(a0) / 10.0f, b0, static_cast(a1) / 10.0f, b1, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : nullptr, pObj); + (pObj ? *pObj->Section : cthr->GetSection()).Particles.Cast(pDef, iAmount, static_cast(iX), static_cast(iY), iLevel, static_cast(a0) / 10.0f, b0, static_cast(a1) / 10.0f, b1, pObj ? (fBack ? &pObj->BackParticles : &pObj->FrontParticles) : nullptr, pObj); // success, even if not created return true; } @@ -4923,7 +4923,7 @@ static bool FnPushParticles(C4AulContext *cthr, C4String *szName, C4ValueInt iAX if (!pDef) return false; } // push them - C4Object::GetSection(cthr->Obj).Particles.Push(pDef, static_cast(iAX) / 10.0f, static_cast(iAY) / 10.0f); + cthr->GetSection().Particles.Push(pDef, static_cast(iAX) / 10.0f, static_cast(iAY) / 10.0f); // success return true; } @@ -4937,7 +4937,7 @@ static bool FnClearParticles(C4AulContext *cthr, C4String *szName, C4Object *pOb pDef = Game.Particles.GetDef(FnStringPar(szName)); if (!pDef) return false; } - C4Section §ion{C4Object::GetSection(cthr->Obj)}; + C4Section §ion{cthr->GetSection()}; // delete them if (pObj) { @@ -4956,7 +4956,7 @@ static bool FnIsNewgfx(C4AulContext *) { return true; } static void FnSetSkyParallax(C4AulContext *ctx, C4ValueInt iMode, C4ValueInt iParX, C4ValueInt iParY, C4ValueInt iXDir, C4ValueInt iYDir, C4ValueInt iX, C4ValueInt iY) { - C4Section §ion{C4Object::GetSection(ctx->Obj)}; + C4Section §ion{ctx->GetSection()}; // set all parameters that aren't SkyPar_KEEP if (iMode != SkyPar_KEEP) if (Inside(iMode, 0, 1)) section.Landscape.Sky.ParallaxMode = iMode; @@ -5044,7 +5044,7 @@ static C4ValueHash *FnGetPath(C4AulContext *ctx, C4ValueInt iFromX, C4ValueInt i PathInfo pathinfo; pathinfo.path.push_back({static_cast(iFromX), static_cast(iFromY), nullptr}); - if (!C4Object::GetSection(ctx->Obj).PathFinder.Find(iFromX, iFromY, iToX, iToY, SetWaypoint, reinterpret_cast(&pathinfo))) + if (!ctx->GetSection().PathFinder.Find(iFromX, iFromY, iToX, iToY, SetWaypoint, reinterpret_cast(&pathinfo))) { return nullptr; } @@ -5078,12 +5078,12 @@ static C4ValueHash *FnGetPath(C4AulContext *ctx, C4ValueInt iFromX, C4ValueInt i static C4ValueInt FnSetTextureIndex(C4AulContext *ctx, C4String *psMatTex, C4ValueInt iNewIndex, bool fInsert) { if (!Inside(iNewIndex, C4ValueInt{0}, C4ValueInt{255})) return false; - return C4Object::GetSection(ctx->Obj).Landscape.SetTextureIndex(FnStringPar(psMatTex), uint8_t(iNewIndex), !!fInsert); + return ctx->GetSection().Landscape.SetTextureIndex(FnStringPar(psMatTex), uint8_t(iNewIndex), !!fInsert); } static void FnRemoveUnusedTexMapEntries(C4AulContext *ctx) { - C4Object::GetSection(ctx->Obj).Landscape.RemoveUnusedTexMapEntries(); + ctx->GetSection().Landscape.RemoveUnusedTexMapEntries(); } static void FnSetLandscapePixel(C4AulContext *ctx, C4ValueInt iX, C4ValueInt iY, C4ValueInt dwValue) @@ -5091,7 +5091,7 @@ static void FnSetLandscapePixel(C4AulContext *ctx, C4ValueInt iX, C4ValueInt iY, // local call if (ctx->Obj) { iX += ctx->Obj->x; iY += ctx->Obj->y; } // set pixel in 32bit-sfc only - C4Object::GetSection(ctx->Obj).Landscape.SetPixDw(iX, iY, dwValue); + ctx->GetSection().Landscape.SetPixDw(iX, iY, dwValue); } static bool FnSetObjectOrder(C4AulContext *ctx, C4Object *pObjBeforeOrAfter, C4Object *pSortObj, bool fSortAfter) @@ -5118,7 +5118,7 @@ static bool FnSetObjectOrder(C4AulContext *ctx, C4Object *pObjBeforeOrAfter, C4O static bool FnDrawMaterialQuad(C4AulContext *ctx, C4String *szMaterial, C4ValueInt iX1, C4ValueInt iY1, C4ValueInt iX2, C4ValueInt iY2, C4ValueInt iX3, C4ValueInt iY3, C4ValueInt iX4, C4ValueInt iY4, bool fSub) { const char *szMat = FnStringPar(szMaterial); - return !!C4Object::GetSection(ctx->Obj).Landscape.DrawQuad(iX1, iY1, iX2, iY2, iX3, iY3, iX4, iY4, szMat, fSub); + return !!ctx->GetSection().Landscape.DrawQuad(iX1, iY1, iX2, iY2, iX3, iY3, iX4, iY4, szMat, fSub); } static bool FnFightWith(C4AulContext *ctx, C4Object *pTarget, C4Object *pClonk) @@ -5328,7 +5328,7 @@ static std::optional FnSimFlight(C4AulContext *ctx, C4Value *pvrX, C4Value xdir = itofix(pvrXDir->getInt(), iPrec), ydir = itofix(pvrYDir->getInt(), iPrec); // simulate - if (!SimFlight(C4Object::GetSection(ctx->Obj), x, y, xdir, ydir, iDensityMin, iDensityMax, iIter)) + if (!SimFlight(ctx->GetSection(), x, y, xdir, ydir, iDensityMin, iDensityMax, iIter)) return {false}; // write results back @@ -5456,7 +5456,7 @@ static C4ValueInt FnAddEffect(C4AulContext *ctx, C4String *psEffectName, C4Objec if (!szEffect || !*szEffect || !iPrio) return 0; // create effect int32_t iEffectNumber; - new C4Effect(pTarget, szEffect, iPrio, iTimerIntervall, pCmdTarget, idCmdTarget, pvVal1, pvVal2, pvVal3, pvVal4, true, iEffectNumber, true); + new C4Effect(pTarget ? *pTarget->Section : ctx->GetSection(), pTarget, szEffect, iPrio, iTimerIntervall, pCmdTarget, idCmdTarget, pvVal1, pvVal2, pvVal3, pvVal4, true, iEffectNumber, true); // return assigned effect number - may be 0 if he effect has been denied by another effect // may also be the number of another effect return iEffectNumber; @@ -5466,7 +5466,7 @@ static C4Value FnGetEffect(C4AulContext *ctx, C4String *psEffectName, C4Object * { const char *szEffect = FnStringPar(psEffectName); // get effects - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return C4VNull; // name/wildcard given: find effect by name and index if (szEffect && *szEffect) @@ -5496,7 +5496,7 @@ static bool FnRemoveEffect(C4AulContext *ctx, C4String *psEffectName, C4Object * // evaluate parameters const char *szEffect = FnStringPar(psEffectName); // get effects - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return false; // name/wildcard given: find effect by name and index if (szEffect && *szEffect) @@ -5522,7 +5522,7 @@ static bool FnChangeEffect(C4AulContext *ctx, C4String *psEffectName, C4Object * const char *szNewEffect = FnStringPar(psNewEffectName); if (!szNewEffect || !*szNewEffect) return false; // get effects - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return false; // name/wildcard given: find effect by name and index if (szEffect && *szEffect) @@ -5552,7 +5552,7 @@ static std::optional FnCheckEffect(C4AulContext *ctx, C4String *psEf if (pTarget && !pTarget->Status) return {}; if (!szEffect || !*szEffect) return {}; // get effects - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return {}; // let them check return {pEffect->Check(pTarget, szEffect, iPrio, iTimerIntervall, pvVal1, pvVal2, pvVal3, pvVal4, true)}; @@ -5563,7 +5563,7 @@ static C4ValueInt FnGetEffectCount(C4AulContext *ctx, C4String *psEffectName, C4 // evaluate parameters const char *szEffect = FnStringPar(psEffectName); // get effects - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return false; // count effects if (!*szEffect) szEffect = nullptr; @@ -5575,7 +5575,7 @@ static C4Value FnEffectVar(C4AulContext *cthr, C4ValueInt iVarIndex, C4Object *p // safety if (iVarIndex < 0) return C4VNull; // get effect - C4Effect *pEffect = pObj ? pObj->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pObj ? pObj->pEffects : cthr->GetSection().GlobalEffects; if (!pEffect) return C4VNull; if (!(pEffect = pEffect->Get(iEffectNumber, true))) return C4VNull; // return ref to var @@ -5589,7 +5589,7 @@ static C4Value FnEffectCall(C4AulContext *ctx, C4Object *pTarget, C4ValueInt iNu if (pTarget && !pTarget->Status) return C4VNull; if (!szCallFn || !*szCallFn) return C4VNull; // get effect - C4Effect *pEffect = pTarget ? pTarget->pEffects : Game.pGlobalEffects; + C4Effect *pEffect = pTarget ? pTarget->pEffects : ctx->GetSection().GlobalEffects; if (!pEffect) return C4VNull; if (!(pEffect = pEffect->Get(iNumber, true))) return C4VNull; // do call @@ -5958,7 +5958,7 @@ static C4ValueInt FnActivateGameGoalMenu(C4AulContext *ctx, C4ValueInt iPlayer) C4Player *pPlr = Game.Players.Get(iPlayer); if (!pPlr) return false; // open menu - return pPlr->Menu.ActivateGoals(pPlr->Number, pPlr->LocalControl && !Game.Control.isReplay()); + return pPlr->Menu.ActivateGoals(**pPlr->ViewSection, pPlr->Number, pPlr->LocalControl && !Game.Control.isReplay()); } static void FnFatalError(C4AulContext *ctx, C4String *pErrorMsg) @@ -6038,7 +6038,7 @@ static bool FnCustomMessage(C4AulContext *ctx, C4String *pMsg, C4Object *pObj, C sMsg.Ref(szMsg); if (dwFlags & C4GM_DropSpeech) sMsg.SplitAtChar('$', nullptr); // create it! - return Game.Messages.New(iType, sMsg, pObj, iOwner, iOffX, iOffY, static_cast(dwClr), idDeco, sPortrait ? sPortrait->Data.getData() : nullptr, dwFlags, iHSize); + return Game.Messages.New(iType, sMsg, pObj ? pObj->Section : &ctx->GetSection(), pObj, iOwner, iOffX, iOffY, static_cast(dwClr), idDeco, sPortrait ? sPortrait->Data.getData() : nullptr, dwFlags, iHSize); } static void FnPauseGame(C4AulContext *ctx, bool fToggle) @@ -6176,11 +6176,9 @@ static bool FnMoveObjectToSection(C4AulContext *ctx, C4ValueInt targetSection, C return true; } -static std::optional FnGetSection(C4AulContext *ctx, C4Object *obj) +C4ValueInt FnGetSection(C4AulContext *ctx, C4Object *obj) { - if (!obj) if (!(obj = ctx->Obj)) return {}; - - return Game.GetSectionIndex(*obj->Section); + return Game.GetSectionIndex(ctx->GetSection()); } template diff --git a/src/C4ScriptHost.cpp b/src/C4ScriptHost.cpp index 2b2d12990..fdb10c0a7 100644 --- a/src/C4ScriptHost.cpp +++ b/src/C4ScriptHost.cpp @@ -97,6 +97,12 @@ int32_t C4ScriptHost::GetControlMethod(int32_t com, int32_t first, int32_t secon return ((first >> com) & 0x01) | (((second >> com) & 0x01) << 1); } +C4Value C4ScriptHost::ObjectCall(C4Object *pCaller, C4Object *pObj, const char *szFunction, const C4AulParSet &pPars, bool fPassError, bool convertNilToIntBool) +{ + if (!szFunction) return C4VNull; + return FunctionCall(*pObj->Section, pCaller, szFunction, pObj, pPars, false, fPassError, convertNilToIntBool); +} + void C4ScriptHost::GetControlMethodMask(const char *szFunctionFormat, int32_t &first, int32_t &second) { first = second = 0; @@ -119,7 +125,7 @@ void C4ScriptHost::GetControlMethodMask(const char *szFunctionFormat, int32_t &f } } -C4Value C4ScriptHost::FunctionCall(C4Object *pCaller, const char *szFunction, C4Object *pObj, const C4AulParSet &Pars, bool fPrivateCall, bool fPassError, bool convertNilToIntBool) +C4Value C4ScriptHost::FunctionCall(C4Section §ion, C4Object *pCaller, const char *szFunction, C4Object *pObj, const C4AulParSet &Pars, bool fPrivateCall, bool fPassError, bool convertNilToIntBool) { // get needed access C4AulAccess Acc = AA_PRIVATE; @@ -129,7 +135,7 @@ C4Value C4ScriptHost::FunctionCall(C4Object *pCaller, const char *szFunction, C4 C4AulScriptFunc *pFn; if (!(pFn = GetSFunc(szFunction, Acc))) return C4VNull; // Call code - return pFn->Exec(pObj, Pars, fPassError, true, convertNilToIntBool); + return pFn->Exec(section, pObj, Pars, fPassError, true, convertNilToIntBool); } bool C4ScriptHost::ReloadScript(const char *szPath) @@ -223,7 +229,7 @@ bool C4GameScriptHost::Execute() if (Go && !Tick10) { sprintf(buffer, PSF_Script, Counter++); - return static_cast(Call(buffer)); + return static_cast(Call(*Game.Sections.front(), buffer)); // FIXME } return false; } @@ -245,7 +251,7 @@ C4Value C4GameScriptHost::GRBroadcast(const char *szFunction, const C4AulParSet } } // scenario script call - return Call(szFunction, pPars, fPassError, convertNilToIntBool); + return Call(*Game.Sections.front(), szFunction, pPars, fPassError, convertNilToIntBool); // FIXME } void C4GameScriptHost::CompileFunc(StdCompiler *pComp) diff --git a/src/C4ScriptHost.h b/src/C4ScriptHost.h index c491f72c5..fc7eef7d5 100644 --- a/src/C4ScriptHost.h +++ b/src/C4ScriptHost.h @@ -40,22 +40,18 @@ class C4ScriptHost : public C4AulScript, public C4ComponentHost void GetControlMethodMask(const char *szFunctionFormat, int32_t &first, int32_t &second); int32_t GetControlMethod(int32_t com, int32_t first, int32_t second); - C4Value ObjectCall(C4Object *pCaller, C4Object *pObj, const char *szFunction, const C4AulParSet &pPars = C4AulParSet{}, bool fPassError = false, bool convertNilToIntBool = true) - { - if (!szFunction) return C4VNull; - return FunctionCall(pCaller, szFunction, pObj, pPars, false, fPassError, convertNilToIntBool); - } + C4Value ObjectCall(C4Object *pCaller, C4Object *pObj, const char *szFunction, const C4AulParSet &pPars = C4AulParSet{}, bool fPassError = false, bool convertNilToIntBool = true); - C4Value Call(const char *szFunction, const C4AulParSet &pPars = C4AulParSet{}, bool fPassError = false, bool convertNilToIntBool = true) + C4Value Call(C4Section §ion, const char *szFunction, const C4AulParSet &pPars = C4AulParSet{}, bool fPassError = false, bool convertNilToIntBool = true) { if (!szFunction) return C4VNull; - return FunctionCall(nullptr, szFunction, nullptr, pPars, false, fPassError, convertNilToIntBool); + return FunctionCall(section, nullptr, szFunction, nullptr, pPars, false, fPassError, convertNilToIntBool); } protected: class C4LangStringTable *pStringTable; void MakeScript(); - C4Value FunctionCall(C4Object *pCaller, const char *szFunction, C4Object *pObj, const C4AulParSet &pPars = C4AulParSet{}, bool fPrivateCall = false, bool fPassError = false, bool convertNilToIntBool = true); + C4Value FunctionCall(C4Section §ion, C4Object *pCaller, const char *szFunction, C4Object *pObj, const C4AulParSet &pPars = C4AulParSet{}, bool fPrivateCall = false, bool fPassError = false, bool convertNilToIntBool = true); bool ReloadScript(const char *szPath) override; }; diff --git a/src/C4Section.cpp b/src/C4Section.cpp index ee3e7766c..dcedf72e6 100644 --- a/src/C4Section.cpp +++ b/src/C4Section.cpp @@ -58,6 +58,7 @@ void C4Section::Default() C4S.Default(); PathFinder.Default(); TransferZones.Default(); + GlobalEffects = nullptr; } void C4Section::Clear() @@ -71,6 +72,8 @@ void C4Section::Clear() TextureMap.Clear(); // texture map *MUST* be cleared after the materials, because of the patterns! PathFinder.Clear(); TransferZones.Clear(); + delete GlobalEffects; + GlobalEffects = nullptr; } bool C4Section::InitSection(C4Group &scenario) @@ -174,7 +177,7 @@ bool C4Section::InitThirdPart() { for (const auto &def : Game.Defs) { - def->Script.Call(PSF_InitializeDef, {name.empty() ? C4VNull : C4VString(name.c_str())}); + def->Script.Call(*this, PSF_InitializeDef, {name.empty() ? C4VNull : C4VString(name.c_str())}); } // Environment @@ -542,6 +545,11 @@ C4Object *C4Section::PlaceAnimal(C4ID idAnimal) void C4Section::Execute() { + if (GlobalEffects) + { + GlobalEffects->Execute(nullptr); + } + Particles.GlobalParticles.Exec(*this); PXS.Execute(); MassMover.Execute(); @@ -612,6 +620,27 @@ void C4Section::ClearPointers(C4Object *const obj) Objects.ForeObjects.ClearPointers(obj); ClearObjectPtrs(obj); TransferZones.ClearPointers(obj); + + if (GlobalEffects) + { + GlobalEffects->ClearPointers(obj); + } +} + +void C4Section::EnumeratePointers() +{ + if (GlobalEffects) + { + GlobalEffects->EnumeratePointers(); + } +} + +void C4Section::DenumeratePointers() +{ + if (GlobalEffects) + { + GlobalEffects->DenumeratePointers(); + } } C4Object *C4Section::OverlapObject(const std::int32_t tx, const std::int32_t ty, const std::int32_t width, const std::int32_t height, const std::int32_t category) diff --git a/src/C4Section.h b/src/C4Section.h index 3719cf45a..f5faa2629 100644 --- a/src/C4Section.h +++ b/src/C4Section.h @@ -15,6 +15,7 @@ #pragma once +#include "C4ForwardDeclarations.h" #include "C4GameObjects.h" #include "C4Group.h" #include "C4Landscape.h" @@ -22,6 +23,7 @@ #include "C4Material.h" #include "C4Math.h" #include "C4ObjectInfo.h" +#include "C4Particles.h" #include "C4PathFinder.h" #include "C4PlayerInfo.h" #include "C4PXS.h" @@ -109,6 +111,8 @@ class C4Section void DeleteObjects(bool deleteInactive); void ClearPointers(C4Object *obj); + void EnumeratePointers(); + void DenumeratePointers(); C4Object *OverlapObject(std::int32_t tx, std::int32_t ty, std::int32_t width, std::int32_t height, std::int32_t category); @@ -267,6 +271,7 @@ class C4Section C4ParticleSystem Particles; C4PathFinder PathFinder; C4TransferZones TransferZones; + C4Effect *GlobalEffects; bool ResortAnyObject{false}; bool LandscapeLoaded{false}; diff --git a/src/C4Viewport.cpp b/src/C4Viewport.cpp index d6eeffc9b..bdb04c46b 100644 --- a/src/C4Viewport.cpp +++ b/src/C4Viewport.cpp @@ -114,7 +114,7 @@ LRESULT APIENTRY C4ViewportWindow::WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, break; case WM_USER_DROPDEF: - Game.DropDef(lParam, cvp->ViewX + static_cast(LOWORD(wParam) / scale), cvp->ViewY + static_cast(HIWORD(wParam) / scale)); + Game.DropDef(cvp->GetViewSection(), lParam, cvp->ViewX + static_cast(LOWORD(wParam) / scale), cvp->ViewY + static_cast(HIWORD(wParam) / scale)); break; case WM_SIZE: @@ -238,7 +238,7 @@ bool C4Viewport::DropFiles(HANDLE hDrop) { DragQueryFile((HDROP)hDrop, cnt, szFilename, 500); DragQueryPoint((HDROP)hDrop, &pntPoint); - Game.DropFile(szFilename, ViewX + pntPoint.x, ViewY + pntPoint.y); + Game.DropFile(GetViewSection(), szFilename, ViewX + pntPoint.x, ViewY + pntPoint.y); } DragFinish((HDROP)hDrop); return true; diff --git a/src/C4Wrappers.cpp b/src/C4Wrappers.cpp index 626f10744..63934bfe3 100644 --- a/src/C4Wrappers.cpp +++ b/src/C4Wrappers.cpp @@ -30,27 +30,27 @@ void GameMsgObject(const char *szText, C4Object *pTarget, int32_t iFCol) { - Game.Messages.New(C4GM_Target, szText, pTarget, NO_OWNER, 0, 0, static_cast(iFCol)); + Game.Messages.New(C4GM_Target, szText, pTarget->Section, pTarget, NO_OWNER, 0, 0, static_cast(iFCol)); } void GameMsgObjectPlayer(const char *szText, C4Object *pTarget, int32_t iPlayer, int32_t iFCol) { - Game.Messages.New(C4GM_TargetPlayer, szText, pTarget, iPlayer, 0, 0, static_cast(iFCol)); + Game.Messages.New(C4GM_TargetPlayer, szText, pTarget->Section, pTarget, iPlayer, 0, 0, static_cast(iFCol)); } void GameMsgGlobal(const char *szText, int32_t iFCol) { - Game.Messages.New(C4GM_Global, szText, nullptr, ANY_OWNER, 0, 0, static_cast(iFCol)); + Game.Messages.New(C4GM_Global, szText, nullptr, nullptr, ANY_OWNER, 0, 0, static_cast(iFCol)); } void GameMsgPlayer(const char *szText, int32_t iPlayer, int32_t iFCol) { - Game.Messages.New(C4GM_GlobalPlayer, szText, nullptr, iPlayer, 0, 0, static_cast(iFCol)); + Game.Messages.New(C4GM_GlobalPlayer, szText, nullptr, nullptr, iPlayer, 0, 0, static_cast(iFCol)); } void GameMsgObjectDw(const char *szText, C4Object *pTarget, uint32_t dwClr) { - Game.Messages.New(C4GM_Target, szText, pTarget, NO_OWNER, 0, 0, dwClr); + Game.Messages.New(C4GM_Target, szText, pTarget->Section, pTarget, NO_OWNER, 0, 0, dwClr); } // Players