From 8eae620b116efe4c4adf7eaaf743f5a24e4df511 Mon Sep 17 00:00:00 2001 From: Matei Date: Tue, 18 Jul 2006 23:59:48 +0000 Subject: [PATCH] # More work on technologies. Techs will now apply to units created after they are researched. This was SVN commit r4143. --- source/ps/Player.h | 13 +++ source/simulation/Entity.cpp | 9 ++ source/simulation/EntityTemplate.cpp | 4 +- source/simulation/EntityTemplate.h | 1 - source/simulation/Technology.cpp | 118 +++++++++++------------ source/simulation/Technology.h | 3 + source/simulation/TechnologyCollection.h | 7 +- 7 files changed, 86 insertions(+), 69 deletions(-) diff --git a/source/ps/Player.h b/source/ps/Player.h index 2416c51cf9..2cc546b366 100644 --- a/source/ps/Player.h +++ b/source/ps/Player.h @@ -8,6 +8,7 @@ class CNetMessage; class HEntity; +class CTechnology; typedef SColour SPlayerColour; @@ -26,6 +27,8 @@ private: UpdateCallback *m_UpdateCB; void *m_UpdateCBData; + std::vector m_ActiveTechs; + virtual void Update(CStrW name, ISynchedJSProperty *prop); public: @@ -59,6 +62,16 @@ public: } void SetValue(CStrW name, CStrW value); + inline void AddActiveTech(CTechnology* tech) + { + m_ActiveTechs.push_back(tech); + } + + inline const std::vector& GetActiveTechs() + { + return m_ActiveTechs; + } + // Caller frees... std::vector* GetControlledEntities(); diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index 522e090d1d..819a460699 100644 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -25,6 +25,7 @@ #include "FormationManager.h" #include "TerritoryManager.h" #include "Formation.h" +#include "TechnologyCollection.h" #include "graphics/GameView.h" #include "graphics/Sprite.h" #include "graphics/UnitManager.h" @@ -671,6 +672,14 @@ void UpdateAuras_Normal( SAura& aura, CEntity* e ) bool CEntity::Initialize() { + // Apply our player's active techs to ourselves (we do this here since m_player isn't yet set in the constructor) + const std::vector& techs = m_player->GetActiveTechs(); + for( int i=0; iapply( this ); + } + + // Dispatch the initialize script event CEventInitialize evt; if( !DispatchEvent( &evt ) ) { diff --git a/source/simulation/EntityTemplate.cpp b/source/simulation/EntityTemplate.cpp index e8610fa01a..dd3d8c41e0 100644 --- a/source/simulation/EntityTemplate.cpp +++ b/source/simulation/EntityTemplate.cpp @@ -37,8 +37,7 @@ CEntityTemplate::CEntityTemplate( CPlayer* player ) m_sectorDivs = 4; // Sentinel values for stamina and health (so scripts can check if an entity has no stamina or no HP). - m_speed=0; - m_staminaCurr = 0; + m_speed = 0; m_staminaMax = 0; m_healthMax = 0; @@ -430,7 +429,6 @@ void CEntityTemplate::ScriptingInit() AddClassProperty( L"traits.health.regen_rate", &CEntityTemplate::m_healthRegenRate ); AddClassProperty( L"traits.health.regen_start", &CEntityTemplate::m_healthRegenStart ); AddClassProperty( L"traits.health.decay_rate", &CEntityTemplate::m_healthDecayRate ); - AddClassProperty( L"traits.stamina.curr", &CEntityTemplate::m_staminaCurr ); AddClassProperty( L"traits.stamina.max", &CEntityTemplate::m_staminaMax ); AddClassProperty( L"traits.stamina.bar_height", &CEntityTemplate::m_staminaBarHeight ); AddClassProperty( L"traits.stamina.bar_size", &CEntityTemplate::m_staminaBarSize ); diff --git a/source/simulation/EntityTemplate.h b/source/simulation/EntityTemplate.h index efdfd710e5..2afe611ced 100644 --- a/source/simulation/EntityTemplate.h +++ b/source/simulation/EntityTemplate.h @@ -63,7 +63,6 @@ public: CBoundingObject::EBoundingType m_bound_type; //SP properties - float m_staminaCurr; float m_staminaMax; // HP properties diff --git a/source/simulation/Technology.cpp b/source/simulation/Technology.cpp index 7c11a0be5b..6c83a15d5c 100644 --- a/source/simulation/Technology.cpp +++ b/source/simulation/Technology.cpp @@ -300,17 +300,16 @@ bool CTechnology::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& f } bool CTechnology::isTechValid() { - if ( !m_player ) - return false; if ( m_excluded ) return false; if ( hasReqEntities() && hasReqTechs() ) return true; return false; } + bool CTechnology::hasReqEntities() { - bool ret=true; + bool ret = false; std::vector* entities = m_player->GetControlledEntities(); for ( std::vector::iterator it=m_ReqEntities.begin(); it != m_ReqEntities.end(); it++ ) { @@ -318,7 +317,7 @@ bool CTechnology::hasReqEntities() { if ( (*it2)->m_classes.IsMember(*it) ) { - ret=true; + ret = true; break; } } @@ -326,19 +325,55 @@ bool CTechnology::hasReqEntities() delete entities; return ret; } + bool CTechnology::hasReqTechs() { - bool ret=true; + bool ret = true; for ( std::vector::iterator it=m_ReqTechs.begin(); it != m_ReqTechs.end(); it++ ) { if ( !g_TechnologyCollection.getTechnology( (CStrW)*it, m_player )->isResearched() ) { - ret=false; + ret = false; break; } } return ret; } + +void CTechnology::apply( CEntity* entity ) +{ + // Find out if the unit has one of our target classes + bool ok = false; + for ( std::vector::iterator it = m_Targets.begin(); it != m_Targets.end(); it++ ) + { + if ( entity->m_classes.IsMember( *it ) ) + { + ok = true; + break; + } + } + if( !ok ) return; + + // Apply modifiers + for ( std::vector::iterator mod=m_Modifiers.begin(); mod!=m_Modifiers.end(); mod++ ) + { + jsval oldVal; + if( entity->GetProperty( g_ScriptingHost.getContext(), mod->attribute, &oldVal ) ) + { + jsval newVal = ToJSVal( ToPrimitive(oldVal) + mod->value ); + entity->SetProperty( g_ScriptingHost.GetContext(), mod->attribute, &newVal ); + } + } + + // Apply sets + for ( std::vector::iterator mod=m_Sets.begin(); mod!=m_Sets.end(); mod++ ) + { + jsval newVal = ToJSVal( mod->value ); + entity->SetProperty( g_ScriptingHost.GetContext(), mod->attribute, &newVal ); + } +} + + //JS stuff void CTechnology::ScriptingInit() @@ -368,81 +403,38 @@ void CTechnology::ScriptingInit() debug_printf("CTechnology::ScriptingInit complete"); } -jsval CTechnology::ApplyEffects( JSContext* cx, uintN argc, jsval* argv ) +jsval CTechnology::ApplyEffects( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) { - if ( argc < 2 ) - { - JS_ReportError(cx, "too few parameters for CTechnology::ApplyEffects."); - return JS_FALSE; - } if ( !isTechValid() ) - return JS_FALSE; - - bool first = ToPrimitive( argv[0] ); - bool invert = ToPrimitive( argv[1] ); - - if ( first ) { - m_effectFunction.Run( this->GetScript() ); + return JSVAL_FALSE; } // Disable any paired techs for ( std::vector::iterator it=m_Pairs.begin(); it != m_Pairs.end(); it++ ) g_TechnologyCollection.getTechnology(*it, m_player)->setExclusion(true); + + // Disable ourselves so we can't be researched twice setExclusion(true); - // Get the entities that should be affected + // Apply effects to all entities std::vector* entities = m_player->GetControlledEntities(); - std::vector entitiesAffected; for ( size_t i=0; isize(); ++i ) { - for ( std::vector::iterator it = m_Targets.begin(); it != m_Targets.end(); it++ ) - { - if ( (*entities)[i]->m_classes.IsMember( *it ) ) - { - entitiesAffected.push_back( (*entities)[i] ); - break; - } - } + apply( (*entities)[i] ); } delete entities; - - std::vector::iterator entIt; - - for ( std::vector::iterator mod=m_Modifiers.begin(); mod!=m_Modifiers.end(); mod++ ) - { - float modValue = (invert ? -mod->value : mod->value); - - for ( entIt = entitiesAffected.begin(); entIt != entitiesAffected.end(); entIt++ ) - { - CEntity* ent = *entIt; - jsval oldVal; - if( ent->GetProperty( g_ScriptingHost.getContext(), mod->attribute, &oldVal ) ) - { - jsval newVal = ToJSVal( ToPrimitive(oldVal) + modValue ); - ent->SetProperty( g_ScriptingHost.GetContext(), mod->attribute, &newVal ); - } - } - } - - if( !invert ) // can't invert Set effects, so just ignore them if invert is true - { - for ( std::vector::iterator mod=m_Sets.begin(); mod!=m_Sets.end(); mod++ ) - { - for ( entIt = entitiesAffected.begin(); entIt != entitiesAffected.end(); entIt++ ) - { - CEntity* ent = *entIt; - jsval newVal = ToJSVal( mod->value ); - ent->SetProperty( g_ScriptingHost.GetContext(), mod->attribute, &newVal ); - } - } - } - - if ( !first ) + + // Run one-time tech script + if( m_effectFunction ) { m_effectFunction.Run( this->GetScript() ); } - return JS_TRUE; + + // Add ourselves to player's researched techs + m_player->AddActiveTech( this ); + + return JSVAL_TRUE; } jsval CTechnology::IsValid( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) diff --git a/source/simulation/Technology.h b/source/simulation/Technology.h index 1a6f86037f..830bf6cbc8 100644 --- a/source/simulation/Technology.h +++ b/source/simulation/Technology.h @@ -12,6 +12,7 @@ class XMBElement; class CXeromyces; +class CEntity; class CTechnology : public CJSObject { @@ -38,6 +39,8 @@ public: jsval IsExcluded( JSContext* cx, uintN argc, jsval* argv ); inline jsval GetPlayerID( JSContext* cx, uintN argc, jsval* argv ); + void apply( CEntity* entity ); + bool isTechValid(); inline bool isResearched() { return m_researched; } diff --git a/source/simulation/TechnologyCollection.h b/source/simulation/TechnologyCollection.h index 2ad4e66ffe..85d64721eb 100644 --- a/source/simulation/TechnologyCollection.h +++ b/source/simulation/TechnologyCollection.h @@ -5,7 +5,6 @@ #ifndef TECHNOLOGY_COLLECTION_INCLUDED #define TECHNOLOGY_COLLECTION_INCLUDED -#include #include "ps/CStr.h" #include "ps/Singleton.h" #include "Technology.h" @@ -20,9 +19,13 @@ class CTechnologyCollection : public Singleton TechMap m_techs[PS_MAX_PLAYERS+1]; TechFilenameMap m_techFilenames; + public: - ~CTechnologyCollection(); + std::vector activeTechs[PS_MAX_PLAYERS+1]; + CTechnology* getTechnology( CStrW techType, CPlayer* player ); + ~CTechnologyCollection(); + int loadTechnologies(); void LoadFile( const char* path ); };