openclonk/src/script/C4ScriptHost.cpp

238 lines
6.4 KiB
C++
Raw Normal View History

2009-05-08 13:28:41 +00:00
/*
* 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
2011-09-01 14:58:52 +00:00
* Copyright (c) 2006-2007, 2009, 2011 Günther Brammer
* Copyright (c) 2009 Nicolas Hake
2009-05-08 13:28:41 +00:00
* 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 <C4Include.h>
#include <C4ScriptHost.h>
#include <C4ObjectCom.h>
#include <C4Object.h>
#include <C4Game.h>
#include <C4GameObjects.h>
#include <C4Components.h>
#include <C4Config.h>
2009-05-08 13:28:41 +00:00
/*--- C4ScriptHost ---*/
C4ScriptHost::C4ScriptHost()
{
Script = NULL;
Code.clear();
LastCode = NULL;
stringTable = 0;
SourceScripts.push_back(this);
}
2009-05-08 13:28:41 +00:00
C4ScriptHost::~C4ScriptHost() { Clear(); }
void C4ScriptHost::Clear()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
C4AulScript::Clear();
ComponentHost.Clear();
Script.Clear();
ClearCode();
SourceScripts.clear();
SourceScripts.push_back(this);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename,
const char *szLanguage, class C4LangStringTable *pLocalTable)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Base load
bool fSuccess = ComponentHost.Load(hGroup,szFilename,szLanguage);
2009-05-08 13:28:41 +00:00
// String Table
stringTable = pLocalTable;
2009-05-08 13:28:41 +00:00
// set name
ScriptName.Ref(ComponentHost.GetFilePath());
2009-05-08 13:28:41 +00:00
// preparse script
MakeScript();
// Success
return fSuccess;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ScriptHost::MakeScript()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// clear prev
Script.Clear();
// create script
if (stringTable)
2009-05-08 13:28:41 +00:00
{
stringTable->ReplaceStrings(ComponentHost.GetDataBuf(), Script);
2009-05-08 13:28:41 +00:00
}
else
{
Script.Ref(ComponentHost.GetDataBuf());
2009-05-08 13:28:41 +00:00
}
// preparse script
Preparse();
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4ScriptHost::ReloadScript(const char *szPath, const char *szLanguage)
2010-03-28 18:58:01 +00:00
{
// this?
if (SEqualNoCase(szPath, ComponentHost.GetFilePath()) || (stringTable && SEqualNoCase(szPath, stringTable->GetFilePath())))
{
// try reload
char szParentPath[_MAX_PATH + 1]; C4Group ParentGrp;
2010-03-28 18:58:01 +00:00
if (GetParentPath(szPath, szParentPath))
if (ParentGrp.Open(szParentPath))
if (Load(ParentGrp, NULL, szLanguage, stringTable))
return true;
}
return false;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ScriptHost::SetError(const char *szMessage)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
/*--- C4ExtraScriptHost ---*/
C4ExtraScriptHost::C4ExtraScriptHost():
ParserPropList(C4PropList::NewAnon())
{
}
void C4ExtraScriptHost::Clear()
{
ParserPropList.getPropList()->Clear();
}
C4PropList * C4ExtraScriptHost::GetPropList()
{
return ParserPropList.getPropList();
}
2009-05-08 13:28:41 +00:00
/*--- 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
2011-12-29 14:56:51 +00:00
if (!Def->GetPlane() && Def->Category & C4D_SortLimit)
{
int Plane; bool gotplane = true;
2011-12-29 14:56:51 +00:00
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;
}
void C4DefScriptHost::Clear()
{
if (Def) Def->TimerCall = 0;
C4ScriptHost::Clear();
}
2009-05-08 13:28:41 +00:00
void C4DefScriptHost::AfterLink()
2010-03-28 18:58:01 +00:00
{
C4ScriptHost::AfterLink();
if (Def && Def->STimerCall[0])
2010-03-28 18:58:01 +00:00
{
Def->TimerCall = Def->GetFunc(Def->STimerCall);
if (!Def->TimerCall)
DebugLogF("Error getting function \"%s\" for TimerCall of %s", Def->STimerCall, Def->id.ToString());
2010-03-28 18:58:01 +00:00
}
}
2009-05-08 13:28:41 +00:00
C4PropList * C4DefScriptHost::GetPropList() { return Def; }
2009-05-08 13:28:41 +00:00
/*--- C4GameScriptHost ---*/
C4GameScriptHost::C4GameScriptHost(): ScenPrototype(0), ScenPropList(0) { }
2009-05-08 13:28:41 +00:00
C4GameScriptHost::~C4GameScriptHost() { }
bool C4GameScriptHost::LoadScenarioScripts(C4Group &hGroup, C4LangStringTable *pLocalTable)
{
// Script
assert(ScriptEngine.GetPropList());
ScenPrototype = C4PropList::NewScen(ScriptEngine.GetPropList());
ScenPropList = C4PropList::NewScen(ScenPrototype);
::ScriptEngine.RegisterGlobalConstant("Scenario", C4VPropList(ScenPropList));
Reg2List(&ScriptEngine, &ScriptEngine);
return Load(hGroup,C4CFN_Script,Config.General.LanguageEx,pLocalTable);
}
void C4GameScriptHost::Clear()
{
delete ScenPropList; ScenPropList = 0;
delete ScenPrototype; ScenPrototype = 0;
2011-10-14 23:38:59 +00:00
C4ScriptHost::Clear();
}
void C4GameScriptHost::AfterLink()
{
C4ScriptHost::AfterLink();
ScenPrototype->Freeze();
}
C4Value C4GameScriptHost::Call(const char *szFunction, C4AulParSet *Pars, bool fPassError)
{
// FIXME: Does fPassError make sense?
return ScenPropList->Call(szFunction, Pars);
}
2009-05-08 13:28:41 +00:00
C4Value C4GameScriptHost::GRBroadcast(const char *szFunction, C4AulParSet *pPars, bool fPassError, bool fRejectTest)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// call objects first - scenario script might overwrite hostility, etc...
2011-03-05 16:36:16 +00:00
C4Value vResult = ::Objects.GRBroadcast(szFunction, pPars, fPassError, fRejectTest);
// rejection tests abort on first nonzero result
if (fRejectTest) if (!!vResult) return vResult;
2009-05-08 13:28:41 +00:00
// scenario script call
return Call(szFunction, pPars, fPassError);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4GameScriptHost GameScript;