/* * OpenClonk, http://www.openclonk.org * * Copyright (c) 1998-2000 Matthes Bender * Copyright (c) 2001-2002, 2005, 2007 Sven Eberhardt * Copyright (c) 2003-2005 Peter Wortmann * Copyright (c) 2006 Armin Burgmeier * Copyright (c) 2006-2007, 2009, 2011 Günther Brammer * Copyright (c) 2009 Nicolas Hake * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de * * Portions might be copyrighted by other authors who have contributed * to OpenClonk. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * See isc_license.txt for full license and disclaimer. * * "Clonk" is a registered trademark of Matthes Bender. * See clonk_trademark_license.txt for full license. */ /* Handles script file components (calls, inheritance, function maps) */ #include #include #include #include /*--- C4ScriptHost ---*/ C4ScriptHost::C4ScriptHost() { Script = NULL; Code.clear(); LastCode = NULL; stringTable = 0; SourceScripts.push_back(this); } C4ScriptHost::~C4ScriptHost() { Clear(); } void C4ScriptHost::Clear() { C4AulScript::Clear(); ComponentHost.Clear(); Script.Clear(); ClearCode(); SourceScripts.clear(); SourceScripts.push_back(this); } bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename, const char *szLanguage, class C4LangStringTable *pLocalTable) { // Base load bool fSuccess = ComponentHost.Load(hGroup,szFilename,szLanguage); // String Table stringTable = pLocalTable; // set name ScriptName.Ref(ComponentHost.GetFilePath()); // preparse script MakeScript(); // Success return fSuccess; } void C4ScriptHost::MakeScript() { // clear prev Script.Clear(); // create script if (stringTable) { stringTable->ReplaceStrings(ComponentHost.GetDataBuf(), Script); } else { Script.Ref(ComponentHost.GetDataBuf()); } // preparse script Preparse(); } bool C4ScriptHost::ReloadScript(const char *szPath, const char *szLanguage) { // this? if (SEqualNoCase(szPath, ComponentHost.GetFilePath()) || (stringTable && SEqualNoCase(szPath, stringTable->GetFilePath()))) { // try reload char szParentPath[_MAX_PATH + 1]; C4Group ParentGrp; if (GetParentPath(szPath, szParentPath)) if (ParentGrp.Open(szParentPath)) if (Load(ParentGrp, NULL, szLanguage, stringTable)) return true; } return false; } void C4ScriptHost::SetError(const char *szMessage) { } /*--- C4ExtraScriptHost ---*/ C4ExtraScriptHost::C4ExtraScriptHost(): ParserPropList(C4PropList::NewAnon(NULL, NULL, NULL)) { } void C4ExtraScriptHost::Clear() { ParserPropList.getPropList()->Clear(); } C4PropList * C4ExtraScriptHost::GetPropList() { return ParserPropList.getPropList(); } /*--- C4DefScriptHost ---*/ bool C4DefScriptHost::Load(C4Group & g, const char * f, const char * l, C4LangStringTable * t) { bool r = C4ScriptHost::Load(g, f, l, t); assert(Def); // Check category if (!Def->GetPlane() && Def->Category & C4D_SortLimit) { int Plane; bool gotplane = true; switch (Def->Category & C4D_SortLimit) { case C4D_StaticBack: Plane = 100; break; case C4D_Structure: Plane = C4Plane_Structure; break; case C4D_Vehicle: Plane = 300; break; case C4D_Living: Plane = 400; break; case C4D_Object: Plane = 500; break; case C4D_StaticBack | C4D_Background: Plane = -500; break; case C4D_Structure | C4D_Background: Plane = -400; break; case C4D_Vehicle | C4D_Background: Plane = -300; break; case C4D_Living | C4D_Background: Plane = -200; break; case C4D_Object | C4D_Background: Plane = -100; break; case C4D_StaticBack | C4D_Foreground: Plane = 1100; break; case C4D_Structure | C4D_Foreground: Plane = 1200; break; case C4D_Vehicle | C4D_Foreground: Plane = 1300; break; case C4D_Living | C4D_Foreground: Plane = 1400; break; case C4D_Object | C4D_Foreground: Plane = 1500; break; default: DebugLogF("WARNING: Def %s (%s) at %s has invalid category!", Def->GetName(), Def->id.ToString(), g.GetFullName().getData()); gotplane = false; break; } if (gotplane) Def->SetProperty(P_Plane, C4VInt(Plane)); } if (!Def->GetPlane()) { DebugLogF("WARNING: Def %s (%s) at %s has invalid Plane!", Def->GetName(), Def->id.ToString(), g.GetFullName().getData()); Def->SetProperty(P_Plane, C4VInt(1)); } return r; } C4PropList * C4DefScriptHost::GetPropList() { return Def; } /*--- C4GameScriptHost ---*/ C4GameScriptHost::C4GameScriptHost(): ScenPrototype(0), ScenPropList(0) { } C4GameScriptHost::~C4GameScriptHost() { } bool C4GameScriptHost::Load(C4Group & g, const char * f, const char * l, C4LangStringTable * t) { assert(ScriptEngine.GetPropList()); C4PropListStatic * pScen = C4PropList::NewAnon(NULL/*ScenPrototype*/, NULL, ::Strings.RegString("Scenario")); ScenPropList.SetPropList(pScen); ::ScriptEngine.RegisterGlobalConstant("Scenario", ScenPropList); ScenPrototype.SetPropList(C4PropList::NewAnon(ScriptEngine.GetPropList(), pScen, &::Strings.P[P_Prototype])); ScenPropList._getPropList()->SetProperty(P_Prototype, ScenPrototype); Reg2List(&ScriptEngine); return C4ScriptHost::Load(g, f, l, t); } void C4GameScriptHost::Clear() { ScenPropList.Set0(); ScenPrototype.Set0(); C4ScriptHost::Clear(); } C4Value C4GameScriptHost::Call(const char *szFunction, C4AulParSet *Pars, bool fPassError) { // FIXME: Does fPassError make sense? return ScenPropList._getPropList()->Call(szFunction, Pars); } C4Value C4GameScriptHost::GRBroadcast(const char *szFunction, C4AulParSet *pPars, bool fPassError, bool fRejectTest) { // call objects first - scenario script might overwrite hostility, etc... C4Value vResult = ::Objects.GRBroadcast(szFunction, pPars, fPassError, fRejectTest); // rejection tests abort on first nonzero result if (fRejectTest) if (!!vResult) return vResult; // scenario script call return Call(szFunction, pPars, fPassError); } C4GameScriptHost GameScript;