diff --git a/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/next_s.bmp b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/next_s.bmp new file mode 100644 index 0000000000..db2018414f Binary files /dev/null and b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/next_s.bmp differ diff --git a/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/pause_s.bmp b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/pause_s.bmp new file mode 100644 index 0000000000..aed9442dd5 Binary files /dev/null and b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/pause_s.bmp differ diff --git a/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/play_s.bmp b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/play_s.bmp new file mode 100644 index 0000000000..5329ea25bc Binary files /dev/null and b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/play_s.bmp differ diff --git a/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/previous_s.bmp b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/previous_s.bmp new file mode 100644 index 0000000000..8315185539 Binary files /dev/null and b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/previous_s.bmp differ diff --git a/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/stop_s.bmp b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/stop_s.bmp new file mode 100644 index 0000000000..c027fec5ff Binary files /dev/null and b/binaries/data/mods/official/art/textures/ui/session/icons/single/atlas/stop_s.bmp differ diff --git a/binaries/data/mods/official/entities/other/temp_themistocles_the_killer.xml b/binaries/data/mods/official/entities/other/temp_themistocles_the_killer.xml index 4d286c6948..3a0f52a520 100644 --- a/binaries/data/mods/official/entities/other/temp_themistocles_the_killer.xml +++ b/binaries/data/mods/official/entities/other/temp_themistocles_the_killer.xml @@ -19,6 +19,10 @@ 20 10 + 0.1 + 0.9 + 0.1 + 0.5 diff --git a/binaries/data/mods/official/entities/template_structure_civic_civil_centre.xml b/binaries/data/mods/official/entities/template_structure_civic_civil_centre.xml index e5c93043a0..644e04b29d 100644 --- a/binaries/data/mods/official/entities/template_structure_civic_civil_centre.xml +++ b/binaries/data/mods/official/entities/template_structure_civic_civil_centre.xml @@ -53,6 +53,10 @@ + 0.1 + 0.2 + .9 + 0.4 diff --git a/binaries/data/mods/official/entities/template_structure_civic_temple.xml b/binaries/data/mods/official/entities/template_structure_civic_temple.xml index 4bd53503e2..7e8816b2dc 100644 --- a/binaries/data/mods/official/entities/template_structure_civic_temple.xml +++ b/binaries/data/mods/official/entities/template_structure_civic_temple.xml @@ -34,6 +34,10 @@ 30 5 2000 + 1.0 + 1.0 + 0.0 + 0.6 diff --git a/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml b/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml index 48b53e4ba9..88fa044e0c 100644 --- a/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml +++ b/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml @@ -41,6 +41,10 @@ + 0.1 + 0.2 + 1.0 + 0.4 diff --git a/binaries/data/mods/official/entities/template_structure_economic_mill.xml b/binaries/data/mods/official/entities/template_structure_economic_mill.xml index 79bb855eb5..488f02704c 100644 --- a/binaries/data/mods/official/entities/template_structure_economic_mill.xml +++ b/binaries/data/mods/official/entities/template_structure_economic_mill.xml @@ -42,6 +42,10 @@ + 0.1 + 0.2 + 1.0 + 0.4 diff --git a/binaries/data/mods/official/entities/template_unit_cavalry_melee.xml b/binaries/data/mods/official/entities/template_unit_cavalry_melee.xml index a61b89780c..86dfc698ab 100644 --- a/binaries/data/mods/official/entities/template_unit_cavalry_melee.xml +++ b/binaries/data/mods/official/entities/template_unit_cavalry_melee.xml @@ -12,7 +12,7 @@ - + s 10 1000 @@ -21,6 +21,10 @@ 0.0 0.5 0.5 + 1.0 + 0.1 + 0.2 + 0.5 diff --git a/binaries/data/mods/official/entities/template_unit_fauna_breed.xml b/binaries/data/mods/official/entities/template_unit_fauna_breed.xml index b54ec80000..2dc3426142 100644 --- a/binaries/data/mods/official/entities/template_unit_fauna_breed.xml +++ b/binaries/data/mods/official/entities/template_unit_fauna_breed.xml @@ -16,6 +16,10 @@ 20 + .8 + .8 + 1.0 + 0.5 diff --git a/binaries/data/mods/official/entities/template_unit_fauna_herd.xml b/binaries/data/mods/official/entities/template_unit_fauna_herd.xml index be5ff90c50..5d8d286cfc 100644 --- a/binaries/data/mods/official/entities/template_unit_fauna_herd.xml +++ b/binaries/data/mods/official/entities/template_unit_fauna_herd.xml @@ -16,6 +16,10 @@ 20 + 0.8 + 0.8 + 1.0 + 0.5 diff --git a/binaries/data/mods/official/entities/template_unit_super_cavalry.xml b/binaries/data/mods/official/entities/template_unit_super_cavalry.xml index 65a800746d..9c0987ef2e 100644 --- a/binaries/data/mods/official/entities/template_unit_super_cavalry.xml +++ b/binaries/data/mods/official/entities/template_unit_super_cavalry.xml @@ -24,6 +24,10 @@ 0 0.9 0.1 + 1.0 + 0.1 + 0.2 + 0.5 diff --git a/binaries/data/mods/official/entities/template_unit_support_female_citizen.xml b/binaries/data/mods/official/entities/template_unit_support_female_citizen.xml index 056d57e0a4..f84e0d07ca 100644 --- a/binaries/data/mods/official/entities/template_unit_support_female_citizen.xml +++ b/binaries/data/mods/official/entities/template_unit_support_female_citizen.xml @@ -20,6 +20,10 @@ 30 + 0.8 + 0.8 + 1.0 + 0.5 diff --git a/binaries/data/mods/official/entities/units/hele_hero_alexander.xml b/binaries/data/mods/official/entities/units/hele_hero_alexander.xml index c652d3618c..ec31f1b233 100644 --- a/binaries/data/mods/official/entities/units/hele_hero_alexander.xml +++ b/binaries/data/mods/official/entities/units/hele_hero_alexander.xml @@ -19,6 +19,10 @@ 20 5 + 0.1 + 0.9 + 0.1 + 0.5 diff --git a/binaries/data/mods/official/entities/units/hele_hero_leonidas.xml b/binaries/data/mods/official/entities/units/hele_hero_leonidas.xml index 91a05b3efc..2321d59a82 100644 --- a/binaries/data/mods/official/entities/units/hele_hero_leonidas.xml +++ b/binaries/data/mods/official/entities/units/hele_hero_leonidas.xml @@ -19,6 +19,10 @@ 20 5 + 0.0 + 0.0 + 0.0 + 0.5 diff --git a/binaries/data/mods/official/entities/units/hele_hero_themistocles.xml b/binaries/data/mods/official/entities/units/hele_hero_themistocles.xml index 2deb98966e..8010e2853c 100644 --- a/binaries/data/mods/official/entities/units/hele_hero_themistocles.xml +++ b/binaries/data/mods/official/entities/units/hele_hero_themistocles.xml @@ -19,6 +19,10 @@ 20 10 + 0.1 + 0.9 + 0.1 + 0.5 diff --git a/binaries/data/mods/official/scripts/entity_functions.js b/binaries/data/mods/official/scripts/entity_functions.js index cfe637b9d8..2321893855 100644 --- a/binaries/data/mods/official/scripts/entity_functions.js +++ b/binaries/data/mods/official/scripts/entity_functions.js @@ -7,7 +7,7 @@ // To add a new generic order, do the following all within template_entity_script.js: -// * Pick a number to be its ID (add this to the "const"s directly below). +// * Pick a number to be its ID (add this to the "const"s directly below). f // * Add code in the entityInit() function below that will call setActionParams to set the action's range, speed and animation if the entity supports this action. For example this.setActionParams( ACTION_GATHER, 0.0, a.range, a.speed, "gather" ) tells the entity that the action with ID of ACTION_GATHER has min range 0, max range a.range, speed a.speed, and should play the animation called "gather" while active. @@ -471,38 +471,38 @@ function attachAuras() if( this.traits.auras.courage ) { a = this.traits.auras.courage; - this.addAura ( "courage", a.radius, 0, new DamageModifyAura( this, true, a.bonus ) ); + this.addAura ( "courage", a.radius, 0, a.r, a.g, a.b, a.a, new DamageModifyAura( this, true, a.bonus ) ); } if( this.traits.auras.fear ) { a = this.traits.auras.fear; - this.addAura ( "fear", a.radius, 0, new DamageModifyAura( this, false, -a.bonus ) ); + this.addAura ( "fear", a.radius, 0, a.r, a.g, a.b, a.a, new DamageModifyAura( this, false, -a.bonus ) ); } if( this.traits.auras.infidelity ) { a = this.traits.auras.infidelity; - this.addAura ( "infidelity", a.radius, 0, new InfidelityAura( this, a.time ) ); + this.addAura ( "infidelity", a.radius, 0, a.r, a.g, a.b, a.a, new InfidelityAura( this, a.time ) ); } if( this.traits.auras.dropsite ) { a = this.traits.auras.dropsite; - this.addAura ( "dropsite", a.radius, 0, new DropsiteAura( this, a.types ) ); + this.addAura ( "dropsite", a.radius, 0, a.r, a.g, a.b, a.a, new DropsiteAura( this, a.types ) ); } if( this.traits.auras.heal ) { a = this.traits.auras.heal; - this.addAura ( "heal", a.radius, a.speed, new HealAura( this ) ); + this.addAura ( "heal", a.radius, a.speed, a.r, a.g, a.b, a.a, new HealAura( this ) ); } if( this.traits.auras.trample ) { a = this.traits.auras.trample; - this.addAura ( "trample", a.radius, a.speed, new TrampleAura( this ) ); + this.addAura ( "trample", a.radius, a.speed, a.r, a.g, a.b, a.a, new TrampleAura( this ) ); } } if( this.hasClass("Settlement") ) { - this.addAura ( "settlement", 1.0, 0, new SettlementAura( this ) ); + this.addAura ( "settlement", 1.0, 0, 0.0, 0.0, 0.0, 0.0, new SettlementAura( this ) ); } } diff --git a/source/graphics/Frustum.cpp b/source/graphics/Frustum.cpp index c4f83ed35f..cd1457ab40 100644 --- a/source/graphics/Frustum.cpp +++ b/source/graphics/Frustum.cpp @@ -52,7 +52,16 @@ bool CFrustum::IsPointVisible (const CVector3D &point) const return true; } - +bool CFrustum::DoesSegmentIntersect(const CVector3D& start, const CVector3D &end) +{ + CVector3D intersect; + for ( int i = 0; iGetWorld()->GetTerritoryManager()->renderTerritories(); + PROFILE_END( "render territories" ); + glDisable( GL_DEPTH_TEST ); + PROFILE_START( "render entity bars" ); pglActiveTextureARB(GL_TEXTURE1_ARB); diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index 0c832d18cd..22e1869dce 100644 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -111,7 +111,15 @@ void CSelectedEntities::renderBars() glDisable( GL_BLEND ); }*/ } +void CSelectedEntities::renderAuras() +{ + std::vector::iterator it; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + for ( it = m_selected.begin(); it != m_selected.end(); ++it ) + (*it)->renderAuras(); +} void CSelectedEntities::renderHealthBars() { std::vector::iterator it; @@ -859,7 +867,15 @@ void CMouseoverEntities::renderSelectionOutlines() glDisable( GL_BLEND ); } +void CMouseoverEntities::renderAuras() +{ + std::vector::iterator it; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + for ( it = m_mouseover.begin(); it != m_mouseover.end(); ++it ) + it->entity->renderAuras(); +} void CMouseoverEntities::renderBars() { std::vector::iterator it; diff --git a/source/ps/Interact.h b/source/ps/Interact.h index 89900e0a76..c02192fa79 100644 --- a/source/ps/Interact.h +++ b/source/ps/Interact.h @@ -77,6 +77,7 @@ struct CSelectedEntities : public Singleton void renderSelectionOutlines(); void renderOverlays(); + void renderAuras(); void renderRallyPoints(); void renderBars(); void renderHealthBars(); @@ -136,6 +137,7 @@ struct CMouseoverEntities : public Singleton void renderSelectionOutlines(); void renderOverlays(); void renderRallyPoints(); + void renderAuras(); void renderBars(); void renderHealthBars(); void renderStaminaBars(); diff --git a/source/simulation/Aura.cpp b/source/simulation/Aura.cpp index 9c77b9628c..905072b5fd 100644 --- a/source/simulation/Aura.cpp +++ b/source/simulation/Aura.cpp @@ -7,9 +7,9 @@ #include -CAura::CAura( JSContext* cx, CEntity* source, CStrW& name, float radius, size_t tickRate, JSObject* handler ) +CAura::CAura( JSContext* cx, CEntity* source, CStrW& name, float radius, size_t tickRate, const CVector4D& color, JSObject* handler ) : m_cx(cx), m_source(source), m_name(name), m_radius(radius), m_handler(handler), - m_tickRate(tickRate), m_tickCyclePos(0) + m_tickRate(tickRate), m_tickCyclePos(0), m_color(color) { JS_AddRoot( m_cx, &m_handler ); // don't GC it so we can call it later } diff --git a/source/simulation/Aura.h b/source/simulation/Aura.h index 99bc4a2ffe..b6ff75093c 100644 --- a/source/simulation/Aura.h +++ b/source/simulation/Aura.h @@ -2,6 +2,7 @@ #define __AURA_H__ #include "EntityHandles.h" +#include "maths/Vector4D.h" class CEntity; @@ -11,13 +12,14 @@ public: JSContext* m_cx; CEntity* m_source; CStrW m_name; + CVector4D m_color; float m_radius; // In graphics units size_t m_tickRate; // In milliseconds JSObject* m_handler; std::vector m_influenced; size_t m_tickCyclePos; // Add time to this until it's time to tick again - CAura( JSContext* cx, CEntity* source, CStrW& name, float radius, size_t tickRate, JSObject* handler ); + CAura( JSContext* cx, CEntity* source, CStrW& name, float radius, size_t tickRate, const CVector4D& color, JSObject* handler ); ~CAura(); // Remove all entities from under our influence; this isn't done in the destructor since diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index c18886af97..26f87e2a51 100644 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -195,7 +195,25 @@ void CEntity::loadBase() for ( int i=0; im_sectorDivs; ++i ) m_sectorValues[i] = false; } +void CEntity::initAuraData() +{ + if ( m_auras.empty() ) + return; + m_unsnappedPoints.resize(m_auras.size()); + size_t i=0; + for ( AuraTable::iterator it=m_auras.begin(); it!=m_auras.end(); ++it, ++i ) + { + m_unsnappedPoints[i].resize(SELECTION_CIRCLE_POINTS); + float radius = it->second->m_radius; + for ( int j=0; jGetColour(); + glPushMatrix(); + glTranslatef(m_graphics_position.X, m_graphics_position.Y, + m_graphics_position.Z); + glBegin(GL_TRIANGLE_FAN); + glVertex3f(0.0f, getAnchorLevel(m_graphics_position.X, + m_graphics_position.Z)-m_graphics_position.Y+.5f, 0.0f); + size_t i=0; + + for ( AuraTable::iterator it=m_auras.begin(); it!=m_auras.end(); ++it, ++i ) + { + CVector4D color = it->second->m_color; + glColor4f(color.m_X, color.m_Y, color.m_Z, color.m_W); + +#ifdef SELECTION_TERRAIN_CONFORMANCE + //This starts to break when the radius is bigger + if ( it->second->m_radius < 15.0f ) + { + for ( int j=0; jsecond->m_radius < 15.0f ) + { + for ( int j=0; j= 4 ); - debug_assert( JSVAL_IS_OBJECT(argv[3]) ); + debug_assert( argc >= 8 ); + debug_assert( JSVAL_IS_OBJECT(argv[7]) ); CStrW name = ToPrimitive( argv[0] ); float radius = ToPrimitive( argv[1] ); size_t tickRate = max( 0, ToPrimitive( argv[2] ) ); // since it's a size_t we don't want it to be negative - JSObject* handler = JSVAL_TO_OBJECT( argv[3] ); + float r = ToPrimitive( argv[3] ); + float g = ToPrimitive( argv[4] ); + float b = ToPrimitive( argv[5] ); + float a = ToPrimitive( argv[6] ); + CVector4D color(r, g, b, a); + JSObject* handler = JSVAL_TO_OBJECT( argv[7] ); if( m_auras[name] ) { delete m_auras[name]; } - m_auras[name] = new CAura( cx, this, name, radius, tickRate, handler ); + m_auras[name] = new CAura( cx, this, name, radius, tickRate, color, handler ); return JSVAL_VOID; } diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index 77b0f08482..d3bf44ca5f 100644 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -225,6 +225,8 @@ public: int m_currentRequest; //Notification we our notifiers are sending std::vector m_sectorValues; + //Slight optimization for aura rendering + std::vector< std::vector > m_unsnappedPoints; private: CEntity( CEntityTemplate* base, CVector3D position, float orientation, const std::set& actorSelections, const CStrW* building = 0 ); @@ -272,6 +274,7 @@ public: // Process initialization bool Initialize(); + void initAuraData(); // Process tick. void Tick(); @@ -298,6 +301,7 @@ public: // Things like selection circles and debug info - possibly move to gui if/when it becomes responsible for (and capable of) it. void render(); void renderSelectionOutline( float alpha = 1.0f ); + void renderAuras(); void renderBars(); void renderBarBorders(); void renderHealthBar(); diff --git a/source/simulation/TerritoryManager.cpp b/source/simulation/TerritoryManager.cpp index 0845ce133b..9b44392ac2 100644 --- a/source/simulation/TerritoryManager.cpp +++ b/source/simulation/TerritoryManager.cpp @@ -5,6 +5,7 @@ #include "ps/Game.h" #include "ps/Player.h" #include "graphics/Terrain.h" +#include "graphics/GameView.h" #include "Entity.h" #include "EntityManager.h" #include "graphics/Unit.h" @@ -12,11 +13,11 @@ #include "graphics/Model.h" #include "lib/allocators.h" #include "lib/timer.h" +#include "lib/ogl.h" #include "EntityManager.h" using namespace std; - CTerritoryManager::CTerritoryManager() { m_TerritoryMatrix = 0; @@ -206,3 +207,56 @@ void CTerritoryManager::CalculateBoundary( std::vector& centres, size_ } } } +void CTerritoryManager::renderTerritories() +{ + const CTerrain* pTerrain = g_Game->GetWorld()->GetTerrain(); + CFrustum frustum = g_Game->GetView()->GetCamera()->GetFrustum(); + std::vector::iterator terr=m_Territories.begin(); + glEnable(GL_LINE_SMOOTH); + glLineWidth(1.4f); + + for ( ; terr != m_Territories.end(); ++terr ) + { + std::vector::iterator it=(*terr)->boundary.begin()+1; + const SPlayerColour& col = (*terr)->owner->GetColour(); + glColor3f(col.r, col.g, col.b); + glBegin(GL_LINE_STRIP); + + for ( ; it != (*terr)->boundary.end(); ++it ) + { + CVector3D front(it->x, pTerrain->getExactGroundLevel(it->x, it->y), it->y); + CVector3D prev((it-1)->x, pTerrain->getExactGroundLevel((it-1)->x, (it-1)->y), (it-1)->y); + if ( !frustum.DoesSegmentIntersect(prev, front) ) + continue; + + float iterf = (front - prev).GetLength() / TERRITORY_PRECISION_STEP; + for ( float i=0; igetExactGroundLevel(pos)+.25f, pos.y); + } + glVertex3f(front.X, pTerrain->getExactGroundLevel(front.X, front.Z)+.25f, front.Z); + } + //Loop around + CVector2D first2D((*terr)->boundary.front()), back2D((*terr)->boundary.back()); + CVector3D first(first2D.x, pTerrain->getExactGroundLevel(first2D), first2D.y); + CVector3D back(back2D.x, pTerrain->getExactGroundLevel(back2D), back2D.y); + + if ( !frustum.DoesSegmentIntersect(back, first) ) + { + glEnd(); + continue; + } + float iterf = (first - back).GetLength() / TERRITORY_PRECISION_STEP; + for ( float i=0; igetExactGroundLevel(pos)+.25f, pos.y); + } + glVertex3f(first.X, pTerrain->getExactGroundLevel(first2D)+.25f, first.Z); + + glEnd(); + } + glDisable(GL_LINE_SMOOTH); + glLineWidth(1.0f); +} \ No newline at end of file diff --git a/source/simulation/TerritoryManager.h b/source/simulation/TerritoryManager.h index 570247380d..5ddb1256c2 100644 --- a/source/simulation/TerritoryManager.h +++ b/source/simulation/TerritoryManager.h @@ -20,6 +20,8 @@ class CUnit; class CPlayer; +const float TERRITORY_PRECISION_STEP = 1.0f / 6; + class CTerritory { public: @@ -44,11 +46,12 @@ public: void Initialize(); // initialize, called after the game is fully loaded void Recalculate(); // recalculate the territory boundaries - + void renderTerritories(); CTerritory* GetTerritory(int x, int z); // get the territory to which the given tile belongs CTerritory* GetTerritory(float x, float z); // get the territory to which the given world-space point belongs std::vector& GetTerritories() { return m_Territories; } + private: void CalculateBoundary( std::vector& centres, size_t index, std::vector& boundary ); };