#Configurable game speed, techs, elevation attack bonus
-techs are not operational yet -set the game speed with setSimRate() in the console or in the config file under hotkey.speed.increase or hotkey.speed.decrease -made a few other small fixes This was SVN commit r3950.
This commit is contained in:
parent
19c31d97ff
commit
e4c40841b2
@ -52,10 +52,17 @@
|
||||
<Height>-1.0</Height>
|
||||
<Name></Name>
|
||||
</Rank>
|
||||
|
||||
<Flank_Penalty>
|
||||
<Sectors>6</Sectors>
|
||||
<Value>.2</Value>
|
||||
</Flank_Penalty>
|
||||
|
||||
<Elevation>
|
||||
<Rate>1.0</Rate>
|
||||
<Value>0.0</Value>
|
||||
</Elevation>
|
||||
|
||||
<Pitch>
|
||||
<Sectors>7</Sectors>
|
||||
<Value>.1</Value>
|
||||
|
@ -377,7 +377,7 @@ function performAttack( evt )
|
||||
dmg.pierce = parseInt(a.damage * a.pierce);
|
||||
}
|
||||
|
||||
// Add flank bonus
|
||||
// Add flank penalty
|
||||
if(evt.target.traits.flank_penalty)
|
||||
{
|
||||
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
|
||||
@ -403,7 +403,13 @@ function performAttackRanged( evt )
|
||||
dmg.hack = parseInt(a.damage * a.hack);
|
||||
dmg.pierce = parseInt(a.damage * a.pierce);
|
||||
|
||||
// Add flank bonus
|
||||
// Add flank penalty and elevation bonus
|
||||
var elevationBonus = (this.getHeight() - evt.target.getHeight())/this.traits.elevation.rate * this.traits.elevation.value;
|
||||
|
||||
dmg.crush += dmg.crush * elevationBonus;
|
||||
dmg.hack += dmg.hack * elevationBonus;
|
||||
dmg.pierce += dmg.pierce * elevationBonus;
|
||||
console.write( dmg.crush + "|" + dmg.hack );
|
||||
if(evt.target.traits.flank_penalty)
|
||||
{
|
||||
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
|
||||
|
@ -54,14 +54,14 @@ CSprite::~CSprite()
|
||||
|
||||
void CSprite::Render()
|
||||
{
|
||||
BeginBillboard();
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(m_translation.X, m_translation.Y, m_translation.Z);
|
||||
glScalef(m_scale.X, m_scale.Y, m_scale.Z);
|
||||
BeginBillboard();
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
ogl_tex_bind(m_texture->GetHandle());
|
||||
if ( m_texture->GetHandle() != 0 )
|
||||
ogl_tex_bind(m_texture->GetHandle());
|
||||
|
||||
glColor4fv(m_colour);
|
||||
|
||||
@ -187,7 +187,7 @@ void CSprite::SetColour(float * colour)
|
||||
m_colour[3] = colour[3];
|
||||
}
|
||||
|
||||
// should be called before any other gl calls
|
||||
//Must call glPushMatrix() before this. Should be called before any other gl calls
|
||||
void CSprite::BeginBillboard()
|
||||
{
|
||||
float newMatrix[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
@ -207,7 +207,6 @@ void CSprite::BeginBillboard()
|
||||
newMatrix[9] = currentMatrix[6];
|
||||
newMatrix[10] = currentMatrix[10];
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf(newMatrix);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,8 @@ CGame::CGame():
|
||||
m_pLocalPlayer(NULL),
|
||||
m_GameStarted(false),
|
||||
m_Paused(false),
|
||||
m_Time(0)
|
||||
m_Time(0),
|
||||
m_SimRate(1.0f)
|
||||
{
|
||||
debug_printf("CGame::CGame(): Game object CREATED; initializing..\n");
|
||||
}
|
||||
@ -139,9 +140,9 @@ void CGame::Update(double deltaTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
deltaTime *= m_SimRate;
|
||||
m_Time += deltaTime;
|
||||
|
||||
|
||||
m_Simulation->Update(deltaTime);
|
||||
|
||||
// TODO Detect game over and bring up the summary screen or something
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _ps_Game_H
|
||||
|
||||
#include "ps/Errors.h"
|
||||
|
||||
#include "maths/MathUtil.h"
|
||||
#include <vector>
|
||||
|
||||
class CWorld;
|
||||
@ -29,6 +29,7 @@ class CGame
|
||||
bool m_GameStarted;
|
||||
|
||||
float m_Time;
|
||||
float m_SimRate;
|
||||
|
||||
enum EOG
|
||||
{
|
||||
@ -92,6 +93,11 @@ public:
|
||||
inline float GetTime()
|
||||
{ return m_Time; }
|
||||
|
||||
inline void SetSimRate(float simRate)
|
||||
{ m_SimRate=clamp(simRate, 0.0f, simRate); }
|
||||
inline float GetSimRate()
|
||||
{ return m_SimRate; }
|
||||
|
||||
private:
|
||||
PSRETURN RegisterInit(CGameAttributes* pAttribs);
|
||||
|
||||
|
@ -345,8 +345,9 @@ void Render()
|
||||
PROFILE_START( "render health bars" );
|
||||
pglActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
pglActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
//Not all hardware supports 3 texture units!
|
||||
//pglActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
pglActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
|
@ -140,7 +140,9 @@ static SHotkeyInfo hotkeyInfo[] =
|
||||
{ HOTKEY_WATER_TOGGLE, "water.toggle", SDLK_q, 0 },
|
||||
{ HOTKEY_WATER_RAISE, "water.toggle", SDLK_a, 0 },
|
||||
{ HOTKEY_WATER_LOWER, "water.toggle", SDLK_z, 0 },
|
||||
{ HOTKEY_PAUSE, "pause", SDLK_PAUSE, 0 }
|
||||
{ HOTKEY_PAUSE, "pause", SDLK_PAUSE, 0 },
|
||||
{ HOTKEY_SPEED_INCREASE, "speed.increase", 0, 0 },
|
||||
{ HOTKEY_SPEED_DECREASE, "speed.decrease", 0, 0 }
|
||||
};
|
||||
|
||||
/* SDL-type ends */
|
||||
|
@ -104,6 +104,8 @@ enum
|
||||
HOTKEY_WATER_RAISE,
|
||||
HOTKEY_WATER_LOWER,
|
||||
HOTKEY_PAUSE,
|
||||
HOTKEY_SPEED_INCREASE,
|
||||
HOTKEY_SPEED_DECREASE,
|
||||
|
||||
HOTKEY_LAST,
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "ScriptGlue.h"
|
||||
#include "JSConversions.h"
|
||||
#include "GameEvents.h"
|
||||
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "graphics/MapWriter.h"
|
||||
@ -35,6 +34,7 @@
|
||||
#include "renderer/SkyManager.h"
|
||||
#include "renderer/WaterManager.h"
|
||||
#include "simulation/BaseEntityCollection.h"
|
||||
#include "simulation/BaseTechCollection.h"
|
||||
#include "simulation/Entity.h"
|
||||
#include "simulation/EntityFormation.h"
|
||||
#include "simulation/EntityHandles.h"
|
||||
@ -267,9 +267,13 @@ JSBool issueCommand( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rv
|
||||
CreateFormationMessage(messages, msg, entities[i]);
|
||||
formation->SetDuplication(true);
|
||||
entities.erase( entities.begin()+i ); //we don't want to be in two orders
|
||||
--i;
|
||||
}
|
||||
else if ( duplicate )
|
||||
{
|
||||
entities.erase( entities.begin()+i );
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +328,37 @@ JSBool isFormationLocked( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsval
|
||||
*rval = entity->GetFormation()->IsLocked() ? JS_TRUE : JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Techs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
JSBool getTechTemplate( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsval* argv, jsval* rval )
|
||||
{
|
||||
REQUIRE_MIN_PARAMS(2, getTechTemplate);
|
||||
|
||||
CStrW name = ToPrimitive<CStrW>( argv[0] );
|
||||
PS_uint playerID = (PS_uint)ToPrimitive<int>( argv[1] );
|
||||
rval = JSVAL_NULL;
|
||||
|
||||
if ( g_Game->GetPlayer(playerID) )
|
||||
{
|
||||
//The tech will now temporarily belong to this player. This will change on the next call.
|
||||
CBaseTech* tech = g_BaseTechCollection.getTemplate(name);
|
||||
if ( tech )
|
||||
{
|
||||
tech->setPlayer( g_Game->GetPlayer(playerID) );
|
||||
*rval = OBJECT_TO_JSVAL(tech->GetScript());
|
||||
}
|
||||
else
|
||||
JS_ReportError(cx, "Invalid tech template name \"%s\" passed for getTechTemplate()", name.c_str() );
|
||||
}
|
||||
else
|
||||
JS_ReportError(cx, "Invalid playerID \"%d\"passed for getTechTemplate()", playerID);
|
||||
|
||||
if ( rval )
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Events
|
||||
@ -523,6 +558,16 @@ JSBool cancelTimer( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNU
|
||||
|
||||
return( JS_TRUE );
|
||||
}
|
||||
//Set the simulation rate scalar-time becomes time * SimRate.
|
||||
//Params: rate [float] : sets SimRate
|
||||
JSBool setSimRate(JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* UNUSED(rval))
|
||||
{
|
||||
REQUIRE_MIN_PARAMS(1, setSimRate);
|
||||
REQUIRE_MAX_PARAMS(1, setSimRate);
|
||||
|
||||
g_Game->SetSimRate( ToPrimitive<float>(argv[0]) );
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1154,7 +1199,9 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
JS_FUNC(removeFromFormation, removeFromFormation, 1)
|
||||
JS_FUNC(lockEntityFormation, lockEntityFormation, 1)
|
||||
JS_FUNC(isFormationLocked, isFormationLocked, 1)
|
||||
|
||||
|
||||
//Tech
|
||||
JS_FUNC(getTechTemplate, getTechTemplate, 2)
|
||||
// Camera
|
||||
JS_FUNC(setCameraTarget, setCameraTarget, 1)
|
||||
|
||||
@ -1186,6 +1233,7 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
JS_FUNC(setInterval, setInterval, 2)
|
||||
JS_FUNC(cancelInterval, cancelInterval, 0)
|
||||
JS_FUNC(cancelTimer, cancelTimer, 0)
|
||||
JS_FUNC(setSimRate, setSimRate, 1)
|
||||
|
||||
// Game Setup
|
||||
JS_FUNC(startGame, startGame, 0)
|
||||
|
@ -57,6 +57,7 @@ CBaseEntity* CBaseEntityCollection::getTemplate( CStrW name, CPlayer* player )
|
||||
if( !newTemplate->loadXML( path ) )
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "CBaseEntityCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
|
||||
delete newTemplate;
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ CBaseFormation* CBaseFormationCollection::getTemplate( CStrW name )
|
||||
if( !newTemplate->loadXML( path ) )
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "CBaseFormationCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
|
||||
delete newTemplate;
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
|
493
source/simulation/BaseTech.cpp
Normal file
493
source/simulation/BaseTech.cpp
Normal file
@ -0,0 +1,493 @@
|
||||
#include "precompiled.h"
|
||||
#include "BaseTech.h"
|
||||
#include "BaseTechCollection.h"
|
||||
#include "EntityManager.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "scripting/ScriptingHost.h"
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
#include "ps/XML/XeroXMB.h"
|
||||
|
||||
#define LOG_CATEGORY "Techs"
|
||||
|
||||
STL_HASH_SET<CStr, CStr_hash_compare> CBaseTech::m_scriptsLoaded;
|
||||
|
||||
CBaseTech::CBaseTech()
|
||||
{
|
||||
m_researched = m_excluded=false;
|
||||
AddProperty(L"generic", &CBaseTech::m_Generic, true);
|
||||
AddProperty(L"specific", &CBaseTech::m_Specific, true);
|
||||
AddProperty(L"icon", &CBaseTech::m_Icon); //GUI might want to change this...?
|
||||
AddProperty<int>(L"icon_cell", &CBaseTech::m_IconCell);
|
||||
AddProperty(L"classes", &CBaseTech::m_Classes, true);
|
||||
AddProperty(L"history", &CBaseTech::m_History, true);
|
||||
|
||||
AddProperty<float>(L"time", &CBaseTech::m_ReqTime); //Techs may upgrade research time and cost of other techs
|
||||
AddProperty<float>(L"food", &CBaseTech::m_ReqFood);
|
||||
AddProperty<float>(L"wood", &CBaseTech::m_ReqWood);
|
||||
AddProperty<float>(L"stone", &CBaseTech::m_ReqStone);
|
||||
AddProperty<float>(L"ore", &CBaseTech::m_ReqOre);
|
||||
|
||||
m_effectFunction = NULL;
|
||||
m_JSFirst = false;
|
||||
|
||||
ONCE( ScriptingInit() );
|
||||
}
|
||||
bool CBaseTech::loadXML( CStr filename )
|
||||
{
|
||||
CXeromyces XeroFile;
|
||||
|
||||
if (XeroFile.Load(filename) != PSRETURN_OK)
|
||||
return false;
|
||||
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
|
||||
EL(tech);
|
||||
EL(id);
|
||||
EL(req);
|
||||
EL(effect);
|
||||
|
||||
#undef EL
|
||||
|
||||
XMBElement Root = XeroFile.getRoot();
|
||||
if ( Root.getNodeName() != el_tech )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: XML root was not \"Tech\" in file %s. Load failed.", filename.c_str() );
|
||||
return false;
|
||||
}
|
||||
XMBElementList RootChildren = Root.getChildNodes();
|
||||
bool ret;
|
||||
for ( int i=0; i<RootChildren.Count; ++i )
|
||||
{
|
||||
XMBElement element = RootChildren.item(i);
|
||||
int name = element.getNodeName();
|
||||
if ( name == el_id )
|
||||
ret = loadELID( element, XeroFile );
|
||||
else if ( name == el_req )
|
||||
ret = loadELReq( element, XeroFile );
|
||||
else if ( name == el_effect )
|
||||
ret = loadELEffect( element, XeroFile, filename );
|
||||
else
|
||||
continue;
|
||||
if ( !ret )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: Load failed for file %s", filename.c_str() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CBaseTech::loadELID( XMBElement ID, CXeromyces& XeroFile )
|
||||
{
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
|
||||
EL(generic);
|
||||
EL(specific);
|
||||
EL(icon);
|
||||
EL(icon_cell);
|
||||
EL(classes);
|
||||
EL(rollover);
|
||||
EL(history);
|
||||
|
||||
#undef EL
|
||||
|
||||
XMBElementList children = ID.getChildNodes();
|
||||
for ( int i=0; i<children.Count; ++i )
|
||||
{
|
||||
XMBElement element = children.item(i);
|
||||
int name = element.getNodeName();
|
||||
CStr value = CStr(element.getText());
|
||||
|
||||
if ( name == el_generic )
|
||||
m_Generic = value;
|
||||
else if ( name == el_specific )
|
||||
m_Specific = value;
|
||||
else if ( name == el_icon )
|
||||
m_Icon = value;
|
||||
else if ( name == el_icon_cell )
|
||||
m_IconCell = value.ToInt();
|
||||
else if ( name == el_classes )
|
||||
m_Classes = value;
|
||||
else if ( name == el_rollover )
|
||||
continue;
|
||||
else if ( name == el_history )
|
||||
m_History = value;
|
||||
else
|
||||
{
|
||||
const char* tagName = XeroFile.getElementString(name).c_str();
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CBaseTech::loadELReq( XMBElement Req, CXeromyces& XeroFile )
|
||||
{
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
|
||||
EL(time);
|
||||
EL(resource);
|
||||
EL(food);
|
||||
EL(tech);
|
||||
EL(stone);
|
||||
EL(ore);
|
||||
EL(wood);
|
||||
EL(entity);
|
||||
|
||||
#undef EL
|
||||
|
||||
XMBElementList children = Req.getChildNodes();
|
||||
for ( int i=0; i<children.Count; ++i )
|
||||
{
|
||||
XMBElement element = children.item(i);
|
||||
int name = element.getNodeName();
|
||||
CStr value = element.getText();
|
||||
|
||||
if ( name == el_time )
|
||||
m_ReqTime = value.ToFloat();
|
||||
else if ( name == el_resource )
|
||||
{
|
||||
XMBElementList resChildren = element.getChildNodes();
|
||||
for ( int j=0; j<resChildren.Count; ++j )
|
||||
{
|
||||
XMBElement resElement = resChildren.item(j);
|
||||
int resName = resElement.getNodeName();
|
||||
CStr resValue = CStr(resElement.getText());
|
||||
|
||||
if ( resName == el_food ) //NOT LOADED-GET CHILD NODES
|
||||
m_ReqFood = resValue.ToFloat();
|
||||
else if ( resName == el_wood )
|
||||
m_ReqWood = resValue.ToFloat();
|
||||
else if ( resName == el_stone )
|
||||
m_ReqStone = resValue.ToFloat();
|
||||
else if ( resName == el_ore )
|
||||
m_ReqOre = resValue.ToFloat();
|
||||
else
|
||||
{
|
||||
const char* tagName = XeroFile.getElementString(name).c_str();
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( name == el_entity )
|
||||
m_ReqEntities.push_back( value );
|
||||
else if ( name == el_tech )
|
||||
m_ReqTechs.push_back( value );
|
||||
else
|
||||
{
|
||||
const char* tagName = XeroFile.getElementString(name).c_str();
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& filename )
|
||||
{
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
#define AT(x) int at_##x = XeroFile.getAttributeID(#x)
|
||||
|
||||
EL(target);
|
||||
EL(pair);
|
||||
EL(modifier);
|
||||
EL(attribute);
|
||||
EL(value);
|
||||
EL(set);
|
||||
EL(script);
|
||||
EL(function);
|
||||
AT(name);
|
||||
AT(order);
|
||||
AT(file);
|
||||
|
||||
#undef EL
|
||||
#undef AT
|
||||
|
||||
XMBElementList children = effect.getChildNodes();
|
||||
for ( int i=0; i<children.Count; ++i )
|
||||
{
|
||||
XMBElement element = children.item(i);
|
||||
int name = element.getNodeName();
|
||||
CStr value = element.getText();
|
||||
|
||||
if ( name == el_target )
|
||||
m_Targets.push_back(value);
|
||||
else if ( name == el_pair )
|
||||
m_Pairs.push_back(value);
|
||||
|
||||
else if ( name == el_modifier )
|
||||
{
|
||||
XMBElementList modChildren = element.getChildNodes();
|
||||
m_Modifiers.push_back(Modifier());
|
||||
for ( int j=0; j<modChildren.Count; ++j )
|
||||
{
|
||||
XMBElement modElement = modChildren.item(j);
|
||||
CStr modValue = CStr(modElement.getText());
|
||||
|
||||
if ( modElement.getNodeName() == el_attribute)
|
||||
{
|
||||
if ( CEntity::m_AttributeTable.find( modValue ) == CEntity::m_AttributeTable.end() )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid attribute %s for modifier attribute", modValue);
|
||||
m_Modifiers.pop_back();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
m_Modifiers.back().attribute = modValue;
|
||||
}
|
||||
else if ( modElement.getNodeName() == el_value )
|
||||
m_Modifiers.back().value = modValue.ToFloat();
|
||||
else
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid tag inside \"Modifier\" tag" );
|
||||
m_Modifiers.pop_back();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( name == el_set )
|
||||
{
|
||||
XMBElementList setChildren = element.getChildNodes();
|
||||
m_Sets.push_back(Modifier());
|
||||
for ( int j=0; j<setChildren.Count; ++j )
|
||||
{
|
||||
XMBElement setElement = setChildren.item(j);
|
||||
CStr setValue = CStr(setElement.getText());
|
||||
|
||||
if ( setElement.getNodeName() == el_attribute)
|
||||
{
|
||||
if ( CEntity::m_AttributeTable.find( setValue ) == CEntity::m_AttributeTable.end() )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid attribute %s for \"set\" attribute", setValue);
|
||||
m_Sets.pop_back();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
m_Sets.back().attribute = setValue;
|
||||
}
|
||||
else if ( setElement.getNodeName() == el_value )
|
||||
m_Sets.back().value = setValue.ToFloat();
|
||||
else
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid tag inside \"Set\" tag" );
|
||||
m_Sets.pop_back();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( name == el_script )
|
||||
{
|
||||
CStr Include = element.getAttributes().getNamedItem( at_file );
|
||||
if( Include.Length() && m_scriptsLoaded.find( Include ) == m_scriptsLoaded.end() )
|
||||
{
|
||||
m_scriptsLoaded.insert( Include );
|
||||
g_ScriptingHost.RunScript( Include );
|
||||
}
|
||||
CStr Inline = element.getText();
|
||||
if( Inline.Length() )
|
||||
{
|
||||
g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.Length(), filename, element.getLineNumber() );
|
||||
}
|
||||
}
|
||||
else if ( name == el_function )
|
||||
{
|
||||
utf16string funcName = element.getAttributes().getNamedItem( at_name );
|
||||
CStr Inline = element.getText();
|
||||
//default to first
|
||||
m_JSFirst = (utf16string() == element.getAttributes().getNamedItem( at_order ));
|
||||
|
||||
if ( funcName != utf16string() )
|
||||
{
|
||||
jsval fnval;
|
||||
JSBool ret = JS_GetUCProperty( g_ScriptingHost.GetContext(), g_ScriptingHost.GetGlobalObject(), funcName.c_str(), funcName.size(), &fnval );
|
||||
debug_assert( ret );
|
||||
JSFunction* fn = JS_ValueToFunction( g_ScriptingHost.GetContext(), fnval );
|
||||
if( !fn )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech::LoadXML: Function does not exist for %hs in file %s. Load failed.", funcName.c_str(), filename.c_str() );
|
||||
return false;
|
||||
}
|
||||
m_effectFunction->SetFunction( fn );
|
||||
}
|
||||
else if ( Inline != CStr() )
|
||||
m_effectFunction->Compile( CStrW( filename ) + L"::" + (CStrW)funcName + L" (" + CStrW( element.getLineNumber() ) + L")", Inline );
|
||||
//(No error needed; scripts are optional)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* tagName = XeroFile.getElementString(name).c_str();
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CBaseTech::isTechValid()
|
||||
{
|
||||
if ( m_excluded )
|
||||
return false;
|
||||
if ( hasReqEntities() && hasReqTechs() )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool CBaseTech::hasReqEntities()
|
||||
{
|
||||
bool ret=true;
|
||||
std::vector<HEntity>* entities = m_player->GetControlledEntities();
|
||||
for ( std::vector<CStr>::iterator it=m_ReqEntities.begin(); it != m_ReqEntities.end(); it++ )
|
||||
{
|
||||
for( CEntityList::iterator it2=entities->begin(); it2 != entities->end(); it2++ )
|
||||
{
|
||||
if ( (*it2)->m_classes.IsMember(*it) )
|
||||
{
|
||||
ret=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete entities;
|
||||
return ret;
|
||||
}
|
||||
bool CBaseTech::hasReqTechs()
|
||||
{
|
||||
bool ret=false;
|
||||
for ( std::vector<CStr>::iterator it=m_ReqTechs.begin(); it != m_ReqTechs.end(); it++ )
|
||||
{
|
||||
if ( g_BaseTechCollection.getTemplate( (CStrW)*it )->isResearched() )
|
||||
{
|
||||
ret=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
//JS stuff
|
||||
|
||||
void CBaseTech::ScriptingInit()
|
||||
{
|
||||
AddMethod<jsval, &CBaseTech::ApplyEffects>( "applyEffects", 1 );
|
||||
AddMethod<jsval, &CBaseTech::IsExcluded>( "isExcluded", 0 );
|
||||
AddMethod<jsval, &CBaseTech::IsValid>( "isValid", 0 );
|
||||
AddMethod<jsval, &CBaseTech::IsResearched>( "isResearched", 0 );
|
||||
AddMethod<jsval, &CBaseTech::GetPlayerID>( "getPlayerID", 0 );
|
||||
AddMethod<jsval, &CBaseTech::IsJSFirst>( "isJSFirst", 0 );
|
||||
|
||||
CJSObject<CBaseTech>::ScriptingInit("TechTemplate");
|
||||
}
|
||||
|
||||
jsval CBaseTech::ApplyEffects( JSContext* cx, uintN argc, jsval* argv )
|
||||
{
|
||||
if ( !isTechValid() )
|
||||
return JS_FALSE;
|
||||
else if ( argc < 2 )
|
||||
{
|
||||
JS_ReportError(cx, "too few parameters for CBaseTech::ApplyEffects.");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
//Order overriding for some special case
|
||||
bool first = ToPrimitive<bool>( argv[0] );
|
||||
bool invert = ToPrimitive<bool>( argv[1] );
|
||||
|
||||
//Optional type overriding if some in some special case the script wants to modify non-floats
|
||||
CStr varType("float");
|
||||
if ( argc == 3 )
|
||||
varType = ToPrimitive<CStr>( argv[2] );
|
||||
|
||||
if ( first )
|
||||
m_effectFunction->Run( this->GetScript() );
|
||||
|
||||
//Disable other templates
|
||||
for ( std::vector<CStr>::iterator it=m_Pairs.begin(); it != m_Pairs.end(); it++ )
|
||||
g_BaseTechCollection.getTemplate(*it)->setExclusion(true);
|
||||
|
||||
std::vector<HEntity>* entities = m_player->GetControlledEntities();
|
||||
if ( entities->empty() )
|
||||
{
|
||||
delete entities;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
//Find which entities should be affected
|
||||
for ( std::vector<CStr>::iterator it = m_Targets.begin(); it != m_Targets.end(); it++ )
|
||||
{
|
||||
for ( size_t i=0; i<entities->size(); ++i )
|
||||
{
|
||||
if ( !(*entities)[i]->m_classes.IsMember( *it ) )
|
||||
entities->erase(entities->begin() + i);
|
||||
}
|
||||
}
|
||||
CEntityList::iterator HEit = entities->begin();
|
||||
for ( ; HEit != entities->end(); HEit++ )
|
||||
{
|
||||
for ( std::vector<Modifier>::iterator mod=m_Modifiers.begin(); mod!=m_Modifiers.end(); mod++ )
|
||||
{
|
||||
//Get the member corresponding to the javascript attribute string
|
||||
void* attribute = (char*)&**HEit + (*HEit)->m_AttributeTable[mod->attribute];
|
||||
float modValue = (invert ? -mod->value : mod->value);
|
||||
|
||||
if ( varType == "int" )
|
||||
*(int*)attribute += (int)modValue;
|
||||
if ( varType == "double" )
|
||||
*(double*)attribute += (double)modValue;
|
||||
else
|
||||
*(float*)attribute += (float)modValue;
|
||||
}
|
||||
}
|
||||
for ( HEit = entities->begin(); HEit != entities->end(); HEit++ )
|
||||
{
|
||||
for ( std::vector<Modifier>::iterator set=m_Sets.begin(); set!=m_Sets.end(); set++ )
|
||||
{
|
||||
//Get the member corresponding to the javascript attribute string
|
||||
void* attribute = (char*)&**HEit + (*HEit)->m_AttributeTable[set->attribute];
|
||||
float setValue = invert ? -set->value : set->value;
|
||||
|
||||
if ( varType == "int" )
|
||||
*(int*)attribute += (int)setValue;
|
||||
if ( varType == "double" )
|
||||
*(double*)attribute += (double)setValue;
|
||||
else
|
||||
*(float*)attribute += (float)setValue;
|
||||
}
|
||||
}
|
||||
if ( !first )
|
||||
m_effectFunction->Run( this->GetScript() );
|
||||
delete entities;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
jsval CBaseTech::IsValid( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
if ( isTechValid() )
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
jsval CBaseTech::IsExcluded( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
if ( m_excluded )
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
jsval CBaseTech::IsResearched( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
if ( isResearched() )
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
inline jsval CBaseTech::GetPlayerID( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
return ToJSVal( m_player->GetPlayerID() );
|
||||
}
|
||||
jsval CBaseTech::IsJSFirst( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
if ( m_JSFirst )
|
||||
return JS_TRUE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
85
source/simulation/BaseTech.h
Normal file
85
source/simulation/BaseTech.h
Normal file
@ -0,0 +1,85 @@
|
||||
//Andrew aka pyrolink
|
||||
//ajdecker1022@msn.com
|
||||
//Holds template information for technologies and research
|
||||
|
||||
#ifndef BASETECH_INCLUDED
|
||||
#define BASETECH_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include "scripting/ScriptableComplex.h"
|
||||
|
||||
class CStr;
|
||||
class XMBElement;
|
||||
class CXeromyces;
|
||||
|
||||
class CBaseTech : public CJSObject<CBaseTech>
|
||||
{
|
||||
friend class CBaseTechCollection;
|
||||
|
||||
typedef struct Modifier
|
||||
{
|
||||
CStr attribute;
|
||||
float value;
|
||||
Modifier() { value = 0; }
|
||||
};
|
||||
static STL_HASH_SET<CStr, CStr_hash_compare> m_scriptsLoaded;
|
||||
|
||||
public:
|
||||
CBaseTech();
|
||||
~CBaseTech() {}
|
||||
|
||||
//JS functions
|
||||
static void ScriptingInit();
|
||||
jsval ApplyEffects( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval IsValid( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval IsResearched( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval IsJSFirst( JSContext* cx, uintN argc, jsval* argv );
|
||||
jsval IsExcluded( JSContext* cx, uintN argc, jsval* argv );
|
||||
inline jsval GetPlayerID( JSContext* cx, uintN argc, jsval* argv );
|
||||
|
||||
|
||||
bool isTechValid();
|
||||
inline bool isResearched() { return m_researched; }
|
||||
|
||||
void setPlayer( CPlayer* player ) { m_player=player; }
|
||||
void setExclusion( bool exclude ) { m_excluded=exclude; }
|
||||
|
||||
bool loadXML( CStr filename );
|
||||
bool loadELID( XMBElement ID, CXeromyces& XeroFile );
|
||||
bool loadELReq( XMBElement Req, CXeromyces& XeroFile );
|
||||
bool loadELEffect( XMBElement Effect, CXeromyces& XeroFile, CStr& filename );
|
||||
|
||||
private:
|
||||
CStr m_Generic;
|
||||
CStr m_Specific;
|
||||
|
||||
CStr m_Icon;
|
||||
int m_IconCell;
|
||||
CStr m_Classes;
|
||||
CStr m_History;
|
||||
|
||||
float m_ReqTime;
|
||||
float m_ReqWood;
|
||||
float m_ReqFood;
|
||||
float m_ReqStone;
|
||||
float m_ReqOre;
|
||||
|
||||
std::vector<CStr> m_ReqEntities;
|
||||
std::vector<CStr> m_ReqTechs;
|
||||
std::vector<CStr> m_Pairs;
|
||||
std::vector<CStr> m_Targets;
|
||||
std::vector<Modifier> m_Modifiers;
|
||||
std::vector<Modifier> m_Sets;
|
||||
|
||||
CPlayer* m_player; //Which player this tech belongs to
|
||||
CScriptObject* m_effectFunction;
|
||||
|
||||
bool m_JSFirst; //Should JS effect function run before C++
|
||||
bool m_excluded;
|
||||
bool m_researched;
|
||||
|
||||
bool hasReqEntities();
|
||||
bool hasReqTechs();
|
||||
};
|
||||
|
||||
#endif
|
71
source/simulation/BaseTechCollection.cpp
Normal file
71
source/simulation/BaseTechCollection.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "BaseTechCollection.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/VFSUtil.h"
|
||||
|
||||
#define LOG_CATEGORY "tech"
|
||||
|
||||
void CBaseTechCollection::LoadFile( const char* path )
|
||||
{
|
||||
//Make tech file reading
|
||||
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
|
||||
m_templateFilenames[tag] = path;
|
||||
}
|
||||
|
||||
static void LoadTechThunk( const char* path, const DirEnt* UNUSED(ent), void* context )
|
||||
{
|
||||
CBaseTechCollection* this_ = (CBaseTechCollection*)context;
|
||||
this_->LoadFile(path);
|
||||
}
|
||||
|
||||
int CBaseTechCollection::loadTemplates()
|
||||
{
|
||||
// Load all files in techs/ and subdirectories.
|
||||
THROW_ERR( vfs_dir_enum( "techs/", VFS_DIR_RECURSIVE, "*.xml",
|
||||
LoadTechThunk, this ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBaseTech* CBaseTechCollection::getTemplate( CStrW name )
|
||||
{
|
||||
// Check whether this template has already been loaded.
|
||||
//If previously loaded, all slots will be found, so any entry works.
|
||||
templateMap::iterator it = m_templates.find( name );
|
||||
if( it != m_templates.end() )
|
||||
return( it->second );
|
||||
|
||||
// Find the filename corresponding to this template
|
||||
templateFilenameMap::iterator filename_it = m_templateFilenames.find( name );
|
||||
if( filename_it == m_templateFilenames.end() )
|
||||
return( NULL );
|
||||
|
||||
CStr path( filename_it->second );
|
||||
|
||||
//Try to load to the tech
|
||||
CBaseTech* newTemplate = new CBaseTech();
|
||||
if( !newTemplate->loadXML( path ) )
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "CBaseTechCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
|
||||
delete newTemplate;
|
||||
return( NULL );
|
||||
|
||||
}
|
||||
m_templates[name] = newTemplate;
|
||||
|
||||
LOG(NORMAL, LOG_CATEGORY, "CBaseTechCollection::loadTemplates(): Loaded template \"%s\"", path.c_str());
|
||||
return newTemplate;
|
||||
}
|
||||
|
||||
void CBaseTechCollection::getBaseTechNames( std::vector<CStrW>& names )
|
||||
{
|
||||
for( templateFilenameMap::iterator it = m_templateFilenames.begin(); it != m_templateFilenames.end(); ++it )
|
||||
if( ! (it->first.Length() > 8 && it->first.Left(8) == L"template"))
|
||||
names.push_back( it->first );
|
||||
}
|
||||
|
||||
CBaseTechCollection::~CBaseTechCollection()
|
||||
{
|
||||
for( templateMap::iterator it = m_templates.begin(); it != m_templates.end(); ++it )
|
||||
delete( it->second );
|
||||
}
|
34
source/simulation/BaseTechCollection.h
Normal file
34
source/simulation/BaseTechCollection.h
Normal file
@ -0,0 +1,34 @@
|
||||
//Andrew aka pyrolink - ajdecker1022@msn.com
|
||||
//Manages the tech templates. More detail: see CBaseFormation and CBaseEntity (collections)
|
||||
|
||||
|
||||
#ifndef BASETECH_COLLECTION_INCLUDED
|
||||
#define BASETECH_COLLECTION_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/Singleton.h"
|
||||
#include "BaseTech.h"
|
||||
#include "ps/Game.h"
|
||||
|
||||
#define g_BaseTechCollection CBaseTechCollection::GetSingleton()
|
||||
|
||||
class CBaseTechCollection : public Singleton<CBaseTechCollection>
|
||||
{
|
||||
|
||||
typedef std::map<CStrW, CBaseTech*> templateMap;
|
||||
typedef std::map<CStrW, CStr> templateFilenameMap;
|
||||
templateMap m_templates;
|
||||
templateFilenameMap m_templateFilenames;
|
||||
public:
|
||||
~CBaseTechCollection();
|
||||
CBaseTech* getTemplate( CStrW techType );
|
||||
int loadTemplates();
|
||||
void LoadFile( const char* path );
|
||||
|
||||
// Create a list of the names of all base techs, excluding template_*,
|
||||
// for display in ScEd's entity-selection box.
|
||||
void getBaseTechNames( std::vector<CStrW>& names );
|
||||
};
|
||||
|
||||
#endif
|
@ -32,6 +32,7 @@ extern int g_xres, g_yres;
|
||||
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
std::map<CStr, size_t> CEntity::m_AttributeTable;
|
||||
|
||||
CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation, const std::set<CStrW>& actorSelections, CStrW building )
|
||||
{
|
||||
@ -233,6 +234,61 @@ void CEntity::loadBase()
|
||||
}
|
||||
}
|
||||
|
||||
void CEntity::initAttributes(const CEntity* _this)
|
||||
{
|
||||
#define getoffset(member) \
|
||||
(size_t) ((unsigned char*)&_this->member - (unsigned char*)_this)
|
||||
|
||||
#define getoffset_action(member, mem2) \
|
||||
(size_t) ((unsigned char*)&_this->member.mem2 - (unsigned char*)_this)
|
||||
|
||||
//Add the attribute name and the variable that holds it
|
||||
CEntity::m_AttributeTable["actions.move.speed_curr"] = getoffset(m_speed);
|
||||
CEntity::m_AttributeTable["actions.move.run.speed"] = getoffset(m_runSpeed);
|
||||
CEntity::m_AttributeTable["actions.move.run.rangemin"] = getoffset_action(m_run, m_MinRange);
|
||||
CEntity::m_AttributeTable["actions.move.run.range"] = getoffset_action(m_run, m_MaxRange);
|
||||
CEntity::m_AttributeTable["actions.move.run.regen_rate"] = getoffset(m_runRegenRate);
|
||||
CEntity::m_AttributeTable["actions.move.run.decay_rate"] = getoffset(m_runDecayRate);
|
||||
CEntity::m_AttributeTable["actions.move.pass_through_allies"] = getoffset(m_passThroughAllies);
|
||||
CEntity::m_AttributeTable["traits.extant"] = getoffset(m_extant);
|
||||
CEntity::m_AttributeTable["traits.corpse"] = getoffset(m_corpse);
|
||||
CEntity::m_AttributeTable["actions.move.turningradius"] = getoffset(m_turningRadius);
|
||||
|
||||
CEntity::m_AttributeTable["traits.health.curr"] = getoffset(m_healthCurr);
|
||||
CEntity::m_AttributeTable["traits.health.max"] = getoffset(m_healthMax);
|
||||
CEntity::m_AttributeTable["traits.health.regen_rate"] = getoffset(m_healthRegenRate);
|
||||
CEntity::m_AttributeTable["traits.health.regen_start"] = getoffset(m_healthRegenStart);
|
||||
CEntity::m_AttributeTable["traits.health.decay_rate"] = getoffset(m_healthDecayRate);
|
||||
//This are not changable from techs until the updated bars are finished
|
||||
|
||||
/* CEntity::m_AttributeTable["traits.stamina.curr"] = getoffset(m_staminaCurr);
|
||||
CEntity::m_AttributeTable["traits.stamina.max"] = getoffset(m_staminaMax);
|
||||
CEntity::m_AttributeTable["traits.bars.height"] = getoffset(m_barHeight);
|
||||
CEntity::m_AttributeTable["traits.bars"] = getoffset(m_barOffset);
|
||||
CEntity::m_AttributeTable["traits.bars.width"] = getoffset(m_barWidth);
|
||||
CEntity::m_AttributeTable["traits.bars.border_height"] = getoffset(m_barBorderHeight);
|
||||
CEntity::m_AttributeTable["traits.bars.border_width"] = getoffset(m_barBorderWidth);
|
||||
CEntity::m_AttributeTable["traits.bars.border_name"] = getoffset(m_barBorderName);*/
|
||||
CEntity::m_AttributeTable["traits.flank_penalty.sectors"] = getoffset(m_sectorDivs);
|
||||
CEntity::m_AttributeTable["traits.pitch.sectors"] = getoffset(m_pitchDivs);
|
||||
CEntity::m_AttributeTable["traits.rank.width"] = getoffset(m_rankWidth);
|
||||
// CEntity::m_AttributeTable["traits.rank"] = getoffset(m_rankOffset);
|
||||
CEntity::m_AttributeTable["traits.rank.height"] = getoffset(m_rankHeight);
|
||||
CEntity::m_AttributeTable["traits.rank.name"] = getoffset(m_rankName);
|
||||
CEntity::m_AttributeTable["traits.minimap.type"] = getoffset(m_minimapType);
|
||||
CEntity::m_AttributeTable["traits.minimap.red"] = getoffset(m_minimapR);
|
||||
CEntity::m_AttributeTable["traits.minimap.green"] = getoffset(m_minimapG);
|
||||
CEntity::m_AttributeTable["traits.minimap.blue"] = getoffset(m_minimapB);
|
||||
CEntity::m_AttributeTable["traits.anchor.type"] = getoffset(m_anchorType);
|
||||
CEntity::m_AttributeTable["traits.anchor.conformx"] = getoffset(m_anchorConformX);
|
||||
CEntity::m_AttributeTable["traits.anchor.conformz"] = getoffset(m_anchorConformZ);
|
||||
CEntity::m_AttributeTable["traits.vision.los"] = getoffset(m_los);
|
||||
CEntity::m_AttributeTable["traits.vision.permanent"] = getoffset(m_permanent);
|
||||
CEntity::m_AttributeTable["last_combat_time"] = getoffset(m_lastCombatTime);
|
||||
CEntity::m_AttributeTable["last_run_time"] = getoffset(m_lastRunTime);
|
||||
CEntity::m_AttributeTable["building"] = getoffset(m_building);
|
||||
#undef getoffset
|
||||
}
|
||||
void CEntity::kill()
|
||||
{
|
||||
g_Selection.removeAll( me );
|
||||
@ -1386,6 +1442,7 @@ void CEntity::ScriptingInit()
|
||||
AddMethod<jsval, &CEntity::RegisterOrderChange>( "registerOrderChange", 0 );
|
||||
AddMethod<jsval, &CEntity::GetAttackDirections>( "getAttackDirections", 0 );
|
||||
AddMethod<jsval, &CEntity::FindSector>("findSector", 4);
|
||||
AddMethod<jsval, &CEntity::GetHeight>("getHeight", 0 );
|
||||
|
||||
AddClassProperty( L"template", (CBaseEntity* CEntity::*)&CEntity::m_base, false, (NotifyFn)&CEntity::loadBase );
|
||||
AddClassProperty( L"traits.id.classes", (GetFn)&CEntity::getClassSet, (SetFn)&CEntity::setClassSet );
|
||||
|
@ -65,6 +65,9 @@ public:
|
||||
// Intrinsic properties
|
||||
CBaseEntity* m_base;
|
||||
|
||||
//Attributes table: key=attribute, value=variable name
|
||||
static std::map<CStr, size_t> m_AttributeTable;
|
||||
|
||||
// The entity to switch to when this dies.
|
||||
CStrW m_corpse;
|
||||
|
||||
@ -90,7 +93,7 @@ public:
|
||||
float m_healthDecayRate;
|
||||
|
||||
SEntityAction m_run;
|
||||
|
||||
|
||||
ActionTable m_actions;
|
||||
|
||||
bool m_selected;
|
||||
@ -306,6 +309,7 @@ public:
|
||||
|
||||
// Reset properties after the entity-template we use changes.
|
||||
void loadBase();
|
||||
static void initAttributes(const CEntity* _this);
|
||||
|
||||
void playerChanged(); // Fixes player colour if player is changed by script
|
||||
void reorient(); // Orientation
|
||||
@ -404,7 +408,10 @@ public:
|
||||
m_orderQueue.pop_front();
|
||||
return JSVAL_VOID;
|
||||
}
|
||||
|
||||
jsval GetHeight( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
|
||||
{
|
||||
return ToJSVal(m_position.Y);
|
||||
}
|
||||
static void ScriptingInit();
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user