diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index 1c1db27c12..5092632547 100755 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -1207,8 +1207,7 @@ void CBuildingPlacer::mouseReleased() if(m_valid) { - CBaseEntity* base = g_EntityTemplateCollection.getTemplate( m_templateName ); - HEntity ent = g_EntityManager.create( base, clickPos, m_angle ); + HEntity ent = g_EntityManager.createFoundation( m_templateName, clickPos, m_angle ); ent->SetPlayer(g_Game->GetLocalPlayer()); } } diff --git a/source/scripting/EventTypes.h b/source/scripting/EventTypes.h index 8b3986314a..151dd3613c 100644 --- a/source/scripting/EventTypes.h +++ b/source/scripting/EventTypes.h @@ -11,6 +11,7 @@ enum EEventType { // Entity events EVENT_INITIALIZE = 0, + EVENT_DEATH, EVENT_TICK, EVENT_GENERIC, EVENT_START_PRODUCTION, @@ -37,6 +38,7 @@ enum EEventType static const wchar_t* const EventNames[EVENT_LAST] = { /* EVENT_INITIALIZE */ L"onInitialize", + /* EVENT_DEATH */ L"onDeath", /* EVENT_TICK */ L"onTick", /* EVENT_GENERIC */ L"onGeneric", /* For generic actions on a target unit, like attack or gather */ /* EVENT_START_PRODUCTION */ L"onStartProduction", /* We're about to start training/researching something (deduct resources, etc) */ diff --git a/source/simulation/BaseEntity.cpp b/source/simulation/BaseEntity.cpp index 22e6ad7e96..2b21072476 100755 --- a/source/simulation/BaseEntity.cpp +++ b/source/simulation/BaseEntity.cpp @@ -45,6 +45,7 @@ CBaseEntity::CBaseEntity() AddProperty( L"traits.anchor.type", &m_anchorType ); AddProperty( L"traits.vision.los", &m_los ); AddProperty( L"traits.vision.permanent", &m_permanent ); + AddProperty( L"traits.foundation", &m_foundation ); for( int t = 0; t < EVENT_LAST; t++ ) { @@ -54,7 +55,9 @@ CBaseEntity::CBaseEntity() // Initialize, make life a little easier on the scriptors m_speed = m_turningRadius = 0.0f; - m_extant = true; m_corpse = CStrW(); + m_extant = true; + m_corpse = CStrW(); + m_foundation = CStrW(); m_bound_type = CBoundingObject::BOUND_NONE; m_bound_circle = NULL; @@ -268,12 +271,14 @@ bool CBaseEntity::loadXML( CStr filename ) } else if( hadDepth ) { + // Specifying a rectangular footprint if( !m_bound_box ) m_bound_box = new CBoundingBox(); m_bound_box->setDimensions( width, depth ); m_bound_box->setHeight( height ); m_bound_type = CBoundingObject::BOUND_OABB; } + // Else, entity has no footprint. } } // important so that scripts can see traits @@ -344,7 +349,9 @@ void CBaseEntity::XMLLoadProperty( const CXeromyces& XeroFile, const XMBElement& AddProperty( PropertyName, JSVAL_TRUE ); } else + { AddProperty( PropertyName, Source.getText() ); + } } diff --git a/source/simulation/BaseEntity.h b/source/simulation/BaseEntity.h index d546f8a5cb..8ecfdaeba0 100755 --- a/source/simulation/BaseEntity.h +++ b/source/simulation/BaseEntity.h @@ -85,6 +85,9 @@ public: int m_los; bool m_permanent; + // Foundation entity, or "" for none + CStrW m_foundation; + float m_speed; float m_runRegenRate; float m_runDecayRate; diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index 4d1474716b..785ca21cda 100755 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -28,7 +28,7 @@ extern int g_xres, g_yres; #include using namespace std; -CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) +CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation, CStrW building ) { m_position = position; m_orientation = orientation; @@ -71,6 +71,7 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) AddProperty( L"traits.vision.los", &m_los ); AddProperty( L"traits.vision.permanent", &m_permanent ); AddProperty( L"last_combat_time", &m_lastCombatTime ); + AddProperty( L"building", &m_building ); m_productionQueue = new CProductionQueue( this ); AddProperty( L"production_queue", m_productionQueue ); @@ -121,6 +122,8 @@ CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) m_grouped = -1; + m_building = building; + m_player = g_Game->GetPlayer( 0 ); Initialize(); @@ -179,6 +182,8 @@ void CEntity::loadBase() { m_bounds = new CBoundingBox( m_position.X, m_position.Z, m_ahead, m_base->m_bound_box ); } + + m_actor_transform_valid = false; } void CEntity::kill() @@ -1286,6 +1291,9 @@ bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, bool Queued ) bool CEntity::Kill( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) { + CEventDeath evt; + DispatchEvent( &evt ); + for( AuraTable::iterator it = m_auras.begin(); it != m_auras.end(); it++ ) { it->second->RemoveAll(); diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index a41b1e7c1c..46b54bd064 100755 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -102,7 +102,10 @@ public: int m_frameCheck; //counts the frame float m_lastCombatTime; - + + // Building to convert to if this is a foundation, or "" otherwise + CStrW m_building; + //SP properties float m_staminaCurr; float m_staminaMax; @@ -181,7 +184,7 @@ public: CEntity* m_currentListener; private: - CEntity( CBaseEntity* base, CVector3D position, float orientation ); + CEntity( CBaseEntity* base, CVector3D position, float orientation, CStrW building = L"" ); uint processGotoHelper( CEntityOrder* current, size_t timestep_milli, HEntity& collide ); diff --git a/source/simulation/EntityManager.cpp b/source/simulation/EntityManager.cpp index 5aa28356f7..4d85b3ffb0 100755 --- a/source/simulation/EntityManager.cpp +++ b/source/simulation/EntityManager.cpp @@ -91,10 +91,41 @@ HEntity CEntityManager::create( CBaseEntity* base, CVector3D position, float ori return( HEntity( m_nextalloc++ ) ); } -HEntity CEntityManager::create( CStrW templatename, CVector3D position, float orientation ) +HEntity CEntityManager::create( const CStrW templateName, CVector3D position, float orientation ) { - CBaseEntity* templateobj = g_EntityTemplateCollection.getTemplate( templatename ); - return( create( templateobj, position, orientation ) ); + CBaseEntity* templateObj = g_EntityTemplateCollection.getTemplate( templateName ); + return( create( templateObj, position, orientation ) ); +} + +HEntity CEntityManager::createFoundation( CStrW templateName, CVector3D position, float orientation ) +{ + CBaseEntity* base = g_EntityTemplateCollection.getTemplate( templateName ); + debug_assert( base ); + if( !base ) + return HEntity(); + if( base->m_foundation == L"" ) + return create( base, position, orientation ); // Entity has no foundation, so just create it + + CBaseEntity* foundation = g_EntityTemplateCollection.getTemplate( base->m_foundation ); + debug_assert( foundation ); + if( !foundation ) + return HEntity(); + + while( m_entities[m_nextalloc].m_refcount ) + { + m_nextalloc++; + if(m_nextalloc == MAX_HANDLES) + { + debug_warn("Ran out of entity handles!"); + return HEntity(); + } + } + + m_entities[m_nextalloc].m_entity = new CEntity( foundation, position, orientation, templateName ); + if( m_collisionPatches) + m_entities[m_nextalloc].m_entity->updateCollisionPatch(); + m_entities[m_nextalloc].m_entity->me = HEntity( m_nextalloc ); + return( HEntity( m_nextalloc++ ) ); } HEntity* CEntityManager::getByHandle( u16 index ) diff --git a/source/simulation/EntityManager.h b/source/simulation/EntityManager.h index a9b412e901..e8a332abb1 100755 --- a/source/simulation/EntityManager.h +++ b/source/simulation/EntityManager.h @@ -49,7 +49,9 @@ public: ~CEntityManager(); HEntity create( CBaseEntity* base, CVector3D position, float orientation ); - HEntity create( CStrW templatename, CVector3D position, float orientation ); + HEntity create( CStrW templateName, CVector3D position, float orientation ); + + HEntity createFoundation( CStrW templateName, CVector3D position, float orientation ); HEntity* getByHandle( u16 index ); CHandle *getHandle( int index ); diff --git a/source/simulation/EventHandlers.h b/source/simulation/EventHandlers.h index 7d443555dc..d6e2f9812a 100755 --- a/source/simulation/EventHandlers.h +++ b/source/simulation/EventHandlers.h @@ -15,6 +15,12 @@ public: CEventInitialize() : CScriptEvent( L"initialize", EVENT_INITIALIZE, false ) {} }; +class CEventDeath : public CScriptEvent +{ +public: + CEventDeath() : CScriptEvent( L"death", EVENT_DEATH, false ) {} +}; + class CEventTick : public CScriptEvent { public: