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 de1a21f80c..595a6d654b 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 @@ -29,6 +29,7 @@ 100 100 + CivilCentre diff --git a/binaries/data/mods/official/entities/template_structure_civic_house.xml b/binaries/data/mods/official/entities/template_structure_civic_house.xml index 685ed22062..1aba22f944 100644 --- a/binaries/data/mods/official/entities/template_structure_civic_house.xml +++ b/binaries/data/mods/official/entities/template_structure_civic_house.xml @@ -24,6 +24,7 @@ 100 + House diff --git a/binaries/data/mods/official/entities/template_structure_defense_scout_tower.xml b/binaries/data/mods/official/entities/template_structure_defense_scout_tower.xml index 16de6b3402..89ead9bf0f 100644 --- a/binaries/data/mods/official/entities/template_structure_defense_scout_tower.xml +++ b/binaries/data/mods/official/entities/template_structure_defense_scout_tower.xml @@ -21,10 +21,11 @@ foundation_1x1 - + 50 50 + ScoutTower 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 27bbcaaff2..ecf239d823 100644 --- a/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml +++ b/binaries/data/mods/official/entities/template_structure_economic_farmstead.xml @@ -19,6 +19,7 @@ foundation_3x3 + Farmstead 200 diff --git a/binaries/data/mods/official/entities/template_structure_military_barracks.xml b/binaries/data/mods/official/entities/template_structure_military_barracks.xml index 0551e230c6..6d3720c18b 100644 --- a/binaries/data/mods/official/entities/template_structure_military_barracks.xml +++ b/binaries/data/mods/official/entities/template_structure_military_barracks.xml @@ -25,6 +25,7 @@ 200 100 + Barracks diff --git a/binaries/data/mods/official/entities/template_structure_military_dock.xml b/binaries/data/mods/official/entities/template_structure_military_dock.xml index 2f6d55c800..c3a1316c53 100644 --- a/binaries/data/mods/official/entities/template_structure_military_dock.xml +++ b/binaries/data/mods/official/entities/template_structure_military_dock.xml @@ -26,6 +26,7 @@ foundation_4x4 + Dock diff --git a/binaries/data/mods/official/entities/template_structure_military_fortress.xml b/binaries/data/mods/official/entities/template_structure_military_fortress.xml index 803a01258c..bffda848d6 100644 --- a/binaries/data/mods/official/entities/template_structure_military_fortress.xml +++ b/binaries/data/mods/official/entities/template_structure_military_fortress.xml @@ -25,6 +25,7 @@ 200 800 + Fortress diff --git a/binaries/data/mods/official/entities/template_structure_resource_field.xml b/binaries/data/mods/official/entities/template_structure_resource_field.xml index ebb27faa07..647bcd151a 100644 --- a/binaries/data/mods/official/entities/template_structure_resource_field.xml +++ b/binaries/data/mods/official/entities/template_structure_resource_field.xml @@ -21,6 +21,7 @@ foundation_3x3 + Field diff --git a/binaries/data/mods/official/entities/template_structure_special.xml b/binaries/data/mods/official/entities/template_structure_special.xml index 4d241feef7..92a796920b 100644 --- a/binaries/data/mods/official/entities/template_structure_special.xml +++ b/binaries/data/mods/official/entities/template_structure_special.xml @@ -21,6 +21,7 @@ foundation_5x5 + Special diff --git a/binaries/data/mods/official/scripts/entity_functions.js b/binaries/data/mods/official/scripts/entity_functions.js index d007f0d21b..6bacf61c87 100644 --- a/binaries/data/mods/official/scripts/entity_functions.js +++ b/binaries/data/mods/official/scripts/entity_functions.js @@ -110,6 +110,7 @@ function entityInit( evt ) this.buildPoints = new Object(); this.buildPoints.curr = 0.0; this.buildPoints.max = parseFloat( building.traits.creation.time ); + this.traits.creation.buildingLimitCategory = building.traits.creation.buildingLimitCategory; } // Generate civ code (1st four characters of civ name, in lower case eg "Carthaginians" => "cart"). @@ -2177,4 +2178,25 @@ function entityEventFormation( evt ) } } +} + +// ==================================================================== + +function getBuildingLimit( category/*, gameMode*/ ) +{ +console.write(category); + // Civil + if(category=="CivilCentre") return 1; + if(category=="House") return 15; + if(category=="Farmstead") return 2; + if(category=="Field") return 5; + // Military + if(category=="Dock") return 2; + if(category=="Fortress") return 1; + if(category=="Barracks") return 2; + if(category=="ScoutTower") return 10; + // Other + if(category=="Special") return 1; + + return 0; } \ No newline at end of file diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index 89ff625e50..7adaadeb99 100644 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -1353,7 +1353,7 @@ void ResetInteraction() bool CBuildingPlacer::Activate(CStrW& templateName) -{ +{ if(m_active) { return false; @@ -1376,7 +1376,6 @@ bool CBuildingPlacer::Activate(CStrW& templateName) return false; } - // m_actor CStr actorName ( m_template->m_actorName ); // convert CStrW->CStr8 std::set selections; @@ -1393,6 +1392,8 @@ bool CBuildingPlacer::Activate(CStrW& templateName) m_bounds = new CBoundingBox( 0, 0, CVector2D(1, 0), m_template->m_bound_box ); } + + return true; } @@ -1508,7 +1509,7 @@ void CBuildingPlacer::Update( float timeStep ) } // Validate placement location. - CheckValid(pos, onSocket); + CheckValidLocation(pos, onSocket); // Flash our actor red if the position is invalid. @@ -1525,12 +1526,16 @@ void CBuildingPlacer::Update( float timeStep ) m_actor->GetModel()->SetShadingColor( col ); } -// Alex's mess -void CBuildingPlacer::CheckValid( CVector3D pos, bool onSocket ) +/** + * Check whether the placement location is valid (look at whether we're + * on the map, who owns the territory, whether we are on a socket, and + * whether we are colliding with anything). + * + * @param pos position under the cursor + * @param onSocket whether on a socket or not + */ +void CBuildingPlacer::CheckValidLocation( CVector3D pos, bool onSocket ) { - // Check whether the placement location is valid (look at whether we're - // on the map, who owns the territory, whether we are on a socket, and - // whether we are colliding with anything). CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); if( pTerrain->IsOnMap( pos.X, pos.Z ) ) { @@ -1550,12 +1555,62 @@ void CBuildingPlacer::CheckValid( CVector3D pos, bool onSocket ) // anything except possibly our socket (which we find out by passing an // ignoreClass to GetCollisionObject); also, if we are a socketed object, // we check that we are actually on a socket, using onSocket (set above). + // UPDATED: Check for territorial building limit + m_valid = ( m_template->m_socket == L"" || onSocket ) - && ( GetCollisionObject( m_bounds, 0, &m_template->m_socket ) == 0 ); + && ( GetCollisionObject( m_bounds, 0, &m_template->m_socket ) == 0 ) + && IsWithinLimit(pos); // Is this building within its appropriate territorial limit? } } else { m_valid = false; } +} + +/** + * Checks whether there is space (territorial limit) in the current territory + * + * @param pos position under the cursor + * + * @returns true if within limit, false otherwise + */ +bool CBuildingPlacer::IsWithinLimit( CVector3D pos ) +{ + // Get the territorial building limit based on its category + CStrW category = m_template->m_buildingLimitCategory; + jsval param = ToJSVal(category); + int limit = ToPrimitive(g_ScriptingHost.CallFunction("getBuildingLimit", ¶m, 1)); + + if( limit == 0 ) + { + return true; + } + else + { + CTerritory* territory = g_Game->GetWorld()->GetTerritoryManager()->GetTerritory( pos.X, pos.Z ); + + std::vector extantEntities; + std::vector::iterator entIter; + int buildingCount = 0; // Number of buildings in the current territory + + g_EntityManager.GetExtant(extantEntities); + + // NOTE: This loop runs continuously because the function is called in Update() + for( entIter = extantEntities.begin(); entIter != extantEntities.end(); entIter++ ) + { + if((*entIter)->m_buildingLimitCategory == m_template->m_buildingLimitCategory + && g_Game->GetWorld()->GetTerritoryManager()->GetTerritory( (*entIter)->m_position.X, (*entIter)->m_position.Z ) == territory) + { + buildingCount++; + } + } + + if(buildingCount < limit) + return true; + else + return false; + } + + } \ No newline at end of file diff --git a/source/ps/Interact.h b/source/ps/Interact.h index 29acad7dbe..5d0aafca7b 100644 --- a/source/ps/Interact.h +++ b/source/ps/Interact.h @@ -178,7 +178,8 @@ struct CBuildingPlacer : public Singleton void MousePressed(); void MouseReleased(); void Update( float timeStep ); - void CheckValid( CVector3D pos, bool onSocket ); + void CheckValidLocation( CVector3D pos, bool onSocket ); + bool IsWithinLimit( CVector3D pos ); }; bool IsMouseoverType( CEntity* ev, void* userdata ); diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index 514e6323b4..4ac64f95cd 100644 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -164,6 +164,9 @@ public: // If the object is a territory centre, this points to its territory CTerritory* m_associatedTerritory; + // Territorial limit + CStrW m_buildingLimitCategory; + // Auras AuraTable m_auras; AuraSet m_aurasInfluencingMe; diff --git a/source/simulation/EntityScriptInterface.cpp b/source/simulation/EntityScriptInterface.cpp index f798d71025..7728f24cfa 100644 --- a/source/simulation/EntityScriptInterface.cpp +++ b/source/simulation/EntityScriptInterface.cpp @@ -121,6 +121,8 @@ void CEntity::ScriptingInit() AddClassProperty( L"building", &CEntity::m_building ); AddClassProperty( L"visible", &CEntity::m_visible ); AddClassProperty( L"productionQueue", &CEntity::m_productionQueue ); + AddClassProperty( L"traits.creation.buildingLimitCategory", &CEntity::m_buildingLimitCategory ); + CJSComplex::ScriptingInit( "Entity", Construct, 2 ); } diff --git a/source/simulation/EntityTemplate.cpp b/source/simulation/EntityTemplate.cpp index 4abbe60583..a43cbaa852 100644 --- a/source/simulation/EntityTemplate.cpp +++ b/source/simulation/EntityTemplate.cpp @@ -466,6 +466,9 @@ void CEntityTemplate::ScriptingInit() AddClassProperty( L"traits.creation.foundation", &CEntityTemplate::m_foundation ); AddClassProperty( L"traits.creation.socket", &CEntityTemplate::m_socket ); AddClassProperty( L"traits.creation.territoryRestriction", &CEntityTemplate::m_territoryRestriction ); + AddClassProperty( L"traits.creation.buildingLimitCategory", &CEntityTemplate::m_buildingLimitCategory ); + + CJSComplex::ScriptingInit( "EntityTemplate" ); } diff --git a/source/simulation/EntityTemplate.h b/source/simulation/EntityTemplate.h index 8391511cef..0ffd63a9fe 100644 --- a/source/simulation/EntityTemplate.h +++ b/source/simulation/EntityTemplate.h @@ -136,6 +136,9 @@ public: // Can be "allied" to allow placement only in allied territories, or "" or "all" for all territories CStrW m_territoryRestriction; + // Territorial limit + CStrW m_buildingLimitCategory; + float m_speed; float m_runSpeed; float m_runRegenRate;