forked from Mirrors/openclonk
Merge script branch
commit
d0d27d25f1
|
@ -785,6 +785,7 @@ set(MAPE_BASE_SOURCES
|
|||
src/lib/C4Rect.h
|
||||
src/object/C4Id.cpp
|
||||
src/object/C4Id.h
|
||||
src/script/C4ScriptStandaloneStubs.cpp
|
||||
)
|
||||
|
||||
set(MAPE_SOURCES
|
||||
|
|
|
@ -2021,9 +2021,9 @@ bool C4Game::ReloadFile(const char *szFile)
|
|||
if ((pDef = ::Definitions.GetByPath(szRelativePath)))
|
||||
return ReloadDef(pDef->id);
|
||||
// script?
|
||||
if (ScriptEngine.ReloadScript(szRelativePath, &::Definitions, Config.General.LanguageEx))
|
||||
if (ScriptEngine.ReloadScript(szRelativePath, Config.General.LanguageEx))
|
||||
{
|
||||
return true;
|
||||
ReLinkScriptEngine();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2050,6 +2050,8 @@ bool C4Game::ReloadDef(C4ID id)
|
|||
// Reload def
|
||||
if (::Definitions.Reload(pDef,C4D_Load_RX,Config.General.LanguageEx,&Application.SoundSystem))
|
||||
{
|
||||
// update script engine - this will also do include callbacks and Freeze() pDef
|
||||
ReLinkScriptEngine();
|
||||
// Success, update all concerned object faces
|
||||
// may have been done by graphics-update already - but not for objects using graphics of another def
|
||||
// better update everything :)
|
||||
|
@ -2422,6 +2424,9 @@ bool C4Game::LinkScriptEngine()
|
|||
ScriptEngine.warnCnt, (ScriptEngine.warnCnt != 1 ? "s" : ""),
|
||||
ScriptEngine.errCnt, (ScriptEngine.errCnt != 1 ? "s" : ""));
|
||||
|
||||
// update material pointers
|
||||
::MaterialMap.UpdateScriptPointers();
|
||||
|
||||
// Set name list for globals
|
||||
ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
|
||||
|
||||
|
@ -2432,6 +2437,18 @@ bool C4Game::LinkScriptEngine()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool C4Game::ReLinkScriptEngine()
|
||||
{
|
||||
::ScriptEngine.ReLink(&::Definitions);
|
||||
|
||||
// update effect pointers
|
||||
::Objects.UpdateScriptPointers();
|
||||
|
||||
// update material pointers
|
||||
::MaterialMap.UpdateScriptPointers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4Game::InitPlayers(C4ValueNumbers * numbers)
|
||||
{
|
||||
|
@ -3079,7 +3096,7 @@ bool C4Game::DoGameOver()
|
|||
// Flag, log, call
|
||||
GameOver=true;
|
||||
Log(LoadResStr("IDS_PRC_GAMEOVER"));
|
||||
::GameScript.GRBroadcast(PSF_OnGameOver);
|
||||
GRBroadcast(PSF_OnGameOver);
|
||||
// Flag all surviving players as winners
|
||||
for (C4Player *pPlayer = Players.First; pPlayer; pPlayer = pPlayer->Next)
|
||||
if (!pPlayer->Eliminated)
|
||||
|
@ -3727,6 +3744,16 @@ bool C4Game::ToggleChat()
|
|||
return C4ChatDlg::ToggleChat();
|
||||
}
|
||||
|
||||
C4Value C4Game::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 ::GameScript.Call(szFunction, pPars, fPassError);
|
||||
}
|
||||
|
||||
void C4Game::SetDefaultGamma()
|
||||
{
|
||||
// Skip this if graphics haven't been initialized yet (happens when
|
||||
|
|
|
@ -205,6 +205,7 @@ public:
|
|||
void CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner=NO_OWNER, int32_t iController=NO_OWNER, C4ValueArray *out_objects=NULL);
|
||||
C4Object *PlaceVegetation(C4PropList *def, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth, C4PropList *shape_proplist, C4PropList * out_pos_proplist);
|
||||
C4Object *PlaceAnimal(C4PropList *def);
|
||||
C4Value GRBroadcast(const char *szFunction, C4AulParSet *pPars = 0, bool fPassError=false, bool fRejectTest=false); // call function in scenario script and all goals/rules/environment objects
|
||||
|
||||
bool LoadScenarioSection(const char *szSection, DWORD dwFlags);
|
||||
|
||||
|
@ -247,6 +248,7 @@ protected:
|
|||
bool InitControl();
|
||||
bool InitScriptEngine();
|
||||
bool LinkScriptEngine();
|
||||
bool ReLinkScriptEngine();
|
||||
bool InitPlayers(C4ValueNumbers *);
|
||||
bool OpenScenario();
|
||||
bool InitDefs();
|
||||
|
|
|
@ -23,12 +23,7 @@
|
|||
|
||||
#include <C4DefList.h>
|
||||
#include <C4Object.h>
|
||||
#include <C4Random.h>
|
||||
#include <C4Game.h>
|
||||
#include <C4Landscape.h>
|
||||
#include <C4PXS.h>
|
||||
#include <C4GameObjects.h>
|
||||
#include <C4SoundSystem.h>
|
||||
|
||||
void C4Effect::AssignCallbackFunctions()
|
||||
{
|
||||
|
@ -568,66 +563,3 @@ C4ValueArray * C4Effect::GetProperties() const
|
|||
(*a)[i++] = C4VString(&::Strings.P[P_Time]);
|
||||
return a;
|
||||
}
|
||||
|
||||
// Some other, internal effects -------------------------------------------------------------
|
||||
|
||||
static int32_t GetSmokeLevel()
|
||||
{
|
||||
// just use fixed smoke level, smoke uses particles anyway
|
||||
return 150;
|
||||
}
|
||||
|
||||
static void BubbleOut(int32_t tx, int32_t ty)
|
||||
{
|
||||
// No bubbles from nowhere
|
||||
if (!GBackSemiSolid(tx,ty)) return;
|
||||
// User-defined smoke level
|
||||
int32_t SmokeLevel = GetSmokeLevel();
|
||||
// Enough bubbles out there already
|
||||
if (::Objects.ObjectCount(C4ID::Bubble) >= SmokeLevel) return;
|
||||
// Create bubble
|
||||
Game.CreateObject(C4ID::Bubble,NULL,NO_OWNER,tx,ty);
|
||||
}
|
||||
|
||||
void Splash(int32_t tx, int32_t ty, int32_t amt, C4Object *pByObj)
|
||||
{
|
||||
// Splash only if there is free space above
|
||||
if (GBackSemiSolid(tx, ty - 15)) return;
|
||||
// get back mat
|
||||
int32_t iMat = GBackMat(tx, ty);
|
||||
// check liquid
|
||||
if (MatValid(iMat))
|
||||
if (DensityLiquid(::MaterialMap.Map[iMat].Density) && ::MaterialMap.Map[iMat].Instable)
|
||||
{
|
||||
int32_t sy = ty;
|
||||
while (GBackLiquid(tx, sy) && sy > ty - 20 && sy >= 0) sy--;
|
||||
// Splash bubbles and liquid
|
||||
for (int32_t cnt=0; cnt<amt; cnt++)
|
||||
{
|
||||
int32_t bubble_x = tx+Random(16)-8;
|
||||
int32_t bubble_y = ty+Random(16)-6;
|
||||
BubbleOut(bubble_x,bubble_y);
|
||||
if (GBackLiquid(tx,ty) && !GBackSemiSolid(tx, sy))
|
||||
{
|
||||
C4Real xdir = C4REAL100(Random(151)-75);
|
||||
C4Real ydir = C4REAL100(-Random(200));
|
||||
::PXS.Create(::Landscape.ExtractMaterial(tx,ty,false),
|
||||
itofix(tx),itofix(sy),
|
||||
xdir,
|
||||
ydir);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Splash sound
|
||||
if (amt>=20)
|
||||
StartSoundEffect("Liquids::Splash2", false, 50, pByObj);
|
||||
else if (amt>1) StartSoundEffect("Liquids::Splash1", false, 50, pByObj);
|
||||
}
|
||||
|
||||
void Smoke(int32_t tx, int32_t ty, int32_t level, DWORD dwClr)
|
||||
{
|
||||
// Use scripted function (global func Smoke) to create smoke
|
||||
// Caution: This makes engine internal smoking a synced call.
|
||||
C4AulParSet pars(C4VInt(tx), C4VInt(ty), C4VInt(level), C4VInt(dwClr));
|
||||
::ScriptEngine.GetPropList()->Call(P_Smoke, &pars);
|
||||
}
|
||||
|
|
|
@ -146,8 +146,4 @@ protected:
|
|||
#define C4Fx_FirePriority 100
|
||||
#define C4Fx_FireTimer 1
|
||||
|
||||
// some other hardcoded engine effects
|
||||
void Splash(int32_t tx, int32_t ty, int32_t amt, C4Object *pByObj);
|
||||
void Smoke(int32_t tx, int32_t ty, int32_t level, DWORD dwClr=0);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -790,14 +790,14 @@ static bool FnSetHostility(C4PropList * _this, long iPlr, long iPlr2, bool fHost
|
|||
// do rejection test first
|
||||
if (!fNoCalls)
|
||||
{
|
||||
if (!!::GameScript.GRBroadcast(PSF_RejectHostilityChange, &C4AulParSet(C4VInt(iPlr), C4VInt(iPlr2), C4VBool(fHostile)), true, true))
|
||||
if (!!::Game.GRBroadcast(PSF_RejectHostilityChange, &C4AulParSet(C4VInt(iPlr), C4VInt(iPlr2), C4VBool(fHostile)), true, true))
|
||||
return false;
|
||||
}
|
||||
// OK; set hostility
|
||||
bool fOldHostility = ::Players.HostilityDeclared(iPlr, iPlr2);
|
||||
if (!pPlr->SetHostility(iPlr2,fHostile, fSilent)) return false;
|
||||
// calls afterwards
|
||||
::GameScript.GRBroadcast(PSF_OnHostilityChange, &C4AulParSet(C4VInt(iPlr), C4VInt(iPlr2), C4VBool(fHostile), C4VBool(fOldHostility)), true);
|
||||
::Game.GRBroadcast(PSF_OnHostilityChange, &C4AulParSet(C4VInt(iPlr), C4VInt(iPlr2), C4VBool(fHostile), C4VBool(fOldHostility)), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1348,7 +1348,7 @@ static C4Value FnGameCallEx(C4PropList * _this, C4Value * Pars)
|
|||
// copy parameters
|
||||
C4AulParSet ParSet(&Pars[1], 9);
|
||||
// Call
|
||||
return ::GameScript.GRBroadcast(fn->GetCStr(), &ParSet, true);
|
||||
return ::Game.GRBroadcast(fn->GetCStr(), &ParSet, true);
|
||||
}
|
||||
|
||||
static C4Object * FnEditCursor(C4PropList * _this)
|
||||
|
@ -2340,7 +2340,7 @@ static bool FnSetPlayerTeam(C4PropList * _this, long iPlayer, long idNewTeam, bo
|
|||
// ask script if it's allowed
|
||||
if (!fNoCalls)
|
||||
{
|
||||
if (!!::GameScript.GRBroadcast(PSF_RejectTeamSwitch, &C4AulParSet(C4VInt(iPlayer), C4VInt(idNewTeam)), true, true))
|
||||
if (!!::Game.GRBroadcast(PSF_RejectTeamSwitch, &C4AulParSet(C4VInt(iPlayer), C4VInt(idNewTeam)), true, true))
|
||||
return false;
|
||||
}
|
||||
// exit previous team
|
||||
|
@ -2373,7 +2373,7 @@ static bool FnSetPlayerTeam(C4PropList * _this, long iPlayer, long idNewTeam, bo
|
|||
}
|
||||
// do callback to reflect change in scenario
|
||||
if (!fNoCalls)
|
||||
::GameScript.GRBroadcast(PSF_OnTeamSwitch, &C4AulParSet(C4VInt(iPlayer), C4VInt(idNewTeam), C4VInt(idOldTeam)), true);
|
||||
::Game.GRBroadcast(PSF_OnTeamSwitch, &C4AulParSet(C4VInt(iPlayer), C4VInt(idNewTeam), C4VInt(idOldTeam)), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -632,6 +632,13 @@ C4MaterialReaction *C4MaterialMap::GetReaction(int32_t iPXSMat, int32_t iLandsca
|
|||
return GetReactionUnsafe(iPXSMat, iLandscapeMat);
|
||||
}
|
||||
|
||||
static void Smoke(int32_t tx, int32_t ty, int32_t level)
|
||||
{
|
||||
// Use scripted function (global func Smoke) to create smoke
|
||||
// Caution: This makes engine internal smoking a synced call.
|
||||
C4AulParSet pars(C4VInt(tx), C4VInt(ty), C4VInt(level));
|
||||
::ScriptEngine.GetPropList()->Call(P_Smoke, &pars);
|
||||
}
|
||||
|
||||
bool mrfInsertCheck(int32_t &iX, int32_t &iY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, bool *pfPosChanged)
|
||||
{
|
||||
|
|
|
@ -118,3 +118,5 @@ bool C4Def::Load(C4Group& hGroup, StdMeshSkeletonLoader& loader, DWORD dwLoadWha
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
C4DefList Definitions;
|
||||
|
|
|
@ -31,45 +31,15 @@
|
|||
#include "C4TextureShape.h"
|
||||
|
||||
/* This file implements stubs for the parts of the engine that are not used
|
||||
* by mape. It also instantiates global variables required by mape that are
|
||||
* not instantiated elsewhere. In particular, we avoid C4Globals.cpp. */
|
||||
* by mape. */
|
||||
|
||||
/* These are actually used by mape: */
|
||||
#ifdef _DEBUG
|
||||
C4Set<C4PropList *> C4PropList::PropLists;
|
||||
#endif
|
||||
C4Set<C4PropListNumbered *> C4PropListNumbered::PropLists;
|
||||
C4Set<C4PropListScript *> C4PropListScript::PropLists;
|
||||
std::vector<C4PropListNumbered *> C4PropListNumbered::ShelvedPropLists;
|
||||
int32_t C4PropListNumbered::EnumerationIndex = 0;
|
||||
C4StringTable Strings;
|
||||
C4AulScriptEngine ScriptEngine;
|
||||
C4DefList Definitions;
|
||||
|
||||
/* These are just stubs used by dead code: */
|
||||
C4Landscape Landscape;
|
||||
C4PXSSystem PXS;
|
||||
C4Config Config;
|
||||
C4GameObjects Objects;
|
||||
C4Reloc Reloc;
|
||||
class C4Draw *pDraw = NULL;
|
||||
|
||||
bool EraseItemSafe(const char *szFilename) {return false;}
|
||||
void Smoke(int32_t tx, int32_t ty, int32_t level, DWORD dwClr) {}
|
||||
class C4SoundInstance *StartSoundEffectAt(const char *, int32_t, int32_t, int32_t, int32_t, int32_t, class C4SoundModifier *) { return NULL; }
|
||||
|
||||
C4Config::C4Config() {}
|
||||
C4Config::~C4Config() {}
|
||||
const char* C4Config::AtTempPath(const char *) { return NULL; }
|
||||
const char* C4Config::AtRelativePath(char const* s) {return s;}
|
||||
bool C4Reloc::Open(C4Group&, char const*) const {return false;}
|
||||
|
||||
bool C4Draw::TextOut(const char *, CStdFont &, float, C4Surface *, float, float, DWORD, BYTE, bool) { return false; }
|
||||
|
||||
C4Facet::C4Facet() {}
|
||||
void C4Facet::Set(C4Surface*, float, float, float, float) {}
|
||||
int32_t C4Facet::GetSectionCount() { return 0; }
|
||||
C4Facet C4Facet::TruncateSection(int32_t) { return *this; }
|
||||
|
||||
C4Surface::C4Surface() {}
|
||||
C4Surface::~C4Surface() {}
|
||||
|
@ -101,9 +71,6 @@ C4IDListChunk::~C4IDListChunk() {}
|
|||
C4DefGraphics::C4DefGraphics(C4Def*) {}
|
||||
void C4DefGraphics::Clear() {}
|
||||
|
||||
void C4Def::IncludeDefinition(C4Def*) {}
|
||||
|
||||
void C4DefList::Draw(C4ID, C4Facet &, bool, int32_t) {}
|
||||
void C4DefList::CallEveryDefinition() {}
|
||||
void C4DefList::ResetIncludeDependencies() {}
|
||||
bool C4DefList::DrawFontImage(const char* szImageTag, C4Facet& rTarget, C4DrawTransform* pTransform) { return false; }
|
||||
|
@ -121,82 +88,11 @@ void C4Landscape::CheckInstabilityRange(int32_t, int32_t) {}
|
|||
void C4Sky::Default() {}
|
||||
C4Sky::~C4Sky() {}
|
||||
|
||||
void C4LSector::Clear() {}
|
||||
|
||||
C4ObjectList::C4ObjectList() {}
|
||||
C4ObjectList::~C4ObjectList() {}
|
||||
void C4ObjectList::Default() {}
|
||||
void C4ObjectList::Clear() {}
|
||||
void C4ObjectList::InsertLinkBefore(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4ObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4ObjectList::RemoveLink(C4ObjectLink*) {}
|
||||
bool C4ObjectList::Add(C4Object*, C4ObjectList::SortType, C4ObjectList*) {return 0;}
|
||||
bool C4ObjectList::Remove(C4Object*) {return 0;}
|
||||
bool C4ObjectList::AssignInfo() {return 0;}
|
||||
bool C4ObjectList::ValidateOwners() {return 0;}
|
||||
|
||||
void C4NotifyingObjectList::InsertLinkBefore(C4ObjectLink *pLink, C4ObjectLink *pBefore) {}
|
||||
void C4NotifyingObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4NotifyingObjectList::RemoveLink(C4ObjectLink*) {}
|
||||
|
||||
C4GameObjects::C4GameObjects() {}
|
||||
C4GameObjects::~C4GameObjects() {}
|
||||
void C4GameObjects::Clear(bool) {}
|
||||
void C4GameObjects::Default() {}
|
||||
bool C4GameObjects::Remove(C4Object*) {return 0;}
|
||||
bool C4GameObjects::AssignInfo() {return 0;}
|
||||
bool C4GameObjects::ValidateOwners() {return 0;}
|
||||
C4Object * C4GameObjects::ObjectPointer(int) {return 0;}
|
||||
void C4GameObjects::UpdateScriptPointers() {}
|
||||
C4Value C4GameObjects::GRBroadcast(char const*, C4AulParSet*, bool, bool) {return C4Value();}
|
||||
|
||||
C4PXSSystem::C4PXSSystem() {}
|
||||
C4PXSSystem::~C4PXSSystem() {}
|
||||
bool C4PXSSystem::Create(int, C4Real, C4Real, C4Real, C4Real) { return false; }
|
||||
|
||||
void AddDbgRec(C4RecordChunkType, const void *, int) {}
|
||||
|
||||
bool C4TextureShape::Load(C4Group &group, const char *filename, int32_t base_tex_wdt, int32_t base_tex_hgt) { return true; }
|
||||
|
||||
#if 0
|
||||
/* Pulled in by C4Game... */
|
||||
CStdFont::CStdFont() {}
|
||||
C4PathFinder::C4PathFinder() {}
|
||||
C4PathFinder::~C4PathFinder() {}
|
||||
C4TransferZones::C4TransferZones() {}
|
||||
C4TransferZones::~C4TransferZones() {}
|
||||
C4PacketBase::C4PacketBase() {}
|
||||
C4PacketList::C4PacketList() {}
|
||||
C4PacketBase::~C4PacketBase() {}
|
||||
C4PacketList::~C4PacketList() {}
|
||||
C4Control::C4Control() {}
|
||||
C4Control::~C4Control() {}
|
||||
C4GameControl::C4GameControl(): Network(this) {}
|
||||
C4GameControl::~C4GameControl() {}
|
||||
C4GameControlNetwork::C4GameControlNetwork(C4GameControl*): pParent(NULL) {}
|
||||
C4GameControlNetwork::~C4GameControlNetwork() {}
|
||||
C4GraphicsResource::C4GraphicsResource(): CaptionFont(FontCaption), TitleFont(FontTitle), TextFont(FontRegular), MiniFont(FontTiny), TooltipFont(FontTooltip) {}
|
||||
C4GraphicsResource::~C4GraphicsResource() {}
|
||||
C4GameParameters::C4GameParameters() {}
|
||||
C4GameParameters::~C4GameParameters() {}
|
||||
|
||||
//C4Extra::C4Extra() {}
|
||||
//C4Extra::~C4Extra() {}
|
||||
void C4Extra::Clear() {}
|
||||
|
||||
static C4KeyboardInput KeyboardInput;
|
||||
void C4KeyboardInput::Clear() {}
|
||||
bool C4KeyboardInput::IsValid = false;
|
||||
C4KeyboardInput &C4KeyboardInput_Init() { return KeyboardInput; }
|
||||
|
||||
static C4GameParameters GameParameters;
|
||||
static C4RoundResults GameRoundResults;
|
||||
C4Game::C4Game(): Parameters(GameParameters), Clients(Parameters.Clients), Teams(Parameters.Teams), PlayerInfos(Parameters.PlayerInfos), RestorePlayerInfos(Parameters.RestorePlayerInfos), RoundResults(GameRoundResults), Input(Control.Input), KeyboardInput(C4KeyboardInput_Init()) {}
|
||||
C4Game::~C4Game() {}
|
||||
#endif
|
||||
|
||||
C4AulDebug *C4AulDebug::pDebug;
|
||||
void C4AulDebug::DebugStep(C4AulBCC*, C4Value*) {}
|
||||
|
||||
C4Shader::C4Shader() {}
|
||||
C4Shader::~C4Shader() {}
|
||||
|
|
|
@ -406,8 +406,6 @@ bool C4DefList::Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4
|
|||
BuildTable();
|
||||
// handle skeleton appends and includes
|
||||
AppendAndIncludeSkeletons();
|
||||
// update script engine - this will also do include callbacks and Freeze() this
|
||||
::ScriptEngine.ReLink(this);
|
||||
// restore graphics
|
||||
GfxBackup.AssignUpdate();
|
||||
// Success
|
||||
|
|
|
@ -435,8 +435,8 @@ void C4Object::DoMovement()
|
|||
{
|
||||
if (!InLiquid) // Enter liquid
|
||||
{
|
||||
if (OCF & OCF_HitSpeed2) if (Mass>3)
|
||||
Splash(GetX(),GetY()+1,std::min(Shape.Wdt*Shape.Hgt/10,20),this);
|
||||
if (OCF & OCF_HitSpeed2)
|
||||
if (Mass>3) Splash();
|
||||
fNoAttach=false;
|
||||
InLiquid=1;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <C4Effect.h>
|
||||
#include <C4ObjectInfo.h>
|
||||
#include <C4Physics.h>
|
||||
#include <C4PXS.h>
|
||||
#include <C4ObjectCom.h>
|
||||
#include <C4Command.h>
|
||||
#include <C4Viewport.h>
|
||||
|
@ -1151,7 +1152,7 @@ void C4Object::AssignDeath(bool fForced)
|
|||
// Now, it is done for every crew member)
|
||||
if(pPlr)
|
||||
if(!pPlr->Crew.ObjectCount())
|
||||
::GameScript.GRBroadcast(PSF_RelaunchPlayer,
|
||||
::Game.GRBroadcast(PSF_RelaunchPlayer,
|
||||
&C4AulParSet(C4VInt(Owner),C4VInt(iDeathCausingPlayer),Status ? C4VObj(this) : C4VNull));
|
||||
if (pInfo)
|
||||
pInfo->HasDied = false;
|
||||
|
@ -4783,6 +4784,53 @@ bool C4Object::AdjustWalkRotation(int32_t iRangeX, int32_t iRangeY, int32_t iSpe
|
|||
return true;
|
||||
}
|
||||
|
||||
static void BubbleOut(int32_t tx, int32_t ty)
|
||||
{
|
||||
// No bubbles from nowhere
|
||||
if (!GBackSemiSolid(tx,ty)) return;
|
||||
// Enough bubbles out there already
|
||||
if (::Objects.ObjectCount(C4ID::Bubble) >= 150) return;
|
||||
// Create bubble
|
||||
Game.CreateObject(C4ID::Bubble,NULL,NO_OWNER,tx,ty);
|
||||
}
|
||||
|
||||
void C4Object::Splash()
|
||||
{
|
||||
int32_t tx = GetX(); int32_t ty = GetY()+1;
|
||||
int32_t amt = std::min(Shape.Wdt*Shape.Hgt/10,20);
|
||||
// Splash only if there is free space above
|
||||
if (GBackSemiSolid(tx, ty - 15)) return;
|
||||
// get back mat
|
||||
int32_t iMat = GBackMat(tx, ty);
|
||||
// check liquid
|
||||
if (MatValid(iMat))
|
||||
if (DensityLiquid(::MaterialMap.Map[iMat].Density) && ::MaterialMap.Map[iMat].Instable)
|
||||
{
|
||||
int32_t sy = ty;
|
||||
while (GBackLiquid(tx, sy) && sy > ty - 20 && sy >= 0) sy--;
|
||||
// Splash bubbles and liquid
|
||||
for (int32_t cnt=0; cnt<amt; cnt++)
|
||||
{
|
||||
int32_t bubble_x = tx+Random(16)-8;
|
||||
int32_t bubble_y = ty+Random(16)-6;
|
||||
BubbleOut(bubble_x,bubble_y);
|
||||
if (GBackLiquid(tx,ty) && !GBackSemiSolid(tx, sy))
|
||||
{
|
||||
C4Real xdir = C4REAL100(Random(151)-75);
|
||||
C4Real ydir = C4REAL100(-Random(200));
|
||||
::PXS.Create(::Landscape.ExtractMaterial(tx,ty,false),
|
||||
itofix(tx),itofix(sy),
|
||||
xdir,
|
||||
ydir);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Splash sound
|
||||
if (amt>=20)
|
||||
StartSoundEffect("Liquids::Splash2", false, 50, this);
|
||||
else if (amt>1) StartSoundEffect("Liquids::Splash1", false, 50, this);
|
||||
}
|
||||
|
||||
void C4Object::UpdateInLiquid()
|
||||
{
|
||||
// InLiquid check
|
||||
|
@ -4790,8 +4838,8 @@ void C4Object::UpdateInLiquid()
|
|||
{
|
||||
if (!InLiquid) // Enter liquid
|
||||
{
|
||||
if (OCF & OCF_HitSpeed2) if (Mass>3)
|
||||
Splash(GetX(),GetY()+1,std::min(Shape.Wdt*Shape.Hgt/10,20),this);
|
||||
if (OCF & OCF_HitSpeed2)
|
||||
if (Mass>3) Splash();
|
||||
InLiquid=1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ class C4Object: public C4PropListNumbered
|
|||
{
|
||||
private:
|
||||
void UpdateInMat();
|
||||
void Splash();
|
||||
public:
|
||||
C4Object();
|
||||
~C4Object();
|
||||
|
|
|
@ -328,7 +328,7 @@ bool C4Player::Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientNa
|
|||
{
|
||||
// player preinit: In case a team needs to be chosen first, no InitializePlayer-broadcast is done
|
||||
// this callback shall give scripters a chance to do stuff like starting an intro or enabling FoW, which might need to be done
|
||||
::GameScript.GRBroadcast(PSF_PreInitializePlayer, &C4AulParSet(C4VInt(Number)));
|
||||
::Game.GRBroadcast(PSF_PreInitializePlayer, &C4AulParSet(C4VInt(Number)));
|
||||
// direct init
|
||||
if (Status != PS_TeamSelection) if (!ScenarioInit()) return false;
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ bool C4Player::ScenarioInit()
|
|||
if (Team) SetTeamHostility();
|
||||
|
||||
// Scenario script initialization
|
||||
::GameScript.GRBroadcast(PSF_InitializePlayer, &C4AulParSet(C4VInt(Number),
|
||||
::Game.GRBroadcast(PSF_InitializePlayer, &C4AulParSet(C4VInt(Number),
|
||||
C4VInt(ptx),
|
||||
C4VInt(pty),
|
||||
C4VObj(FirstBase),
|
||||
|
@ -715,7 +715,7 @@ bool C4Player::SetWealth(int32_t iVal)
|
|||
|
||||
Wealth=Clamp<int32_t>(iVal,0,1000000000);
|
||||
|
||||
::GameScript.GRBroadcast(PSF_OnWealthChanged,&C4AulParSet(C4VInt(Number)));
|
||||
::Game.GRBroadcast(PSF_OnWealthChanged,&C4AulParSet(C4VInt(Number)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ bool C4PlayerList::Remove(C4Player *pPlr, bool fDisconnect, bool fNoCalls)
|
|||
|
||||
// inform script
|
||||
if (!fNoCalls)
|
||||
::GameScript.GRBroadcast(PSF_RemovePlayer, &C4AulParSet(C4VInt(pPlr->Number), C4VInt(pPlr->Team)));
|
||||
::Game.GRBroadcast(PSF_RemovePlayer, &C4AulParSet(C4VInt(pPlr->Number), C4VInt(pPlr->Team)));
|
||||
|
||||
// Transfer ownership of other objects to team members
|
||||
if (!fNoCalls) pPlr->NotifyOwnedObjects();
|
||||
|
|
|
@ -371,10 +371,10 @@ public:
|
|||
~C4AulScriptEngine(); // destructor
|
||||
void Clear(); // clear data
|
||||
void Link(C4DefList *rDefs); // link and parse all scripts
|
||||
void ReLink(C4DefList *rDefs); // unlink + relink and parse all scripts
|
||||
void ReLink(C4DefList *rDefs); // unlink, link and parse all scripts
|
||||
virtual C4PropListStatic * GetPropList();
|
||||
using C4AulScript::ReloadScript;
|
||||
bool ReloadScript(const char *szScript, C4DefList *pDefs, const char *szLanguage); // search script and reload + relink, if found
|
||||
bool ReloadScript(const char *szScript, const char *szLanguage); // search script and reload, if found
|
||||
C4AulFunc * GetFirstFunc(C4String * Name)
|
||||
{ return FuncLookUp.GetFirstFunc(Name); }
|
||||
C4AulFunc * GetNextSNFunc(const C4AulFunc * After)
|
||||
|
|
|
@ -79,14 +79,6 @@ public:
|
|||
inline bool IsNil() const { return true; }
|
||||
};
|
||||
|
||||
// Some functions are callable in definition context only.
|
||||
// This exception gets thrown if they are called from anywhere else.
|
||||
class NeedDefinitionContext : public C4AulExecError
|
||||
{
|
||||
public:
|
||||
NeedDefinitionContext(const char *function) : C4AulExecError(FormatString("%s: must be called from definition context", function).getData()) {}
|
||||
};
|
||||
|
||||
// Other functions are callable in object context only.
|
||||
// This exception gets thrown if they are called from anywhere else.
|
||||
class NeedObjectContext : public C4AulExecError
|
||||
|
|
|
@ -136,14 +136,11 @@ bool C4AulExec::FnLogCallStack(C4PropList * _this)
|
|||
|
||||
void C4AulExec::ClearPointers(C4Object * obj)
|
||||
{
|
||||
#if 0
|
||||
// FIXME: reactivate this code and remove the checks from Call once scripts are fixed
|
||||
for (C4AulScriptContext *pCtx = pCurCtx; pCtx >= Contexts; pCtx--)
|
||||
{
|
||||
if (pCtx->Obj == obj)
|
||||
pCtx->Obj = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
C4Value C4AulExec::Exec(C4AulScriptFunc *pSFunc, C4PropList * p, C4Value *pnPars, bool fPassErrors)
|
||||
|
|
|
@ -42,9 +42,9 @@ bool C4ScriptHost::ResolveAppends(C4DefList *rDefs)
|
|||
if (State != ASS_PREPARSED) return false;
|
||||
for (std::list<StdCopyStrBuf>::iterator a = Appends.begin(); a != Appends.end(); ++a)
|
||||
{
|
||||
if (*a != "*")
|
||||
if (*a != "*" || !rDefs)
|
||||
{
|
||||
C4Def *Def = rDefs->GetByName(*a);
|
||||
C4Def *Def = rDefs ? rDefs->GetByName(*a) : NULL;
|
||||
if (Def)
|
||||
{
|
||||
if (std::find(Def->Script.SourceScripts.begin(), Def->Script.SourceScripts.end(), GetScriptHost()) == Def->Script.SourceScripts.end())
|
||||
|
@ -93,7 +93,7 @@ bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
|
|||
// append all includes to local script
|
||||
for (std::list<StdCopyStrBuf>::reverse_iterator i = Includes.rbegin(); i != Includes.rend(); ++i)
|
||||
{
|
||||
C4Def *Def = rDefs->GetByName(*i);
|
||||
C4Def *Def = rDefs ? rDefs->GetByName(*i) : NULL;
|
||||
if (Def)
|
||||
{
|
||||
// resolve #includes in included script first (#include-chains :( )
|
||||
|
@ -180,10 +180,8 @@ void C4AulScriptEngine::Link(C4DefList *rDefs)
|
|||
// engine is always parsed (for global funcs)
|
||||
State = ASS_PARSED;
|
||||
|
||||
// update material pointers
|
||||
::MaterialMap.UpdateScriptPointers();
|
||||
|
||||
rDefs->CallEveryDefinition();
|
||||
if (rDefs)
|
||||
rDefs->CallEveryDefinition();
|
||||
|
||||
// Done modifying the proplists now
|
||||
for (C4AulScript *s = Child0; s; s = s->Next)
|
||||
|
@ -214,25 +212,14 @@ void C4AulScriptEngine::ReLink(C4DefList *rDefs)
|
|||
// display state
|
||||
LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
|
||||
lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));
|
||||
|
||||
// update effect pointers
|
||||
::Objects.UpdateScriptPointers();
|
||||
|
||||
// update material pointers
|
||||
::MaterialMap.UpdateScriptPointers();
|
||||
}
|
||||
|
||||
bool C4AulScriptEngine::ReloadScript(const char *szScript, C4DefList *pDefs, const char *szLanguage)
|
||||
bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)
|
||||
{
|
||||
C4AulScript * s;
|
||||
for (s = Child0; s; s = s->Next)
|
||||
if (s->ReloadScript(szScript, szLanguage))
|
||||
break;
|
||||
if (!s)
|
||||
return false;
|
||||
// relink
|
||||
ReLink(pDefs);
|
||||
// ok
|
||||
return true;
|
||||
return !!s;
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,7 @@ private:
|
|||
void DebugChunk();
|
||||
void RemoveLastBCC();
|
||||
C4V_Type GetLastRetType(C4V_Type to); // for warning purposes
|
||||
void DumpByteCode();
|
||||
|
||||
C4AulBCC MakeSetter(bool fLeaveValue = false); // Prepares to generate a setter for the last value that was generated
|
||||
|
||||
|
@ -697,6 +698,89 @@ static const char * GetTTName(C4AulBCCType e)
|
|||
}
|
||||
}
|
||||
|
||||
void C4AulParse::DumpByteCode()
|
||||
{
|
||||
if (DEBUG_BYTECODE_DUMP && Type == PARSER)
|
||||
{
|
||||
fprintf(stderr, "%s:\n", Fn->GetName());
|
||||
std::map<C4AulBCC *, int> labels;
|
||||
int labeln = 0;
|
||||
for (C4AulBCC *pBCC = Fn->GetCode(); pBCC->bccType != AB_EOFN; pBCC++)
|
||||
{
|
||||
switch (pBCC->bccType)
|
||||
{
|
||||
case AB_JUMP: case AB_JUMPAND: case AB_JUMPOR: case AB_JUMPNNIL: case AB_CONDN: case AB_COND:
|
||||
labels[pBCC + pBCC->Par.i] = ++labeln; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
for (C4AulBCC *pBCC = Fn->GetCode();; pBCC++)
|
||||
{
|
||||
C4AulBCCType eType = pBCC->bccType;
|
||||
if (labels.find(pBCC) != labels.end())
|
||||
fprintf(stderr, "%d:\n", labels[pBCC]);
|
||||
fprintf(stderr, "\t%d\t%s", Fn->GetLineOfCode(pBCC), GetTTName(eType));
|
||||
if (strlen(GetTTName(eType)) < 8) fprintf(stderr, " ");
|
||||
switch (eType)
|
||||
{
|
||||
case AB_FUNC:
|
||||
fprintf(stderr, "\t%s\n", pBCC->Par.f->GetName()); break;
|
||||
case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
|
||||
fprintf(stderr, "\t%s\n", pBCC->Par.s->GetCStr()); break;
|
||||
case AB_STRING:
|
||||
{
|
||||
const StdStrBuf &s = pBCC->Par.s->GetData();
|
||||
std::string es;
|
||||
std::for_each(s.getData(), s.getData() + s.getLength(), [&es](char c) {
|
||||
if (std::isgraph((unsigned char)c))
|
||||
{
|
||||
es += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\'': es.append("\\'"); break;
|
||||
case '\"': es.append("\\\""); break;
|
||||
case '\\': es.append("\\\\"); break;
|
||||
case '\a': es.append("\\a"); break;
|
||||
case '\b': es.append("\\b"); break;
|
||||
case '\f': es.append("\\f"); break;
|
||||
case '\n': es.append("\\n"); break;
|
||||
case '\r': es.append("\\r"); break;
|
||||
case '\t': es.append("\\t"); break;
|
||||
case '\v': es.append("\\v"); break;
|
||||
default:
|
||||
{
|
||||
std::stringstream hex;
|
||||
hex << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>((unsigned char)c);
|
||||
es.append(hex.str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
fprintf(stderr, "\t\"%s\"\n", es.c_str()); break;
|
||||
}
|
||||
case AB_DEBUG: case AB_NIL: case AB_RETURN:
|
||||
case AB_PAR: case AB_THIS:
|
||||
case AB_ARRAYA: case AB_ARRAYA_SET: case AB_ARRAY_SLICE: case AB_ARRAY_SLICE_SET:
|
||||
case AB_ERR: case AB_EOFN:
|
||||
assert(!pBCC->Par.X); fprintf(stderr, "\n"); break;
|
||||
case AB_CARRAY:
|
||||
fprintf(stderr, "\t%s\n", C4VArray(pBCC->Par.a).GetDataString().getData()); break;
|
||||
case AB_CPROPLIST:
|
||||
fprintf(stderr, "\t%s\n", C4VPropList(pBCC->Par.p).GetDataString().getData()); break;
|
||||
case AB_JUMP: case AB_JUMPAND: case AB_JUMPOR: case AB_JUMPNNIL: case AB_CONDN: case AB_COND:
|
||||
fprintf(stderr, "\t% -d\n", labels[pBCC + pBCC->Par.i]); break;
|
||||
default:
|
||||
fprintf(stderr, "\t% -d\n", pBCC->Par.i); break;
|
||||
}
|
||||
if (eType == AB_EOFN) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C4AulScriptFunc::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
||||
{
|
||||
// store chunk
|
||||
|
@ -1487,89 +1571,9 @@ void C4AulParse::Parse_Function()
|
|||
DebugChunk();
|
||||
AddBCC(AB_RETURN);
|
||||
}
|
||||
DumpByteCode();
|
||||
// add separator
|
||||
AddBCC(AB_EOFN);
|
||||
|
||||
// dump bytecode
|
||||
if (DEBUG_BYTECODE_DUMP && Type == PARSER)
|
||||
{
|
||||
fprintf(stderr, "%s:\n", Fn->GetName());
|
||||
std::map<C4AulBCC *, int> labels;
|
||||
int labeln = 0;
|
||||
for (C4AulBCC *pBCC = Fn->GetCode(); pBCC->bccType != AB_EOFN; pBCC++)
|
||||
{
|
||||
switch (pBCC->bccType)
|
||||
{
|
||||
case AB_JUMP: case AB_JUMPAND: case AB_JUMPOR: case AB_JUMPNNIL: case AB_CONDN: case AB_COND:
|
||||
labels[pBCC + pBCC->Par.i] = ++labeln; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
for (C4AulBCC *pBCC = Fn->GetCode();; pBCC++)
|
||||
{
|
||||
C4AulBCCType eType = pBCC->bccType;
|
||||
if (labels.find(pBCC) != labels.end())
|
||||
fprintf(stderr, "%d:\n", labels[pBCC]);
|
||||
fprintf(stderr, "\t%d\t%s", Fn->GetLineOfCode(pBCC), GetTTName(eType));
|
||||
switch (eType)
|
||||
{
|
||||
case AB_FUNC:
|
||||
fprintf(stderr, "\t%s\n", pBCC->Par.f->GetName()); break;
|
||||
case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
|
||||
fprintf(stderr, "\t%s\n", pBCC->Par.s->GetCStr()); break;
|
||||
case AB_STRING:
|
||||
{
|
||||
const StdStrBuf &s = pBCC->Par.s->GetData();
|
||||
std::string es;
|
||||
std::for_each(s.getData(), s.getData() + s.getLength(), [&es](char c) {
|
||||
if (std::isgraph((unsigned char)c))
|
||||
{
|
||||
es += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\'': es.append("\\'"); break;
|
||||
case '\"': es.append("\\\""); break;
|
||||
case '\\': es.append("\\\\"); break;
|
||||
case '\a': es.append("\\a"); break;
|
||||
case '\b': es.append("\\b"); break;
|
||||
case '\f': es.append("\\f"); break;
|
||||
case '\n': es.append("\\n"); break;
|
||||
case '\r': es.append("\\r"); break;
|
||||
case '\t': es.append("\\t"); break;
|
||||
case '\v': es.append("\\v"); break;
|
||||
default:
|
||||
{
|
||||
std::stringstream hex;
|
||||
hex << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>((unsigned char)c);
|
||||
es.append(hex.str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
fprintf(stderr, "\t\"%s\"\n", es.c_str()); break;
|
||||
}
|
||||
case AB_DEBUG: case AB_NIL: case AB_RETURN:
|
||||
case AB_PAR: case AB_THIS:
|
||||
case AB_ARRAYA: case AB_ARRAYA_SET: case AB_ARRAY_SLICE: case AB_ARRAY_SLICE_SET:
|
||||
case AB_ERR: case AB_EOFN:
|
||||
assert(!pBCC->Par.X); fprintf(stderr, "\n"); break;
|
||||
case AB_CARRAY:
|
||||
fprintf(stderr, "\t%s\n", C4VArray(pBCC->Par.a).GetDataString().getData()); break;
|
||||
case AB_CPROPLIST:
|
||||
fprintf(stderr, "\t%s\n", C4VPropList(pBCC->Par.p).GetDataString().getData()); break;
|
||||
case AB_JUMP: case AB_JUMPAND: case AB_JUMPOR: case AB_JUMPNNIL: case AB_CONDN: case AB_COND:
|
||||
fprintf(stderr, "\t%d\n", labels[pBCC + pBCC->Par.i]); break;
|
||||
default:
|
||||
fprintf(stderr, "\t%d\n", pBCC->Par.i); break;
|
||||
}
|
||||
if (eType == AB_EOFN) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not blame this function for script errors between functions
|
||||
Fn = 0;
|
||||
Shift();
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <C4ScriptHost.h>
|
||||
|
||||
#include <C4Def.h>
|
||||
#include <C4GameObjects.h>
|
||||
|
||||
/*--- C4ScriptHost ---*/
|
||||
|
||||
|
@ -280,14 +279,4 @@ C4Value C4GameScriptHost::Call(const char *szFunction, C4AulParSet *Pars, bool f
|
|||
return ScenPropList._getPropList()->Call(szFunction, Pars, fPassError);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -111,7 +111,6 @@ public:
|
|||
void Clear();
|
||||
virtual C4PropListStatic * GetPropList();
|
||||
C4Value Call(const char *szFunction, C4AulParSet *pPars=0, bool fPassError=false);
|
||||
C4Value GRBroadcast(const char *szFunction, C4AulParSet *pPars = 0, bool fPassError=false, bool fRejectTest=false); // call function in scenario script and all goals/rules/environment objects
|
||||
C4Value ScenPropList;
|
||||
C4Value ScenPrototype;
|
||||
};
|
||||
|
|
|
@ -21,8 +21,15 @@
|
|||
#include "c4group/C4Group.h"
|
||||
#include "gamescript/C4Script.h"
|
||||
#include "script/C4Aul.h"
|
||||
#include "object/C4DefList.h"
|
||||
#include "script/C4ScriptHost.h"
|
||||
#include <C4DefList.h>
|
||||
|
||||
/* StandaloneStubs.cpp is shared with mape, which has a real implementation of these */
|
||||
C4Def* C4DefList::GetByName(const StdStrBuf &) {return NULL;}
|
||||
C4Def * C4DefList::GetDef(int) {return 0;}
|
||||
int C4DefList::GetDefCount() {return 0;}
|
||||
void C4DefList::CallEveryDefinition() {}
|
||||
void C4DefList::ResetIncludeDependencies() {}
|
||||
|
||||
void InitializeC4Script()
|
||||
{
|
||||
|
@ -35,7 +42,7 @@ void InitializeC4Script()
|
|||
C4Value RunLoadedC4Script()
|
||||
{
|
||||
// Link script engine (resolve includes/appends, generate code)
|
||||
ScriptEngine.Link(&::Definitions);
|
||||
ScriptEngine.Link(NULL);
|
||||
|
||||
// Set name list for globals
|
||||
ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
|
||||
|
|
|
@ -15,18 +15,15 @@
|
|||
|
||||
#include <C4Include.h>
|
||||
|
||||
#include <C4Config.h>
|
||||
#include <C4DefList.h>
|
||||
#include <C4GameObjects.h>
|
||||
#include <C4MapScript.h>
|
||||
#include <C4Material.h>
|
||||
#include <C4Reloc.h>
|
||||
#include <C4Aul.h>
|
||||
#include <C4AulDebug.h>
|
||||
#include <C4ScriptHost.h>
|
||||
#include <C4Config.h>
|
||||
#include <C4Def.h>
|
||||
#include <C4Log.h>
|
||||
#include <C4PropList.h>
|
||||
#include <C4Record.h>
|
||||
#include <C4Reloc.h>
|
||||
|
||||
/* Parts of the ScriptEngine that are normally in C4Globals for initialization order reasons. */
|
||||
#ifdef _DEBUG
|
||||
C4Set<C4PropList *> C4PropList::PropLists;
|
||||
#endif
|
||||
|
@ -37,70 +34,18 @@ int32_t C4PropListNumbered::EnumerationIndex = 0;
|
|||
C4StringTable Strings;
|
||||
C4AulScriptEngine ScriptEngine;
|
||||
|
||||
/* Stubs */
|
||||
C4Config Config;
|
||||
C4Config::C4Config() {}
|
||||
C4Config::~C4Config() {}
|
||||
const char * C4Config::AtRelativePath(char const*s) {return s;}
|
||||
|
||||
C4DefList Definitions;
|
||||
C4DefList::C4DefList() {}
|
||||
C4DefList::~C4DefList() {}
|
||||
C4Def* C4DefList::GetByName(const StdStrBuf &) {return NULL;}
|
||||
C4Def * C4DefList::GetDef(int) {return 0;}
|
||||
int C4DefList::GetDefCount() {return 0;}
|
||||
void C4DefList::CallEveryDefinition() {}
|
||||
void C4DefList::ResetIncludeDependencies() {}
|
||||
bool C4DefList::DrawFontImage(const char* szImageTag, C4Facet& rTarget, C4DrawTransform* pTransform) { return false; }
|
||||
float C4DefList::GetFontImageAspect(const char* szImageTag) { return -1.0f; }
|
||||
|
||||
C4MaterialMap MaterialMap;
|
||||
C4MaterialMap::C4MaterialMap() {}
|
||||
C4MaterialMap::~C4MaterialMap() {}
|
||||
void C4MaterialMap::UpdateScriptPointers() {}
|
||||
|
||||
C4AulDebug *C4AulDebug::pDebug;
|
||||
void C4AulDebug::DebugStep(C4AulBCC*,C4Value*) {}
|
||||
|
||||
C4GameObjects Objects;
|
||||
C4GameObjects::C4GameObjects() {}
|
||||
C4GameObjects::~C4GameObjects() {}
|
||||
void C4GameObjects::UpdateScriptPointers() {}
|
||||
void C4GameObjects::Clear(bool) {}
|
||||
void C4GameObjects::Default() {}
|
||||
bool C4GameObjects::Remove(C4Object*) {return 0;}
|
||||
bool C4GameObjects::AssignInfo() {return 0;}
|
||||
bool C4GameObjects::ValidateOwners() {return 0;}
|
||||
C4Value C4GameObjects::GRBroadcast(char const*, C4AulParSet*, bool, bool) {return C4Value();}
|
||||
|
||||
C4ObjectList::C4ObjectList() {}
|
||||
C4ObjectList::~C4ObjectList() {}
|
||||
void C4ObjectList::Default() {}
|
||||
void C4ObjectList::Clear() {}
|
||||
void C4ObjectList::InsertLinkBefore(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4ObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4ObjectList::RemoveLink(C4ObjectLink*) {}
|
||||
bool C4ObjectList::Add(C4Object*, C4ObjectList::SortType, C4ObjectList*) {return 0;}
|
||||
bool C4ObjectList::Remove(C4Object*) {return 0;}
|
||||
bool C4ObjectList::AssignInfo() {return 0;}
|
||||
bool C4ObjectList::ValidateOwners() {return 0;}
|
||||
|
||||
void C4NotifyingObjectList::InsertLinkBefore(C4ObjectLink *pLink, C4ObjectLink *pBefore) {}
|
||||
void C4NotifyingObjectList::InsertLink(C4ObjectLink*, C4ObjectLink*) {}
|
||||
void C4NotifyingObjectList::RemoveLink(C4ObjectLink*) {}
|
||||
|
||||
C4Reloc Reloc;
|
||||
bool C4Reloc::Open(C4Group&, char const*) const { return false; }
|
||||
|
||||
void C4LSector::Clear() {}
|
||||
void C4Def::IncludeDefinition(C4Def*) {}
|
||||
bool EraseItemSafe(const char *szFilename) {return false;}
|
||||
void AddDbgRec(C4RecordChunkType, const void *, int) {}
|
||||
|
||||
C4MapScriptHost MapScript;
|
||||
C4MapScriptHost::C4MapScriptHost() {}
|
||||
C4MapScriptHost::~C4MapScriptHost() {}
|
||||
void C4MapScriptHost::Clear() {}
|
||||
C4PropListStatic *C4MapScriptHost::GetPropList() {return NULL;}
|
||||
bool C4MapScriptHost::Load(C4Group &, const char *, const char *, C4LangStringTable *) { return false; }
|
||||
bool C4MapScriptHost::LoadData(const char *, const char *, C4LangStringTable *) { return false; }
|
||||
void C4MapScriptHost::AddEngineFunctions() {}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#ifndef INC_C4Value
|
||||
#define INC_C4Value
|
||||
|
||||
#include "C4Id.h"
|
||||
#include "C4StringTable.h"
|
||||
|
||||
// C4Value type
|
||||
|
@ -107,8 +106,6 @@ public:
|
|||
C4AulFunc *_getFunction() const { return Data.Fn; }
|
||||
C4PropList *_getPropList() const { return Data.PropList; }
|
||||
|
||||
// Template versions
|
||||
|
||||
bool operator ! () const { return !GetData(); }
|
||||
inline operator const void* () const { return GetData() ? this : 0; } // To allow use of C4Value in conditions
|
||||
|
||||
|
@ -233,9 +230,6 @@ inline C4Value C4VFunction(C4AulFunc * pFn) { return C4Value(pFn); }
|
|||
C4Value C4VString(StdStrBuf strString);
|
||||
C4Value C4VString(const char *strString);
|
||||
|
||||
#define C4VFalse C4VBool(false)
|
||||
#define C4VTrue C4VBool(true)
|
||||
|
||||
extern const C4Value C4VNull;
|
||||
|
||||
// C4Values can contain data structures that have to maintain their
|
||||
|
|
|
@ -121,6 +121,7 @@ if (GTEST_FOUND AND GMOCK_FOUND)
|
|||
aul/AulMathTest.cpp
|
||||
aul/AulPredefinedFunctionTest.cpp
|
||||
../src/script/C4ScriptStandaloneStubs.cpp
|
||||
../src/script/C4ScriptStandalone.cpp
|
||||
LIBRARIES
|
||||
libmisc
|
||||
libc4script)
|
||||
|
|
|
@ -63,6 +63,6 @@ TEST_F(AulMathTest, Bug1389)
|
|||
EXPECT_EQ(C4VINT_MAX, RunExpr("-2147483648 - 1"));
|
||||
// x ± 1 ± 1 is handled differently from x ± 2, yet the result should be
|
||||
// the same.
|
||||
EXPECT_EQ(C4VTrue, RunExpr("2147483647 + 1 + 1 == 2147483647 + 2"));
|
||||
EXPECT_EQ(C4VTrue, RunExpr("-2147483648 - 1 - 1 == -2147483648 - 2"));
|
||||
EXPECT_EQ(C4Value(true), RunExpr("2147483647 + 1 + 1 == 2147483647 + 2"));
|
||||
EXPECT_EQ(C4Value(true), RunExpr("-2147483648 - 1 - 1 == -2147483648 - 2"));
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ C4Value AulTest::RunCode(const char *code, bool wrap)
|
|||
src += ">";
|
||||
|
||||
GameScript.LoadData(src.c_str(), wrapped.c_str(), NULL);
|
||||
ScriptEngine.Link(&::Definitions);
|
||||
ScriptEngine.Link(NULL);
|
||||
ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
|
||||
|
||||
return GameScript.Call("Main", nullptr, true);
|
||||
|
@ -78,8 +78,8 @@ TEST_F(AulTest, ValueReturn)
|
|||
// Make sure primitive value returns work.
|
||||
EXPECT_EQ(C4VNull, RunCode("return;"));
|
||||
EXPECT_EQ(C4VNull, RunExpr("nil"));
|
||||
EXPECT_EQ(C4VTrue, RunExpr("true"));
|
||||
EXPECT_EQ(C4VFalse, RunExpr("false"));
|
||||
EXPECT_EQ(C4Value(true), RunExpr("true"));
|
||||
EXPECT_EQ(C4Value(false), RunExpr("false"));
|
||||
EXPECT_EQ(C4VInt(42), RunExpr("42"));
|
||||
EXPECT_EQ(C4VString("Hello World!"), RunExpr("\"Hello World!\""));
|
||||
|
||||
|
@ -95,3 +95,29 @@ TEST_F(AulTest, ValueReturn)
|
|||
C4VPropList("a", C4VInt(1), "b", C4VArray()),
|
||||
RunExpr("{\"a\": 1, \"b\"=[]}"));
|
||||
}
|
||||
|
||||
TEST_F(AulTest, Loops)
|
||||
{
|
||||
EXPECT_EQ(C4VInt(5), RunCode("var i = 0; do ++i; while (i < 5); return i;"));
|
||||
EXPECT_EQ(C4VInt(5), RunCode("var i = 0; while (i < 5) ++i; return i;"));
|
||||
EXPECT_EQ(C4VInt(5), RunCode("for(var i = 0; i < 5; ++i); return i;"));
|
||||
EXPECT_EQ(C4VInt(6), RunCode("var i = 0, b; do { b = i++ >= 5; } while (!b); return i;"));
|
||||
EXPECT_EQ(C4VInt(6), RunCode("var i = 0, b; while (!b) { b = i++ >= 5; } return i;"));
|
||||
EXPECT_EQ(C4Value(), RunCode("var a = [], sum; for(var i in a) sum += i; return sum;"));
|
||||
EXPECT_EQ(C4VInt(1), RunCode("var a = [1], sum; for(var i in a) sum += i; return sum;"));
|
||||
EXPECT_EQ(C4VInt(6), RunCode("var a = [1,2,3], sum; for(var i in a) sum += i; return sum;"));
|
||||
}
|
||||
|
||||
TEST_F(AulTest, Locals)
|
||||
{
|
||||
EXPECT_EQ(C4VInt(42), RunCode("local i = 42; func Main() { return i; }", false));
|
||||
EXPECT_EQ(C4VInt(42), RunCode("local i; func Main() { i = 42; return i; }", false));
|
||||
EXPECT_EQ(C4VInt(42), RunCode("func Main() { local i = 42; return i; }", false));
|
||||
EXPECT_EQ(C4VInt(42), RunCode("local i = [42]; func Main() { return i[0]; }", false));
|
||||
EXPECT_EQ(C4VInt(42), RunCode("local p = { i = 42 }; func Main() { return p.i; }", false));
|
||||
}
|
||||
|
||||
TEST_F(AulTest, Eval)
|
||||
{
|
||||
EXPECT_EQ(C4VInt(42), RunExpr("eval(\"42\")"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue