Ticket #3: technology_16-04-12.diff
File technology_16-04-12.diff, 139.5 KB (added by , 12 years ago) |
---|
-
source/simulation2/system/ComponentManager.h
233 233 static int Script_AddLocalEntity(void* cbdata, std::string templateName); 234 234 static void Script_DestroyEntity(void* cbdata, int ent); 235 235 static CScriptVal Script_ReadJSONFile(void* cbdata, std::wstring fileName); 236 static std::vector<std::string> Script_FindAllTechnologyTemplates(void* cbdata); 236 237 237 238 CMessage* ConstructMessage(int mtid, CScriptVal data); 238 239 void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const; -
source/simulation2/system/ComponentManager.cpp
81 81 m_ScriptInterface.RegisterFunction<int, std::string, CComponentManager::Script_AddLocalEntity> ("AddLocalEntity"); 82 82 m_ScriptInterface.RegisterFunction<void, int, CComponentManager::Script_DestroyEntity> ("DestroyEntity"); 83 83 m_ScriptInterface.RegisterFunction<CScriptVal, std::wstring, CComponentManager::Script_ReadJSONFile> ("ReadJSONFile"); 84 m_ScriptInterface.RegisterFunction<std::vector<std::string>, CComponentManager::Script_FindAllTechnologyTemplates> ("FindAllTechnologyTemplates"); 84 85 } 85 86 86 87 // Define MT_*, IID_* as script globals, and store their names … … 944 945 945 946 return componentManager->GetScriptInterface().ReadJSONFile(path).get(); 946 947 } 948 949 std::vector<std::string> CComponentManager::Script_FindAllTechnologyTemplates(void* cbdata) 950 { 951 CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata); 952 953 return componentManager->GetScriptInterface().FindAllTechnologyTemplates(); 954 } -
source/simulation2/Simulation2.cpp
125 125 LOAD_SCRIPTED_COMPONENT("GuiInterface"); 126 126 LOAD_SCRIPTED_COMPONENT("PlayerManager"); 127 127 LOAD_SCRIPTED_COMPONENT("Timer"); 128 LOAD_SCRIPTED_COMPONENT("TechnologyTemplateManager"); 128 129 129 130 #undef LOAD_SCRIPTED_COMPONENT 130 131 } -
source/scriptinterface/ScriptInterface.h
230 230 * Read a JSON file. Returns the undefined value on error. 231 231 */ 232 232 CScriptValRooted ReadJSONFile(const VfsPath& path); 233 234 std::vector<std::string> FindAllTechnologyTemplates(); 233 235 234 236 /** 235 237 * Stringify to a JSON string, UTF-8 encoded. Returns an empty string on error. -
source/scriptinterface/ScriptInterface.cpp
1023 1023 return ParseJSON(content); 1024 1024 } 1025 1025 1026 static Status AddToTechnologyTemplates(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) 1027 { 1028 std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; 1029 1030 // Strip the .json extension 1031 VfsPath pathstem = pathname.ChangeExtension(L""); 1032 // Strip the root from the path 1033 std::wstring name = pathstem.string().substr(ARRAY_SIZE("simulation/data/technologies/")-1); 1034 1035 templates.push_back(std::string(name.begin(), name.end())); 1036 return INFO::OK; 1037 } 1038 1039 std::vector<std::string> ScriptInterface::FindAllTechnologyTemplates() 1040 { 1041 std::vector<std::string> templates; 1042 1043 Status ok; 1044 1045 // Find all the technology template files 1046 ok = vfs::ForEachFile(g_VFS, "simulation/data/technologies/", AddToTechnologyTemplates, (uintptr_t)&templates, L"*.json", vfs::DIR_RECURSIVE); 1047 WARN_IF_ERR(ok); 1048 1049 return templates; 1050 } 1051 1026 1052 struct Stringifier 1027 1053 { 1028 1054 static JSBool callback(const jschar* buf, uint32 len, void* data) -
binaries/data/mods/public/simulation/templates/units/pers_infantry_spearman_b.xml
23 23 <SpecificName>Mada Sparabara</SpecificName> 24 24 <Icon>units/pers_infantry_spearman.png</Icon> 25 25 <History>Mede Shieldbearers comprised the main infantry regiment of the Persians during this period, especially in the reign of Xerxes. First under the Medes and later the Achaemenids these soldiers were the bread and butter infantry for hand-to-hand engagement. Within the Satabam, the basic tactical unit of the Achamenid army, the shieldbearers formed the first two ranks, protecting the arhcers and also serving as a way to keep the enemy pinned down until the cavalry could act. While well known for tenacity the shieldbearers were not equipped to last long in an extended melee with heavy infantry, like hoplites. </History> 26 <RequiredTechnology>town_phase</RequiredTechnology> 26 27 </Identity> 27 28 <Promotion> 28 29 <Entity>units/pers_infantry_spearman_a</Entity> -
binaries/data/mods/public/simulation/templates/units/pers_hero_cyrus.xml
9 9 Hero Aura: "Lead from the Front." Boosts attack of nearby cavalry units.</Tooltip> 10 10 <History>(559 BC - 530 BC) The son of a Median princess and the ruler of Anshan; justly called the 'Father of the Empire', Cyrus the Great conquered Media, Lydia, Babylonia and Bactria, thereby establishing the Persian Empire. He was also renown as a benevolent conqueror. Technically the second ruler of the Persians by that name, and so appears as Kurush II on his documents and coins. Kurush I was his grandfather.</History> 11 11 </Identity> 12 < TrainingQueue>12 <ProductionQueue> 13 13 <Entities datatype="tokens"> 14 14 units/pers_champion_infantry 15 15 </Entities> 16 </ TrainingQueue>16 </ProductionQueue> 17 17 <VisualActor> 18 18 <Actor>units/persians/hero_cyrus.xml</Actor> 19 19 </VisualActor> -
binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml
50 50 </SoundGroups> 51 51 </Sound> 52 52 <TerritoryDecay disable=""/> 53 < TrainingQueue>53 <ProductionQueue> 54 54 <Entities datatype="tokens"> 55 55 units/{civ}_ship_fishing 56 56 units/{civ}_ship_merchant 57 57 </Entities> 58 </ TrainingQueue>58 </ProductionQueue> 59 59 <Vision> 60 60 <Range>40</Range> 61 61 </Vision> -
binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml
42 42 <Radius>40</Radius> 43 43 <Weight>65536</Weight> 44 44 </TerritoryInfluence> 45 < TrainingQueue>45 <ProductionQueue> 46 46 <Entities datatype="tokens"> 47 47 units/{civ}_support_trader 48 48 </Entities> 49 </ TrainingQueue>49 </ProductionQueue> 50 50 <Vision> 51 51 <Range>32</Range> 52 52 </Vision> -
binaries/data/mods/public/simulation/templates/template_structure_civic_temple.xml
56 56 <Radius>40</Radius> 57 57 <Weight>65536</Weight> 58 58 </TerritoryInfluence> 59 < TrainingQueue>59 <ProductionQueue> 60 60 <Entities datatype="tokens"> 61 61 units/{civ}_support_healer_b 62 62 </Entities> 63 </ TrainingQueue>63 </ProductionQueue> 64 64 <Vision> 65 65 <Range>40</Range> 66 66 </Vision> -
binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
62 62 CivCentre 63 63 </Classes> 64 64 <Icon>structures/civic_centre.png</Icon> 65 <RequiredTechnology>town_phase</RequiredTechnology> 65 66 </Identity> 66 67 <Obstruction> 67 68 <Static width="30.0" depth="30.0"/> … … 82 83 <Radius>180</Radius> 83 84 <Weight>65536</Weight> 84 85 </TerritoryInfluence> 85 < TrainingQueue>86 <ProductionQueue> 86 87 <Entities datatype="tokens"> 87 88 units/{civ}_support_female_citizen 88 89 </Entities> 89 </TrainingQueue> 90 <Technologies datatype="tokens"> 91 town_phase 92 city_phase 93 plough 94 </Technologies> 95 </ProductionQueue> 90 96 <Vision> 91 97 <Range>90</Range> 92 98 </Vision> -
binaries/data/mods/public/simulation/templates/structures/rome_fortress.xml
5 5 <SpecificName>Castellum</SpecificName> 6 6 <History>Fortified auxillary camp.</History> 7 7 </Identity> 8 < TrainingQueue>8 <ProductionQueue> 9 9 <Entities datatype="tokens"> 10 10 units/rome_hero_marcellus 11 11 units/rome_hero_maximus … … 16 16 units/rome_mechanical_siege_scorpio 17 17 units/rome_mechanical_siege_ram 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/romans/fortress.xml</Actor> 22 22 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/rome_dock.xml
12 12 <Obstruction> 13 13 <Static width="20.0" depth="24.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/rome_ship_bireme 18 18 units/rome_ship_trireme 19 19 units/rome_ship_quinquereme 20 20 </Entities> 21 </ TrainingQueue>21 </ProductionQueue> 22 22 <VisualActor> 23 23 <Actor>structures/romans/dock.xml</Actor> 24 24 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/rome_corral.xml
12 12 <Obstruction> 13 13 <Static width="14" depth="20"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 gaia/fauna_goat 18 18 gaia/fauna_sheep 19 19 </Entities> 20 </ TrainingQueue>20 </ProductionQueue> 21 21 <VisualActor> 22 22 <FoundationActor>structures/fndn_2x4.xml</FoundationActor> 23 23 <Actor>structures/romans/corral.xml</Actor> -
binaries/data/mods/public/simulation/templates/structures/rome_civil_centre.xml
12 12 <Obstruction> 13 13 <Static width="37.0" depth="37.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/rome_infantry_swordsman_b 18 18 units/rome_infantry_javelinist_b 19 19 units/rome_cavalry_spearman_b 20 20 </Entities> 21 </ TrainingQueue>21 </ProductionQueue> 22 22 <VisualActor> 23 23 <FoundationActor>structures/fndn_8x8.xml</FoundationActor> 24 24 <Actor>structures/romans/civic_centre.xml</Actor> -
binaries/data/mods/public/simulation/templates/structures/rome_barracks.xml
18 18 <Obstruction> 19 19 <Static width="24.0" depth="24.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 units/rome_infantry_swordsman_b 24 24 units/rome_infantry_spearman_a 25 25 units/rome_infantry_javelinist_b 26 26 units/rome_cavalry_spearman_b 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <FoundationActor>structures/fndn_5x5.xml</FoundationActor> 31 31 <Actor>structures/romans/barracks.xml</Actor> -
binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml
68 68 <HealthDecayRate>5</HealthDecayRate> 69 69 </TerritoryDecay> 70 70 <TerritoryInfluence disable=""/> 71 < TrainingQueue>71 <ProductionQueue> 72 72 <Entities datatype="tokens"> 73 73 units/rome_infantry_swordsman_b 74 74 units/rome_infantry_spearman_a … … 78 78 units/rome_mechanical_siege_scorpio 79 79 units/rome_mechanical_siege_ram 80 80 </Entities> 81 </ TrainingQueue>81 </ProductionQueue> 82 82 <Vision> 83 83 <Range>60</Range> 84 84 </Vision> … … 86 86 <FoundationActor>structures/fndn_8x8.xml</FoundationActor> 87 87 <Actor>structures/romans/camp.xml</Actor> 88 88 </VisualActor> 89 </Entity> 90 No newline at end of file 89 </Entity> -
binaries/data/mods/public/simulation/templates/structures/pers_stables.xml
25 25 <Obstruction> 26 26 <Static width="18.0" depth="16.0"/> 27 27 </Obstruction> 28 < TrainingQueue>28 <ProductionQueue> 29 29 <Entities datatype="tokens"> 30 30 units/pers_cavalry_spearman_b 31 31 units/pers_cavalry_swordsman_b 32 32 units/pers_cavalry_javelinist_b 33 33 units/pers_cavalry_archer_b 34 34 </Entities> 35 </ TrainingQueue>35 </ProductionQueue> 36 36 <VisualActor> 37 37 <Actor>structures/persians/stables.xml</Actor> 38 38 <FoundationActor>structures/fndn_4x4.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/pers_sb2.xml
40 40 <Root>false</Root> 41 41 <Radius>38</Radius> 42 42 </TerritoryInfluence> 43 < TrainingQueue>43 <ProductionQueue> 44 44 <Entities datatype="tokens"> 45 45 units/pers_kardakes_hoplite 46 46 units/pers_kardakes_skirmisher 47 47 units/pers_war_elephant 48 48 </Entities> 49 </ TrainingQueue>49 </ProductionQueue> 50 50 <VisualActor> 51 51 <Actor>structures/persians/sb2.xml</Actor> 52 52 <FoundationActor>structures/fndn_6x6.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/pers_fortress.xml
12 12 <History>The Susa Chateau was a fortress in the administrative capital of Susa, which was reconstructed by a French archaeologist in 1890 with the use of original building material.</History> 13 13 <Tooltip>Train Champion Units and Construct Siege Rams.</Tooltip> 14 14 </Identity> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/pers_champion_cavalry 18 18 units/pers_mechanical_siege_ram 19 19 </Entities> 20 </ TrainingQueue>20 </ProductionQueue> 21 21 <VisualActor> 22 22 <Actor>structures/persians/fortress.xml</Actor> 23 23 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/pers_dock.xml
18 18 <Obstruction> 19 19 <Static width="23.0" depth="15.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 units/pers_ship_bireme 24 24 units/pers_ship_trireme 25 25 </Entities> 26 </ TrainingQueue>26 </ProductionQueue> 27 27 <VisualActor> 28 28 <Actor>structures/persians/dock.xml</Actor> 29 29 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/pers_corral.xml
18 18 <Obstruction> 19 19 <Static width="17.0" depth="11.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 gaia/fauna_goat 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/persians/corral.xml</Actor> 28 28 <FoundationActor>structures/fndn_4x2.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/pers_civil_centre.xml
12 12 <SpecificName>Xsacapava</SpecificName> 13 13 <History>Possibly of Median origin, the word 'satrapy' means province. Soon after coming to the throne, Darius the Great carried out a vast administrative reform, dividing the huge empire into 20 satrapies governed by satraps.</History> 14 14 </Identity> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/pers_infantry_spearman_b 18 18 units/pers_infantry_archer_b 19 19 units/pers_cavalry_javelinist_b 20 20 </Entities> 21 </ TrainingQueue>21 </ProductionQueue> 22 22 <VisualActor> 23 23 <Actor>structures/persians/civil_centre.xml</Actor> 24 24 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/pers_barracks.xml
17 17 <Tooltip>Levy citizen-infantry units.</Tooltip> 18 18 <Icon>structures/pers_barracks.png</Icon> 19 19 </Identity> 20 < TrainingQueue>20 <ProductionQueue> 21 21 <Entities datatype="tokens"> 22 22 units/pers_infantry_spearman_b 23 23 units/pers_infantry_javelinist_b 24 24 units/pers_infantry_archer_b 25 25 </Entities> 26 </ TrainingQueue>26 </ProductionQueue> 27 27 <VisualActor> 28 28 <Actor>structures/persians/barracks.xml</Actor> 29 29 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/pers_apadana.xml
32 32 <Root>true</Root> 33 33 <Radius>38</Radius> 34 34 </TerritoryInfluence> 35 < TrainingQueue>35 <ProductionQueue> 36 36 <Entities datatype="tokens"> 37 37 units/pers_hero_cyrus 38 38 units/pers_hero_darius 39 39 units/pers_hero_xerxes 40 40 units/pers_champion_infantry 41 41 </Entities> 42 </ TrainingQueue>42 </ProductionQueue> 43 43 <VisualActor> 44 44 <Actor>structures/persians/sb1_new.xml</Actor> 45 45 <FoundationActor>structures/fndn_6x6.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/iber_fortress.xml
19 19 <Obstruction> 20 20 <Static width="27.0" depth="27.0"/> 21 21 </Obstruction> 22 < TrainingQueue>22 <ProductionQueue> 23 23 <Entities datatype="tokens"> 24 24 units/iber_hero_caros 25 25 units/iber_hero_indibil … … 28 28 units/iber_champion_cavalry 29 29 units/iber_mechanical_siege_ram 30 30 </Entities> 31 </ TrainingQueue>31 </ProductionQueue> 32 32 <VisualActor> 33 33 <Actor>structures/iberians/fortress.xml</Actor> 34 34 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/iber_dock.xml
12 12 <Obstruction> 13 13 <Static width="14.0" depth="24.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/iber_ship_fire 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/iberians/dock.xml</Actor> 22 22 <FoundationActor>structures/fndn_dock_iber.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/iber_corral.xml
12 12 <Obstruction> 13 13 <Static width="14.0" depth="14.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 gaia/fauna_goat 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/iberians/corral.xml</Actor> 22 22 <FoundationActor>structures/fndn_4x4.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/iber_civil_centre.xml
5 5 <SpecificName>Oppidum</SpecificName> 6 6 <History>The Oppidum, plural Oppida (oh-PEE-dah), has a long history in the Iberian Peninsula. They were walled towns, dating back to even before the time period of the game and expanding greatly during it. They were usually built upon heights for better defensive purposes but sometimes right out on the plains, especially in the east where there may not have been heights at desirable locations near meandering rivers. This concept drawing is derived from an actual archeological site that has been excavated in the northeast of Spain having belonged to the Ilergete (ee-layer-HAY-tay) tribe as shown in the figure below and from the virtual reconstruction of the site at the museum located adjacent to it.</History> 7 7 </Identity> 8 < TrainingQueue>8 <ProductionQueue> 9 9 <Entities datatype="tokens"> 10 10 units/iber_infantry_swordsman_b 11 11 units/iber_infantry_javelinist_b 12 12 units/iber_cavalry_javelinist_b 13 13 </Entities> 14 </ TrainingQueue>14 </ProductionQueue> 15 15 <VisualActor> 16 16 <Actor>structures/iberians/civil_centre.xml</Actor> 17 17 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/iber_barracks.xml
11 11 <SpecificName>Cuartel</SpecificName> 12 12 <History>To the best of our knowledge, the Iberians did not have standing armies in the sense that we know of them elsewhere or of today, it is doubtful that they had specific structures designated as military centres; however as a game construct we show a modest structure wherein military related activities take place.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/iber_infantry_spearman_b 17 17 units/iber_infantry_swordsman_b … … 20 20 units/iber_cavalry_spearman_b 21 21 units/iber_cavalry_javelinist_b 22 22 </Entities> 23 </ TrainingQueue>23 </ProductionQueue> 24 24 <VisualActor> 25 25 <Actor>structures/iberians/barracks.xml</Actor> 26 26 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/hele_prytaneion.xml
34 34 <death>attack/destruction/building_collapse_large.xml</death> 35 35 </SoundGroups> 36 36 </Sound> 37 < TrainingQueue>37 <ProductionQueue> 38 38 <Entities datatype="tokens"> 39 39 units/hele_hero_alexander 40 40 units/hele_hero_demetrius … … 43 43 units/hele_hero_themistocles 44 44 units/hele_hero_xenophon 45 45 </Entities> 46 </ TrainingQueue>46 </ProductionQueue> 47 47 <VisualActor> 48 48 <Actor>structures/hellenes/tholos.xml</Actor> 49 49 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/hele_gymnasion.xml
33 33 <death>attack/destruction/building_collapse_large.xml</death> 34 34 </SoundGroups> 35 35 </Sound> 36 < TrainingQueue>36 <ProductionQueue> 37 37 <Entities datatype="tokens"> 38 38 units/hele_champion_cavalry_mace 39 39 units/hele_champion_infantry_mace 40 40 units/hele_champion_infantry_polis 41 41 units/hele_champion_swordsman_polis 42 42 </Entities> 43 </ TrainingQueue>43 </ProductionQueue> 44 44 <VisualActor> 45 45 <Actor>structures/hellenes/gymnasion.xml</Actor> 46 46 <FoundationActor>structures/fndn_6x6.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/hele_fortress.xml
19 19 <Obstruction> 20 20 <Static width="24.0" depth="26.0"/> 21 21 </Obstruction> 22 < TrainingQueue>22 <ProductionQueue> 23 23 <Entities datatype="tokens"> 24 24 units/hele_mechanical_siege_oxybeles 25 25 units/hele_mechanical_siege_lithobolos 26 26 units/hele_mechanical_siege_tower 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>structures/hellenes/fortress_new.xml</Actor> 31 31 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/hele_dock.xml
11 11 <SpecificName>Limḗn</SpecificName> 12 12 <History>Greece is a sea country, which is why some of the greatest Hellenic and Hellenistic cities like Ephesus, Corinth, Alexandria and Antioch were built by the sea. It should also be noted that all colonies during the Great Colonisation were thriving port centres, which traded with the local population.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/hele_ship_bireme 17 17 units/hele_ship_trireme 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/hellenes/dock.xml</Actor> 22 22 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/hele_corral.xml
18 18 <Obstruction> 19 19 <Static width="14.0" depth="14.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 gaia/fauna_goat 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/hellenes/corral.xml</Actor> 28 28 <FoundationActor>structures/fndn_3x3.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/hele_civil_centre.xml
11 11 <SpecificName>Agorā́</SpecificName> 12 12 <History>The most important place in most Classical Greek poleis, the Agora served many purposes; it was a place for public speeches and was the stage for civic life and commercial interests.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/hele_infantry_spearman_b 17 17 units/hele_infantry_javelinist_b 18 18 units/hele_cavalry_javelinist_b 19 19 </Entities> 20 </ TrainingQueue>20 </ProductionQueue> 21 21 <VisualActor> 22 22 <Actor>structures/hellenes/civic_centre_new.xml</Actor> 23 23 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/hele_barracks.xml
15 15 <SpecificName>Stratēgeîon</SpecificName> 16 16 <History>The Stratigeion was the main military headquarters, where important decisions were taken and plans for battles discussed by the Hellene Generals, or "Strategoi".</History> 17 17 </Identity> 18 < TrainingQueue>18 <ProductionQueue> 19 19 <Entities datatype="tokens"> 20 20 units/hele_infantry_spearman_b 21 21 units/hele_infantry_javelinist_b … … 24 24 units/hele_cavalry_swordsman_b 25 25 units/hele_cavalry_javelinist_b 26 26 </Entities> 27 </ TrainingQueue>27 </ProductionQueue> 28 28 <VisualActor> 29 29 <Actor>structures/hellenes/barracks.xml</Actor> 30 30 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/celt_kennel.xml
40 40 <Radius>20</Radius> 41 41 <Weight>65536</Weight> 42 42 </TerritoryInfluence> 43 < TrainingQueue>43 <ProductionQueue> 44 44 <Entities datatype="tokens"> 45 45 units/celt_war_dog_b 46 46 </Entities> 47 </ TrainingQueue>47 </ProductionQueue> 48 48 <VisualActor> 49 49 <Actor>structures/celts/kennel.xml</Actor> 50 50 <FoundationActor>structures/fndn_2x2.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/celt_fortress_g.xml
16 16 <death>attack/destruction/building_collapse_large.xml</death> 17 17 </SoundGroups> 18 18 </Sound> 19 < TrainingQueue>19 <ProductionQueue> 20 20 <Entities datatype="tokens"> 21 21 units/celt_hero_brennus 22 22 units/celt_hero_britomartus … … 25 25 units/celt_champion_infantry_gaul 26 26 units/celt_mechanical_siege_ram 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>structures/celts/fortress_gallic.xml</Actor> 31 31 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/celt_fortress_b.xml
29 29 <death>attack/destruction/building_collapse_large.xml</death> 30 30 </SoundGroups> 31 31 </Sound> 32 < TrainingQueue>32 <ProductionQueue> 33 33 <Entities datatype="tokens"> 34 34 units/celt_hero_boudicca 35 35 units/celt_hero_caratacos … … 38 38 units/celt_champion_infantry_brit 39 39 units/celt_mechanical_siege_ram 40 40 </Entities> 41 </ TrainingQueue>41 </ProductionQueue> 42 42 <Vision> 43 43 <Range>100</Range> 44 44 </Vision> -
binaries/data/mods/public/simulation/templates/structures/celt_dock.xml
15 15 <Obstruction> 16 16 <Static width="10.0" depth="22.0"/> 17 17 </Obstruction> 18 < TrainingQueue>18 <ProductionQueue> 19 19 <Entities datatype="tokens"> 20 20 units/celt_ship_trireme 21 21 </Entities> 22 </ TrainingQueue>22 </ProductionQueue> 23 23 <VisualActor> 24 24 <Actor>structures/celts/dock_new.xml</Actor> 25 25 <FoundationActor>structures/fndn_celt_dock.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/celt_corral.xml
12 12 <Obstruction> 13 13 <Static width="10.0" depth="20.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 gaia/fauna_sheep 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/celts/plot_corral.xml</Actor> 22 22 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/celt_civil_centre.xml
12 12 <Obstruction> 13 13 <Static width="25.0" depth="25.0"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 units/celt_infantry_spearman_b 18 18 units/celt_infantry_javelinist_b 19 19 units/celt_cavalry_javelinist_b 20 20 </Entities> 21 </ TrainingQueue>21 </ProductionQueue> 22 22 <VisualActor> 23 23 <Actor>structures/celts/civic_centre.xml</Actor> 24 24 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/celt_barracks.xml
14 14 <Obstruction> 15 15 <Static width="20.0" depth="20.0"/> 16 16 </Obstruction> 17 < TrainingQueue>17 <ProductionQueue> 18 18 <Entities datatype="tokens"> 19 19 units/celt_infantry_spearman_b 20 20 units/celt_infantry_javelinist_b … … 22 22 units/celt_cavalry_swordsman_b 23 23 units/celt_cavalry_javelinist_b 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/celts/barracks_new.xml</Actor> 28 28 <FoundationActor>structures/fndn_5x5.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/cart_temple.xml
18 18 <Obstruction> 19 19 <Static width="17.0" depth="30.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 units/cart_champion_infantry 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/carthaginians/temple_big.xml</Actor> 28 28 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_super_dock.xml
46 46 </Sound> 47 47 <TerritoryDecay disable=""/> 48 48 <TerritoryInfluence disable=""/> 49 < TrainingQueue>49 <ProductionQueue> 50 50 <Entities datatype="tokens"> 51 51 units/cart_ship_bireme 52 52 units/cart_ship_trireme 53 53 units/cart_ship_quinquereme 54 54 </Entities> 55 </ TrainingQueue>55 </ProductionQueue> 56 56 <Vision> 57 57 <Range>100</Range> 58 58 </Vision> -
binaries/data/mods/public/simulation/templates/structures/cart_fortress.xml
13 13 <Obstruction> 14 14 <Static width="26.0" depth="28.0"/> 15 15 </Obstruction> 16 < TrainingQueue>16 <ProductionQueue> 17 17 <Entities datatype="tokens"> 18 18 units/cart_hero_hamilcar 19 19 units/cart_hero_hannibal … … 22 22 units/cart_mechanical_siege_ballista 23 23 units/cart_mechanical_siege_oxybeles 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/carthaginians/fortress.xml</Actor> 28 28 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_embassy_italiote.xml
20 20 <Obstruction> 21 21 <Static width="11.0" depth="14.0"/> 22 22 </Obstruction> 23 < TrainingQueue>23 <ProductionQueue> 24 24 <Entities datatype="tokens"> 25 25 units/cart_infantry_swordsman_2_b 26 26 units/cart_cavalry_spearman_b 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>structures/carthaginians/embassy_italiote.xml</Actor> 31 31 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_embassy_iberian.xml
17 17 <Obstruction> 18 18 <Static width="16.0" depth="16.0"/> 19 19 </Obstruction> 20 < TrainingQueue>20 <ProductionQueue> 21 21 <Entities datatype="tokens"> 22 22 units/cart_infantry_javelinist_b 23 23 units/cart_infantry_slinger_b 24 24 units/cart_cavalry_swordsman_b 25 25 </Entities> 26 </ TrainingQueue>26 </ProductionQueue> 27 27 <VisualActor> 28 28 <Actor>structures/carthaginians/embassy_iberian.xml</Actor> 29 29 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_embassy_celtic.xml
24 24 <Obstruction> 25 25 <Static width="15.0" depth="12.0"/> 26 26 </Obstruction> 27 < TrainingQueue>27 <ProductionQueue> 28 28 <Entities datatype="tokens"> 29 29 units/cart_infantry_swordsman_b 30 30 units/cart_cavalry_swordsman_2_b 31 31 </Entities> 32 </ TrainingQueue>32 </ProductionQueue> 33 33 <VisualActor> 34 34 <Actor>structures/carthaginians/embassy_celtic.xml</Actor> 35 35 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_embassy.xml
21 21 <Obstruction> 22 22 <Static width="28.0" depth="28.0"/> 23 23 </Obstruction> 24 < TrainingQueue>24 <ProductionQueue> 25 25 <Entities datatype="tokens"> 26 26 units/cart_infantry_swordsman_b 27 27 units/cart_infantry_javelinist_b … … 29 29 units/cart_cavalry_swordsman_b 30 30 units/cart_cavalry_spearman_b 31 31 </Entities> 32 </ TrainingQueue>32 </ProductionQueue> 33 33 <VisualActor> 34 34 <Actor>structures/carthaginians/embassy.xml</Actor> 35 35 <FoundationActor>structures/fndn_5x5.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/cart_corral.xml
12 12 <Obstruction> 13 13 <Static width="16.0" depth="14.5"/> 14 14 </Obstruction> 15 < TrainingQueue>15 <ProductionQueue> 16 16 <Entities datatype="tokens"> 17 17 gaia/fauna_goat 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/carthaginians/corral.xml</Actor> 22 22 <FoundationActor>structures/fndn_3x3.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/structures/cart_civil_centre.xml
5 5 <SpecificName>Merkāz</SpecificName> 6 6 <History>Carthiginian's History</History> 7 7 </Identity> 8 < TrainingQueue>8 <ProductionQueue> 9 9 <Entities datatype="tokens"> 10 10 units/cart_infantry_spearman_b 11 11 units/cart_infantry_archer_b 12 12 units/cart_cavalry_javelinist_b 13 13 </Entities> 14 </ TrainingQueue>14 </ProductionQueue> 15 15 <VisualActor> 16 16 <Actor>structures/carthaginians/civil_centre.xml</Actor> 17 17 </VisualActor> -
binaries/data/mods/public/simulation/templates/structures/cart_barracks.xml
19 19 <Obstruction> 20 20 <Static width="22.0" depth="23.0"/> 21 21 </Obstruction> 22 < TrainingQueue>22 <ProductionQueue> 23 23 <Entities datatype="tokens"> 24 24 units/cart_infantry_spearman_b 25 25 units/cart_infantry_archer_b 26 26 units/cart_cavalry_javelinist_b 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>structures/carthaginians/barracks.xml</Actor> 31 31 <FoundationActor>structures/fndn_5x5.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/special/player.xml
10 10 </BuildLimits> 11 11 <Player/> 12 12 <StatisticsTracker/> 13 <TechnologyManager/> 13 14 </Entity> -
binaries/data/mods/public/simulation/templates/other/pers_inn.xml
21 21 <TerritoryInfluence> 22 22 <Radius>26</Radius> 23 23 </TerritoryInfluence> 24 < TrainingQueue>24 <ProductionQueue> 25 25 <Entities datatype="tokens"> 26 26 units/{civ}_support_female_citizen 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>props/structures/persians/alt_building_04.xml</Actor> 31 31 </VisualActor> -
binaries/data/mods/public/simulation/templates/other/pers_apartment_block.xml
21 21 <TerritoryInfluence> 22 22 <Radius>25</Radius> 23 23 </TerritoryInfluence> 24 < TrainingQueue>24 <ProductionQueue> 25 25 <Entities datatype="tokens"> 26 26 units/{civ}_support_female_citizen 27 27 </Entities> 28 </ TrainingQueue>28 </ProductionQueue> 29 29 <VisualActor> 30 30 <Actor>props/structures/persians/alt_building_03.xml</Actor> 31 31 </VisualActor> -
binaries/data/mods/public/simulation/templates/other/hellenic_royal_stoa.xml
48 48 <Radius>40</Radius> 49 49 <Weight>65536</Weight> 50 50 </TerritoryInfluence> 51 < TrainingQueue>51 <ProductionQueue> 52 52 <Entities datatype="tokens"> 53 53 units/thrace_black_cloak 54 54 units/mace_thorakites 55 55 units/mace_thureophoros 56 56 </Entities> 57 </ TrainingQueue>57 </ProductionQueue> 58 58 <Vision> 59 59 <Range>40</Range> 60 60 <RetainInFog>true</RetainInFog> -
binaries/data/mods/public/simulation/templates/other/celt_tavern.xml
39 39 <Radius>32</Radius> 40 40 <Weight>65536</Weight> 41 41 </TerritoryInfluence> 42 < TrainingQueue>42 <ProductionQueue> 43 43 <Entities datatype="tokens"> 44 44 units/celt_fanatic 45 45 </Entities> 46 </ TrainingQueue>46 </ProductionQueue> 47 47 <VisualActor> 48 48 <Actor>structures/celts/tavern.xml</Actor> 49 49 <FoundationActor>structures/fndn_4x4.xml</FoundationActor> -
binaries/data/mods/public/simulation/templates/other/celt_homestead.xml
35 35 <ResourceDropsite> 36 36 <Types>food wood stone metal</Types> 37 37 </ResourceDropsite> 38 < TrainingQueue>38 <ProductionQueue> 39 39 <Entities datatype="tokens"> 40 40 units/celt_cavalry_javelinist_b 41 41 units/celt_infantry_javelinist_b 42 42 units/celt_infantry_spearman_b 43 43 </Entities> 44 </ TrainingQueue>44 </ProductionQueue> 45 45 <TerritoryInfluence> 46 46 <Radius>100</Radius> 47 47 <Weight>65536</Weight> -
binaries/data/mods/public/simulation/templates/other/cart_tophet.xml
34 34 <Static width="22.0" depth="24.0"/> 35 35 </Obstruction> 36 36 <TerritoryDecay disable=""/> 37 < TrainingQueue>37 <ProductionQueue> 38 38 <Entities datatype="tokens"> 39 39 units/cart_sacred_band_cavalry 40 40 </Entities> 41 </ TrainingQueue>41 </ProductionQueue> 42 42 <Vision> 43 43 <Range>40</Range> 44 44 </Vision> -
binaries/data/mods/public/simulation/helpers/Commands.js
121 121 // Verify that the building can be controlled by the player 122 122 if (CanControlUnit(cmd.entity, player, controlAllUnits)) 123 123 { 124 var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue); 125 if (queue) 126 queue.AddBatch(cmd.template, +cmd.count, cmd.metadata); 124 var cmpTechMan = QueryOwnerInterface(cmd.entity, IID_TechnologyManager); 125 // TODO: Enable this check once the AI gets technology support 126 if (cmpTechMan.CanProduce(cmd.template) || true) 127 { 128 var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue); 129 if (queue) 130 queue.AddBatch(cmd.template, "unit", +cmd.count, cmd.metadata); 131 } 132 else if (g_DebugCommands) 133 { 134 warn("Invalid command: training requires unresearched technology: " + uneval(cmd)); 135 } 127 136 } 128 137 else if (g_DebugCommands) 129 138 { … … 131 140 } 132 141 break; 133 142 134 case " stop-train":143 case "research": 135 144 // Verify that the building can be controlled by the player 136 145 if (CanControlUnit(cmd.entity, player, controlAllUnits)) 137 146 { 138 var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue); 147 var cmpTechMan = QueryOwnerInterface(cmd.entity, IID_TechnologyManager); 148 // TODO: Enable this check once the AI gets technology support 149 if (cmpTechMan.CanResearch(cmd.template) || true) 150 { 151 var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue); 152 if (queue) 153 queue.AddBatch(cmd.template, "technology"); 154 } 155 else if (g_DebugCommands) 156 { 157 warn("Invalid command: Requirements to research technology are not met: " + uneval(cmd)); 158 } 159 } 160 else if (g_DebugCommands) 161 { 162 warn("Invalid command: research building cannot be controlled by player "+player+": "+uneval(cmd)); 163 } 164 break; 165 166 case "stop-production": 167 // Verify that the building can be controlled by the player 168 if (CanControlUnit(cmd.entity, player, controlAllUnits)) 169 { 170 var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue); 139 171 if (queue) 140 172 queue.RemoveBatch(cmd.id); 141 173 } 142 174 else if (g_DebugCommands) 143 175 { 144 warn("Invalid command: trainingbuilding cannot be controlled by player "+player+": "+uneval(cmd));176 warn("Invalid command: production building cannot be controlled by player "+player+": "+uneval(cmd)); 145 177 } 146 178 break; 147 179 … … 219 251 Engine.DestroyEntity(ent); 220 252 break; 221 253 } 254 255 var cmpTechMan = QueryPlayerIDInterface(player, IID_TechnologyManager); 256 // TODO: Enable this check once the AI gets technology support 257 if (!cmpTechMan.CanProduce(cmd.template) && false) 258 { 259 if (g_DebugCommands) 260 { 261 warn("Invalid command: required technology check failed for player "+player+": "+uneval(cmd)); 262 } 222 263 264 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 265 cmpGuiInterface.PushNotification({ "player": player, "message": "Building's technology requirements are not met." }); 266 267 // Remove the foundation because the construction was aborted 268 Engine.DestroyEntity(ent); 269 } 270 223 271 // TODO: AI has no visibility info 224 272 if (!cmpPlayer.IsAI()) 225 273 { -
binaries/data/mods/public/simulation/data/technologies/village_phase.json
1 { 2 "genericName": "Village Phase", 3 "description": "Advances from a small village to a bustling town, ready to expand rapidly.", 4 "autoResearch": true, 5 "icon": "technologies/town_phase.png", 6 "researchTime": 10, 7 "tooltip": "Advance to Town Phase" 8 } -
binaries/data/mods/public/simulation/data/technologies/town_phase.json
1 { 2 "genericName": "Town Phase", 3 "description": "Advances from a small village to a bustling town, ready to expand rapidly.", 4 "cost": {"food": 100, "wood": 100, "stone": 0, "metal": 50}, 5 "supercedes": "village_phase", 6 "icon": "technologies/town_phase.png", 7 "researchTime": 10, 8 "tooltip": "Advance to Town Phase" 9 } -
binaries/data/mods/public/simulation/data/technologies/plough.json
1 { 2 "genericName": "Plough", 3 "description": "A horse drawn instrument to turn the sod", 4 "cost": {"food": 0, "wood": 0, "stone": 0, "metal": 0}, 5 "requirements": {"tech": "town_phase"}, 6 "requirementsTooltip": "Requires Town Phase", 7 "icon": "technologies/plough.png", 8 "researchTime": 10, 9 "tooltip": "Discover the Plough", 10 "modifications": [{"value": "ResourceGatherer/Rates/food.grain", "multiplier": 15}], 11 "affects": ["Female"] 12 } -
binaries/data/mods/public/simulation/data/technologies/city_phase.json
1 { 2 "genericName": "City Phase", 3 "description": "Advances from a bustling town to a veritable metropolis, full of the wonders of modern technology.", 4 "cost": {"food": 0, "wood": 0, "stone": 50, "metal": 0}, 5 "supercedes": "town_phase", 6 "icon": "technologies/city_phase.png", 7 "researchTime": 10, 8 "tooltip": "Advance to City Phase" 9 } -
binaries/data/mods/public/simulation/data/technologies/town_phase.json
1 { 2 "genericName": "Town Phase", 3 "description": "Advances from a small village to a bustling town, ready to expand rapidly.", 4 "cost": {"food": 100, "wood": 100, "stone": 0, "metal": 50}, 5 "supercedes": "village_phase", 6 "icon": "technologies/town_phase.png", 7 "researchTime": 10, 8 "tooltip": "Advance to Town Phase" 9 } -
binaries/data/mods/public/simulation/data/technologies/city_phase.json
1 { 2 "genericName": "City Phase", 3 "description": "Advances from a bustling town to a veritable metropolis, full of the wonders of modern technology.", 4 "cost": {"food": 0, "wood": 0, "stone": 50, "metal": 0}, 5 "supercedes": "town_phase", 6 "icon": "technologies/city_phase.png", 7 "researchTime": 10, 8 "tooltip": "Advance to City Phase" 9 } -
binaries/data/mods/public/simulation/data/technologies/plough.json
1 { 2 "genericName": "Plough", 3 "description": "A horse drawn instrument to turn the sod", 4 "cost": {"food": 0, "wood": 0, "stone": 0, "metal": 0}, 5 "requirements": {"tech": "town_phase"}, 6 "requirementsTooltip": "Requires Town Phase", 7 "icon": "technologies/plough.png", 8 "researchTime": 10, 9 "tooltip": "Discover the Plough", 10 "modifications": [{"value": "ResourceGatherer/Rates/food.grain", "multiplier": 15}], 11 "affects": ["Female"] 12 } -
binaries/data/mods/public/simulation/data/technologies/village_phase.json
1 { 2 "genericName": "Village Phase", 3 "description": "Advances from a small village to a bustling town, ready to expand rapidly.", 4 "autoResearch": true, 5 "icon": "technologies/town_phase.png", 6 "researchTime": 10, 7 "tooltip": "Advance to Town Phase" 8 } -
binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
11 11 Engine.LoadComponentScript("interfaces/ResourceDropsite.js"); 12 12 Engine.LoadComponentScript("interfaces/ResourceGatherer.js"); 13 13 Engine.LoadComponentScript("interfaces/ResourceSupply.js"); 14 Engine.LoadComponentScript("interfaces/ TrainingQueue.js");14 Engine.LoadComponentScript("interfaces/ProductionQueue.js"); 15 15 Engine.LoadComponentScript("interfaces/Trader.js") 16 16 Engine.LoadComponentScript("interfaces/Timer.js"); 17 17 Engine.LoadComponentScript("interfaces/StatisticsTracker.js"); … … 57 57 GetPopulationLimit: function() { return 20; }, 58 58 GetMaxPopulation: function() { return 200; }, 59 59 GetResourceCounts: function() { return { food: 100 }; }, 60 IsTraining QueueBlocked: function() { return false; },60 IsTrainingBlocked: function() { return false; }, 61 61 GetState: function() { return "active"; }, 62 62 GetTeam: function() { return -1; }, 63 63 GetDiplomacy: function() { return [-1, 1]; }, … … 104 104 GetPopulationLimit: function() { return 30; }, 105 105 GetMaxPopulation: function() { return 300; }, 106 106 GetResourceCounts: function() { return { food: 200 }; }, 107 IsTraining QueueBlocked: function() { return false; },107 IsTrainingBlocked: function() { return false; }, 108 108 GetState: function() { return "active"; }, 109 109 GetTeam: function() { return -1; }, 110 110 GetDiplomacy: function() { return [-1, 1]; }, … … 156 156 popLimit: 20, 157 157 popMax: 200, 158 158 resourceCounts: { food: 100 }, 159 training QueueBlocked: false,159 trainingBlocked: false, 160 160 state: "active", 161 161 team: -1, 162 162 phase: "", … … 173 173 popLimit: 30, 174 174 popMax: 300, 175 175 resourceCounts: { food: 200 }, 176 training QueueBlocked: false,176 trainingBlocked: false, 177 177 state: "active", 178 178 team: -1, 179 179 phase: "village", … … 197 197 popLimit: 20, 198 198 popMax: 200, 199 199 resourceCounts: { food: 100 }, 200 training QueueBlocked: false,200 trainingBlocked: false, 201 201 state: "active", 202 202 team: -1, 203 203 phase: "", … … 230 230 popLimit: 30, 231 231 popMax: 300, 232 232 resourceCounts: { food: 200 }, 233 training QueueBlocked: false,233 trainingBlocked: false, 234 234 state: "active", 235 235 team: -1, 236 236 phase: "village", -
binaries/data/mods/public/simulation/components/interfaces/TrainingQueue.js
1 Engine.RegisterInterface("TrainingQueue");2 3 // Message of the form { } (use GetQueue if you want the current details),4 // sent to the current entity whenever the training queue changes.5 Engine.RegisterMessageType("TrainingQueueChanged");6 7 // Message of the form { entities: [id, ...], metadata: ... }8 // sent to the current entity whenever a unit has been trained.9 Engine.RegisterMessageType("TrainingFinished"); -
binaries/data/mods/public/simulation/components/interfaces/TechnologyTemplateManager.js
1 Engine.RegisterInterface("TechnologyTemplateManager"); 2 No newline at end of file -
binaries/data/mods/public/simulation/components/interfaces/TechnologyManager.js
1 Engine.RegisterInterface("TechnologyManager"); 2 3 // Message of the form { "component": "Attack", "player": 3 } 4 // Sent when a new technology is researched which modifies a component 5 Engine.RegisterMessageType("TechnologyModificationChange"); -
binaries/data/mods/public/simulation/components/interfaces/ProductionQueue.js
1 Engine.RegisterInterface(" TrainingQueue");1 Engine.RegisterInterface("ProductionQueue"); 2 2 3 3 // Message of the form { } (use GetQueue if you want the current details), 4 4 // sent to the current entity whenever the training queue changes. 5 Engine.RegisterMessageType(" TrainingQueueChanged");5 Engine.RegisterMessageType("ProductionQueueChanged"); 6 6 7 7 // Message of the form { entities: [id, ...], metadata: ... } 8 8 // sent to the current entity whenever a unit has been trained. -
binaries/data/mods/public/simulation/components/TrainingQueue.js
1 var g_ProgressInterval = 1000;2 const MAX_QUEUE_SIZE = 16;3 4 function TrainingQueue() {}5 6 TrainingQueue.prototype.Schema =7 "<a:help>Allows the building to train new units.</a:help>" +8 "<a:example>" +9 "<Entities datatype='tokens'>" +10 "\n units/{civ}_support_female_citizen\n units/{civ}_support_trader\n units/celt_infantry_spearman_b\n " +11 "</Entities>" +12 "</a:example>" +13 "<element name='Entities' a:help='Space-separated list of entity template names that this building can train. The special string \"{civ}\" will be automatically replaced by the building's four-character civ code'>" +14 "<attribute name='datatype'>" +15 "<value>tokens</value>" +16 "</attribute>" +17 "<text/>" +18 "</element>";19 20 TrainingQueue.prototype.Init = function()21 {22 this.nextID = 1;23 24 this.queue = [];25 // Queue items are:26 // {27 // "id": 1,28 // "player": 1, // who paid for this batch; we need this to cope with refunds cleanly29 // "template": "units/example",30 // "count": 10,31 // "resources": { "wood": 100, ... }, // resources per unit, multiply by count to get total32 // "population": 1, // population per unit, multiply by count to get total33 // "trainingStarted": false, // true iff we have reserved population34 // "timeTotal": 15000, // msecs35 // "timeRemaining": 10000, // msecs36 // }37 38 this.timer = undefined; // g_ProgressInterval msec timer, active while the queue is non-empty39 40 this.entityCache = [];41 this.spawnNotified = false;42 };43 44 /*45 * Returns list of entities that can be trained by this building.46 */47 TrainingQueue.prototype.GetEntitiesList = function()48 {49 var string = this.template.Entities._string;50 51 // Replace the "{civ}" codes with this entity's civ ID52 var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);53 if (cmpIdentity)54 string = string.replace(/\{civ\}/g, cmpIdentity.GetCiv());55 56 return string.split(/\s+/);57 };58 59 /*60 * Adds a new batch of identical units to the training queue.61 */62 TrainingQueue.prototype.AddBatch = function(templateName, count, metadata)63 {64 // TODO: there should probably be a limit on the number of queued batches65 // TODO: there should be a way for the GUI to determine whether it's going66 // to be possible to add a batch (based on resource costs and length limits)67 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);68 69 if (this.queue.length < MAX_QUEUE_SIZE)70 {71 // Find the template data so we can determine the build costs72 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);73 var template = cmpTempMan.GetTemplate(templateName);74 if (!template)75 return;76 77 // Apply a time discount to larger batches.78 // TODO: work out what equation we should use here.79 var timeMult = Math.pow(count, 0.7);80 81 var time = timeMult * template.Cost.BuildTime;82 83 var totalCosts = {};84 for each (var r in ["food", "wood", "stone", "metal"])85 totalCosts[r] = Math.floor(count * template.Cost.Resources[r]);86 87 var population = template.Cost.Population;88 89 // TrySubtractResources should report error to player (they ran out of resources)90 if (!cmpPlayer.TrySubtractResources(totalCosts))91 return;92 93 this.queue.push({94 "id": this.nextID++,95 "player": cmpPlayer.GetPlayerID(),96 "template": templateName,97 "count": count,98 "metadata": metadata,99 "resources": deepcopy(template.Cost.Resources), // need to copy to avoid serialization problems100 "population": population,101 "trainingStarted": false,102 "timeTotal": time*1000,103 "timeRemaining": time*1000,104 });105 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });106 107 // If this is the first item in the queue, start the timer108 if (!this.timer)109 {110 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);111 this.timer = cmpTimer.SetTimeout(this.entity, IID_TrainingQueue, "ProgressTimeout", g_ProgressInterval, {});112 }113 }114 else115 {116 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "The training queue is full."};117 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);118 cmpGUIInterface.PushNotification(notification);119 }120 };121 122 /*123 * Removes an existing batch of units from the training queue.124 * Refunds resource costs and population reservations.125 */126 TrainingQueue.prototype.RemoveBatch = function(id)127 {128 // Destroy any cached entities (those which didn't spawn for some reason)129 for (var i = 0; i < this.entityCache.length; ++i)130 {131 Engine.DestroyEntity(this.entityCache[i]);132 }133 this.entityCache = [];134 135 for (var i = 0; i < this.queue.length; ++i)136 {137 var item = this.queue[i];138 if (item.id != id)139 continue;140 141 // Now we've found the item to remove142 143 var cmpPlayer = QueryPlayerIDInterface(item.player, IID_Player);144 145 // Refund the resource cost for this batch146 var totalCosts = {};147 for each (var r in ["food", "wood", "stone", "metal"])148 totalCosts[r] = Math.floor(item.count * item.resources[r]);149 150 cmpPlayer.AddResources(totalCosts);151 152 // Remove reserved population slots if necessary153 if (item.trainingStarted)154 cmpPlayer.UnReservePopulationSlots(item.population * item.count);155 156 // Remove from the queue157 // (We don't need to remove the timer - it'll expire if it discovers the queue is empty)158 this.queue.splice(i, 1);159 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });160 161 return;162 }163 };164 165 /*166 * Returns basic data from all batches in the training queue.167 */168 TrainingQueue.prototype.GetQueue = function()169 {170 var out = [];171 for each (var item in this.queue)172 {173 out.push({174 "id": item.id,175 "template": item.template,176 "count": item.count,177 "progress": 1-(item.timeRemaining/item.timeTotal),178 "metadata": item.metadata,179 });180 }181 return out;182 };183 184 /*185 * Removes all existing batches from the queue.186 */187 TrainingQueue.prototype.ResetQueue = function()188 {189 // Empty the training queue and refund all the resource costs190 // to the player. (This is to avoid players having to micromanage their191 // buildings' queues when they're about to be destroyed or captured.)192 193 while (this.queue.length)194 this.RemoveBatch(this.queue[0].id);195 };196 197 TrainingQueue.prototype.OnOwnershipChanged = function(msg)198 {199 if (msg.from != -1)200 {201 // Unset flag that previous owner's training queue may be blocked202 var cmpPlayer = QueryPlayerIDInterface(msg.from, IID_Player);203 if (cmpPlayer && this.queue.length > 0)204 cmpPlayer.UnBlockTrainingQueue();205 }206 207 // Reset the training queue whenever the owner changes.208 // (This should prevent players getting surprised when they capture209 // an enemy building, and then loads of the enemy's civ's soldiers get210 // created from it. Also it means we don't have to worry about211 // updating the reserved pop slots.)212 this.ResetQueue();213 };214 215 TrainingQueue.prototype.OnDestroy = function()216 {217 // Reset the queue to refund any resources218 this.ResetQueue();219 220 if (this.timer)221 {222 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);223 cmpTimer.CancelTimer(this.timer);224 }225 };226 227 /*228 * This function creates the entities and places them in world if possible.229 * returns the number of successfully spawned entities.230 */231 TrainingQueue.prototype.SpawnUnits = function(templateName, count, metadata)232 {233 var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint);234 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);235 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);236 var cmpRallyPoint = Engine.QueryInterface(this.entity, IID_RallyPoint);237 238 var spawnedEnts = [];239 240 if (this.entityCache.length == 0)241 {242 // We need entities to test spawning, but we don't want to waste resources,243 // so only create them once and use as needed244 for (var i = 0; i < count; ++i)245 {246 this.entityCache.push(Engine.AddEntity(templateName));247 }248 }249 250 for (var i = 0; i < count; ++i)251 {252 var ent = this.entityCache[0];253 var pos = cmpFootprint.PickSpawnPoint(ent);254 if (pos.y < 0)255 {256 // Fail: there wasn't any space to spawn the unit257 break;258 }259 else260 {261 // Successfully spawned262 var cmpNewPosition = Engine.QueryInterface(ent, IID_Position);263 cmpNewPosition.JumpTo(pos.x, pos.z);264 // TODO: what direction should they face in?265 266 var cmpNewOwnership = Engine.QueryInterface(ent, IID_Ownership);267 cmpNewOwnership.SetOwner(cmpOwnership.GetOwner());268 269 var cmpPlayerStatisticsTracker = QueryOwnerInterface(this.entity, IID_StatisticsTracker);270 cmpPlayerStatisticsTracker.IncreaseTrainedUnitsCounter();271 272 // Play a sound, but only for the first in the batch (to avoid nasty phasing effects)273 if (spawnedEnts.length == 0)274 PlaySound("trained", ent);275 276 this.entityCache.shift();277 spawnedEnts.push(ent);278 }279 }280 281 if (spawnedEnts.length > 0)282 {283 // If a rally point is set, walk towards it (in formation) using a suitable command based on where the284 // rally point is placed.285 if (cmpRallyPoint)286 {287 var rallyPos = cmpRallyPoint.GetPosition();288 if (rallyPos)289 {290 ProcessCommand(cmpOwnership.GetOwner(), GetRallyPointCommand(cmpRallyPoint, spawnedEnts));291 }292 }293 294 Engine.PostMessage(this.entity, MT_TrainingFinished, {295 "entities": spawnedEnts,296 "owner": cmpOwnership.GetOwner(),297 "metadata": metadata,298 });299 }300 301 return spawnedEnts.length;302 };303 304 /*305 * Increments progress on the first batch in the training queue, and blocks the306 * queue if population limit is reached or some units failed to spawn.307 */308 TrainingQueue.prototype.ProgressTimeout = function(data)309 {310 // Allocate the 1000msecs to as many queue items as it takes311 // until we've used up all the time (so that we work accurately312 // with items that take fractions of a second)313 var time = g_ProgressInterval;314 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);315 316 while (time > 0 && this.queue.length)317 {318 var item = this.queue[0];319 if (!item.trainingStarted)320 {321 // Batch's training hasn't started yet.322 // Try to reserve the necessary population slots323 if (!cmpPlayer.TryReservePopulationSlots(item.population * item.count))324 {325 // No slots available - don't train this batch now326 // (we'll try again on the next timeout)327 328 // Set flag that training queue is blocked329 cmpPlayer.BlockTrainingQueue();330 break;331 }332 333 // Unset flag that training queue is blocked334 cmpPlayer.UnBlockTrainingQueue();335 336 item.trainingStarted = true;337 }338 339 // If we won't finish the batch now, just update its timer340 if (item.timeRemaining > time)341 {342 item.timeRemaining -= time;343 break;344 }345 346 var numSpawned = this.SpawnUnits(item.template, item.count, item.metadata);347 if (numSpawned == item.count)348 {349 // All entities spawned, this batch finished350 cmpPlayer.UnReservePopulationSlots(item.population * numSpawned);351 time -= item.timeRemaining;352 this.queue.shift();353 // Unset flag that training queue is blocked354 cmpPlayer.UnBlockTrainingQueue();355 this.spawnNotified = false;356 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });357 }358 else359 {360 if (numSpawned > 0)361 {362 // Only partially finished363 cmpPlayer.UnReservePopulationSlots(item.population * numSpawned);364 item.count -= numSpawned;365 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });366 }367 368 // Some entities failed to spawn369 // Set flag that training queue is blocked370 cmpPlayer.BlockTrainingQueue();371 372 if (!this.spawnNotified)373 {374 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);375 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Can't find free space to spawn trained units" };376 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);377 cmpGUIInterface.PushNotification(notification);378 this.spawnNotified = true;379 }380 break;381 }382 }383 384 // If the queue's empty, delete the timer, else repeat it385 if (this.queue.length == 0)386 {387 this.timer = undefined;388 389 // Unset flag that training queue is blocked390 // (This might happen when the player unqueues all batches)391 cmpPlayer.UnBlockTrainingQueue();392 }393 else394 {395 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);396 this.timer = cmpTimer.SetTimeout(this.entity, IID_TrainingQueue, "ProgressTimeout", g_ProgressInterval, data);397 }398 }399 400 Engine.RegisterComponentType(IID_TrainingQueue, "TrainingQueue", TrainingQueue); -
binaries/data/mods/public/simulation/components/TechnologyTemplateManager.js
1 /** 2 * System component which loads the technology data files 3 */ 4 function TechnologyTemplateManager() {} 5 6 TechnologyTemplateManager.prototype.Schema = 7 "<a:component type='system'/><empty/>"; 8 9 TechnologyTemplateManager.prototype.Init = function() 10 { 11 this.allTechs = {}; 12 var techNames = this.ListAllTechs(); 13 for (i in techNames) 14 this.GetTemplate(techNames[i]); 15 }; 16 17 TechnologyTemplateManager.prototype.GetTemplate = function(template) 18 { 19 if (!this.allTechs[template]) 20 { 21 this.allTechs[template] = Engine.ReadJSONFile("technologies/" + template + ".json"); 22 if (! this.allTechs[template]) 23 error("Failed to load technology \"" + template + "\""); 24 } 25 26 return this.allTechs[template]; 27 }; 28 29 TechnologyTemplateManager.prototype.ListAllTechs = function() 30 { 31 return Engine.FindAllTechnologyTemplates(); 32 } 33 34 TechnologyTemplateManager.prototype.GetAllTechs = function() 35 { 36 return this.allTechs; 37 } 38 39 Engine.RegisterComponentType(IID_TechnologyTemplateManager, "TechnologyTemplateManager", TechnologyTemplateManager); 40 No newline at end of file -
binaries/data/mods/public/simulation/components/TechnologyManager.js
1 function TechnologyManager() {} 2 3 TechnologyManager.prototype.Schema = 4 "<a:component type='system'/><empty/>"; 5 6 TechnologyManager.prototype.Init = function () 7 { 8 var cmpTechTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TechnologyTemplateManager); 9 this.allTechs = cmpTechTempMan.GetAllTechs(); 10 this.researchedTechs = {}; // technologies which have been researched 11 this.inProgressTechs = {}; // technologies which are being researched currently 12 13 // This stores the modifications to unit stats from researched technologies 14 // Example data: {"ResourceGatherer/Rates/food.grain": [ {"multiplier": 1.15, "affects": ["Female", "Infantry Swordsman"]}, 15 // {"add": 2} ]} 16 this.modifications = {}; 17 18 // Some technologies are automatically researched when their conditions are met. They have no cost and are 19 // researched instantly. This allows civ bonuses and more complicated technologies. 20 this.autoResearchTech = {}; 21 for (var key in this.allTechs) 22 { 23 if (this.allTechs[key].autoResearch) 24 this.autoResearchTech[key] = this.allTechs[key]; 25 } 26 27 this._UpdateAutoResearch(); 28 }; 29 30 // This function checks if the requirements of any autoresearch techs are met and if they are it researches them 31 TechnologyManager.prototype._UpdateAutoResearch = function () 32 { 33 for (var key in this.autoResearchTech) 34 { 35 if (this.CanResearch(key)) 36 { 37 delete this.autoResearchTech[key]; 38 this.ResearchTechnology(key); 39 return; // We will have recursively handled any knock-on effects so can just return 40 } 41 } 42 } 43 44 TechnologyManager.prototype.GetTechnologyTemplate = function (tech) 45 { 46 return this.allTechs[tech]; 47 }; 48 49 // This function checks an entity template to see if it's technology requirements have been met 50 TechnologyManager.prototype.CanProduce = function (templateName) 51 { 52 var cmpTempManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 53 var template = cmpTempManager.GetTemplate(templateName); 54 55 if (template.Identity && template.Identity.RequiredTechnology) 56 return this.IsTechnologyResearched(template.Identity.RequiredTechnology); 57 else 58 return true; // If there is no required technology then this entity can be produced 59 }; 60 61 TechnologyManager.prototype.IsTechnologyResearched = function (tech) 62 { 63 return (this.researchedTechs[tech] !== undefined); 64 }; 65 66 // Checks the requirements for a technology to see if it can be researched at the current time 67 TechnologyManager.prototype.CanResearch = function (tech) 68 { 69 var template = this.GetTechnologyTemplate(tech); 70 if (!template) 71 return false; 72 73 var ret = true; 74 75 // The technology which this technology supercedes is required 76 if (template.supercedes) 77 ret = ret && this.IsTechnologyResearched(template.supercedes); 78 79 ret = ret && this._CheckTechnologyRequirements(template.requirements); 80 81 return ret; 82 }; 83 84 TechnologyManager.prototype._CheckTechnologyRequirements = function (reqs) 85 { 86 // If there are no requirements then all requirements are met 87 if (!reqs) 88 return true; 89 90 if (reqs.tech) 91 { 92 return this.IsTechnologyResearched(reqs.tech); 93 } 94 else if (reqs.all) 95 { 96 var ret = true; 97 for (var i = 0; i < reqs.all.length; i++) 98 { 99 ret = ret && this._CheckTechnologyRequirements(reqs.all[i]); 100 } 101 return ret; 102 } 103 else if (reqs.any) 104 { 105 for (var i = 0; i < reqs.any.length; i++) 106 { 107 if (this._CheckTechnologyRequirements(reqs.any[i])) 108 return true; 109 } 110 return false 111 } 112 113 // The technologies requirements are not a recognised format 114 error("Bad requirements " + uneval(reqs)); 115 return false; 116 }; 117 118 // Marks a technology as researched. Note that this does not verify that the requirements are met. 119 TechnologyManager.prototype.ResearchTechnology = function (tech) 120 { 121 this.StoppedResearch(tech); // The tech is no longer being currently researched 122 123 var template = this.GetTechnologyTemplate(tech); 124 if (template) 125 { 126 var modifiedComponents = {}; 127 this.researchedTechs[tech] = template; 128 // store the modifications in an easy to access structure 129 if (template.modifications) 130 { 131 var affects = []; 132 if (template.affects && template.affects.length > 0) 133 { 134 for (var i in template.affects) 135 { 136 // Put the list of classes into an array for convenient access 137 affects.push(template.affects[i].split(" ")); 138 } 139 } 140 else 141 { 142 affects.push([]); 143 } 144 145 // We add an item to this.modifications for every 146 for (var i in template.modifications) 147 { 148 var modification = template.modifications[i]; 149 if (!this.modifications[modification.value]) 150 this.modifications[modification.value] = []; 151 152 var mod = {"affects": affects}; 153 // copy the modification data into our new data structure 154 for (var j in modification) 155 if (j !== "value") 156 mod[j] = modification[j] 157 158 this.modifications[modification.value].push(mod); 159 modifiedComponents[modification.value.split("/")[0]] = true; 160 } 161 } 162 163 var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player); 164 var player = cmpPlayer.GetPlayerID(); 165 166 for (var component in modifiedComponents) 167 Engine.BroadcastMessage(MT_TechnologyModificationChange, { "component": component, "player": player }); 168 169 this._UpdateAutoResearch(); 170 } 171 else 172 { 173 error("Tried to research invalid techonology: " + uneval(tech)); 174 } 175 }; 176 177 TechnologyManager.prototype.ApplyModifications = function(valueName, curValue, ent) 178 { 179 // Get all modifications to this value 180 var modifications = this.modifications[valueName]; 181 if (!modifications) // no modifications so return the orignal value 182 return curValue; 183 184 // Get the classes which this entity belongs to 185 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 186 var classes = cmpIdentity.GetClassesList(); 187 188 var retValue = +curValue; 189 190 for (var i in modifications) 191 { 192 var modification = modifications[i]; 193 var applies = false; 194 // See if any of the lists of classes matches this entity 195 for (var j in modification.affects) 196 { 197 var hasAllClasses = true; 198 // Check each 199 for (var k in modification.affects[j]) 200 hasAllClasses = hasAllClasses && (classes.indexOf(modification.affects[j][k]) !== -1); 201 202 if (hasAllClasses) 203 { 204 applies = true; 205 break; 206 } 207 } 208 209 // Nothing is cumulative so that ordering doesn't matter as much as possible 210 if (modification.multiplier) 211 retValue += (modification.multiplier - 1) * +curValue; 212 else if (modification.add) 213 retValue += modification.add; 214 else if (modification.replace) // This will depend on ordering because there is no choice 215 retValue = modification.replace; 216 else 217 warn("modification format not recognised (modifying " + valueName + "): " + uneval(modification)); 218 } 219 220 return retValue; 221 }; 222 223 // Marks a technology as being currently researched 224 TechnologyManager.prototype.StartedResearch = function (tech) 225 { 226 this.inProgressTechs[tech] = true; 227 }; 228 229 // Marks a technology as not being currently researched 230 TechnologyManager.prototype.StoppedResearch = function (tech) 231 { 232 delete this.inProgressTechs[tech]; 233 }; 234 235 // Checks whether a technology is being currently researched 236 TechnologyManager.prototype.IsInProgress = function(tech) 237 { 238 if (this.inProgressTechs[tech]) 239 return true; 240 else 241 return false; 242 } 243 244 Engine.RegisterComponentType(IID_TechnologyManager, "TechnologyManager", TechnologyManager); -
binaries/data/mods/public/simulation/components/ResourceGatherer.js
123 123 return undefined; 124 124 }; 125 125 126 // Remove any cached template data which is based on technology data 127 ResourceGatherer.prototype.OnTechnologyModificationChange = function(msg) 128 { 129 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 130 if (!cmpOwnership) 131 return; 132 133 var player = cmpOwnership.GetOwner(); 134 135 if (msg.component === "ResourceGatherer" && msg.player === player) 136 delete this.gatherRatesCache; 137 }; 138 126 139 ResourceGatherer.prototype.GetGatherRates = function() 127 140 { 128 var ret = {}; 129 for (var r in this.template.Rates) 130 ret[r] = this.template.Rates[r] * this.template.BaseSpeed; 131 return ret; 141 if (!this.gatherRatesCache){ 142 this.gatherRatesCache = {}; 143 var cmpTechManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); 144 var baseSpeed = cmpTechManager.ApplyModifications("ResourceGatherer/BaseSpeed", this.template.BaseSpeed, this.entity); 145 for (var r in this.template.Rates) 146 { 147 var rate = cmpTechManager.ApplyModifications("ResourceGatherer/Rates/" + r, this.template.Rates[r], this.entity); 148 this.gatherRatesCache[r] = rate * baseSpeed; 149 } 150 } 151 152 return this.gatherRatesCache; 132 153 }; 133 154 134 155 ResourceGatherer.prototype.GetRange = function() 135 156 { 136 157 return { "max": +this.template.MaxDistance, "min": 0 }; 137 158 // maybe this should depend on the unit or target or something? 138 } 159 }; 139 160 140 161 /** 141 162 * Try to gather treasure … … 219 240 var type = cmpResourceSupply.GetType(); 220 241 221 242 var rate; 222 if (type.specific && this. template.Rates[type.generic+"."+type.specific])223 rate = this. template.Rates[type.generic+"."+type.specific];243 if (type.specific && this.GetGatherRates()[type.generic+"."+type.specific]) 244 rate = this.GetGatherRates()[type.generic+"."+type.specific]; 224 245 else 225 rate = this. template.Rates[type.generic];246 rate = this.GetGatherRates()[type.generic]; 226 247 227 return (rate || 0) * this.template.BaseSpeed;228 } 248 return (rate || 0); 249 }; 229 250 230 251 /** 231 252 * Returns whether this unit can carry more of the given type of resource. -
binaries/data/mods/public/simulation/components/ProductionQueue.js
1 1 var g_ProgressInterval = 1000; 2 2 const MAX_QUEUE_SIZE = 16; 3 3 4 function TrainingQueue() {}4 function ProductionQueue() {} 5 5 6 TrainingQueue.prototype.Schema =7 "<a:help>Allows the building to train new units .</a:help>" +6 ProductionQueue.prototype.Schema = 7 "<a:help>Allows the building to train new units and research technologies.</a:help>" + 8 8 "<a:example>" + 9 9 "<Entities datatype='tokens'>" + 10 10 "\n units/{civ}_support_female_citizen\n units/{civ}_support_trader\n units/celt_infantry_spearman_b\n " + 11 11 "</Entities>" + 12 12 "</a:example>" + 13 "<element name='Entities' a:help='Space-separated list of entity template names that this building can train. The special string \"{civ}\" will be automatically replaced by the building's four-character civ code'>" + 14 "<attribute name='datatype'>" + 15 "<value>tokens</value>" + 16 "</attribute>" + 17 "<text/>" + 18 "</element>"; 13 "<optional>" + 14 "<element name='Entities' a:help='Space-separated list of entity template names that this building can train. The special string \"{civ}\" will be automatically replaced by the building's four-character civ code'>" + 15 "<attribute name='datatype'>" + 16 "<value>tokens</value>" + 17 "</attribute>" + 18 "<text/>" + 19 "</element>" + 20 "</optional>" + 21 "<optional>" + 22 "<element name='Technologies' a:help='Space-separated list of technology names that this building can research.'>" + 23 "<attribute name='datatype'>" + 24 "<value>tokens</value>" + 25 "</attribute>" + 26 "<text/>" + 27 "</element>" + 28 "</optional>"; 19 29 20 TrainingQueue.prototype.Init = function()30 ProductionQueue.prototype.Init = function() 21 31 { 22 32 this.nextID = 1; 23 33 … … 26 36 // { 27 37 // "id": 1, 28 38 // "player": 1, // who paid for this batch; we need this to cope with refunds cleanly 29 // " template": "units/example",39 // "unitTemplate": "units/example", 30 40 // "count": 10, 31 41 // "resources": { "wood": 100, ... }, // resources per unit, multiply by count to get total 32 42 // "population": 1, // population per unit, multiply by count to get total 33 // " trainingStarted": false, // true iff we have reserved population43 // "productionStarted": false, // true iff we have reserved population 34 44 // "timeTotal": 15000, // msecs 35 45 // "timeRemaining": 10000, // msecs 36 46 // } 47 // 48 // { 49 // "id": 1, 50 // "player": 1, // who paid for this research; we need this to cope with refunds cleanly 51 // "technologyTemplate": "example_tech", 52 // "resources": { "wood": 100, ... }, // resources needed for research 53 // "productionStarted": false, // true iff production has started 54 // "timeTotal": 15000, // msecs 55 // "timeRemaining": 10000, // msecs 56 // } 37 57 38 58 this.timer = undefined; // g_ProgressInterval msec timer, active while the queue is non-empty 39 59 … … 44 64 /* 45 65 * Returns list of entities that can be trained by this building. 46 66 */ 47 TrainingQueue.prototype.GetEntitiesList = function()67 ProductionQueue.prototype.GetEntitiesList = function() 48 68 { 69 if (!this.template.Entities) 70 return []; 71 49 72 var string = this.template.Entities._string; 50 73 51 74 // Replace the "{civ}" codes with this entity's civ ID … … 57 80 }; 58 81 59 82 /* 60 * Adds a new batch of identical units to the training queue.83 * Returns list of technologies that can be researched by this building. 61 84 */ 62 TrainingQueue.prototype.AddBatch = function(templateName, count, metadata)85 ProductionQueue.prototype.GetTechnologiesList = function() 63 86 { 87 if (!this.template.Technologies) 88 return []; 89 90 var string = this.template.Technologies._string; 91 92 var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager); 93 if (!cmpTechMan) 94 return []; 95 96 var techs = string.split(/\s+/); 97 var ret = []; 98 var superceded = {}; // Stores the tech which supercedes the key 99 100 // Add any top level technologies to an array which corresponds to the displayed icons 101 // Also store the "children" for the superceding, 102 for (var i in techs) 103 { 104 var tech = techs[i]; 105 var template = cmpTechMan.GetTechnologyTemplate(tech); 106 if (!template.supercedes || techs.indexOf(template.supercedes) === -1) 107 ret.push(tech); 108 else 109 superceded[template.supercedes] = tech; 110 } 111 112 // Now make researched/in progress techs invisible 113 for (var i in ret) 114 { 115 var tech = ret[i]; 116 while (cmpTechMan.IsTechnologyResearched(tech) || cmpTechMan.IsInProgress(tech)) 117 { 118 tech = superceded[tech]; 119 } 120 121 122 ret[i] = tech; 123 } 124 125 return ret; 126 }; 127 128 /* 129 * Adds a new batch of identical units to train or a technology to research to the production queue. 130 */ 131 ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadata) 132 { 64 133 // TODO: there should probably be a limit on the number of queued batches 65 134 // TODO: there should be a way for the GUI to determine whether it's going 66 135 // to be possible to add a batch (based on resource costs and length limits) … … 68 137 69 138 if (this.queue.length < MAX_QUEUE_SIZE) 70 139 { 71 // Find the template data so we can determine the build costs 72 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 73 var template = cmpTempMan.GetTemplate(templateName); 74 if (!template) 75 return; 140 141 if (type == "unit") 142 { 143 // Find the template data so we can determine the build costs 144 var cmpTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); 145 var template = cmpTempMan.GetTemplate(templateName); 146 if (!template) 147 return; 148 149 // Apply a time discount to larger batches. 150 // TODO: work out what equation we should use here. 151 var timeMult = Math.pow(count, 0.7); 76 152 77 // Apply a time discount to larger batches. 78 // TODO: work out what equation we should use here. 79 var timeMult = Math.pow(count, 0.7); 153 var time = timeMult * template.Cost.BuildTime; 80 154 81 var time = timeMult * template.Cost.BuildTime; 155 var totalCosts = {}; 156 for each (var r in ["food", "wood", "stone", "metal"]) 157 totalCosts[r] = Math.floor(count * template.Cost.Resources[r]); 82 158 83 var totalCosts = {}; 84 for each (var r in ["food", "wood", "stone", "metal"]) 85 totalCosts[r] = Math.floor(count * template.Cost.Resources[r]); 159 var population = template.Cost.Population; 160 161 // TrySubtractResources should report error to player (they ran out of resources) 162 if (!cmpPlayer.TrySubtractResources(totalCosts)) 163 return; 86 164 87 var population = template.Cost.Population; 88 89 // TrySubtractResources should report error to player (they ran out of resources) 90 if (!cmpPlayer.TrySubtractResources(totalCosts)) 165 this.queue.push({ 166 "id": this.nextID++, 167 "player": cmpPlayer.GetPlayerID(), 168 "unitTemplate": templateName, 169 "count": count, 170 "metadata": metadata, 171 "resources": deepcopy(template.Cost.Resources), // need to copy to avoid serialization problems 172 "population": population, 173 "productionStarted": false, 174 "timeTotal": time*1000, 175 "timeRemaining": time*1000, 176 }); 177 } 178 else if (type == "technology") 179 { 180 // Load the technology template 181 var cmpTechTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TechnologyTemplateManager); 182 var template = cmpTechTempMan.GetTemplate(templateName); 183 if (!template) 184 return; 185 186 var time = template.researchTime; 187 188 var cost = {}; 189 for each (var r in ["food", "wood", "stone", "metal"]) 190 cost[r] = Math.floor(template.cost[r]); 191 192 // TrySubtractResources should report error to player (they ran out of resources) 193 if (!cmpPlayer.TrySubtractResources(cost)) 194 return; 195 196 // Tell the technology manager that we have started researching this so that people can't research the same 197 // thing twice. 198 var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager); 199 cmpTechMan.StartedResearch(templateName); 200 201 this.queue.push({ 202 "id": this.nextID++, 203 "player": cmpPlayer.GetPlayerID(), 204 "count": 1, 205 "technologyTemplate": templateName, 206 "resources": deepcopy(template.cost), // need to copy to avoid serialization problems 207 "productionStarted": false, 208 "timeTotal": time*1000, 209 "timeRemaining": time*1000, 210 }); 211 } 212 else 213 { 214 warn("Tried to add invalid item of type \"" + type + "\" and template \"" + templateName + "\" to a production queue"); 91 215 return; 216 } 217 218 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); 92 219 93 this.queue.push({94 "id": this.nextID++,95 "player": cmpPlayer.GetPlayerID(),96 "template": templateName,97 "count": count,98 "metadata": metadata,99 "resources": deepcopy(template.Cost.Resources), // need to copy to avoid serialization problems100 "population": population,101 "trainingStarted": false,102 "timeTotal": time*1000,103 "timeRemaining": time*1000,104 });105 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { });106 107 220 // If this is the first item in the queue, start the timer 108 221 if (!this.timer) 109 222 { 110 223 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 111 this.timer = cmpTimer.SetTimeout(this.entity, IID_ TrainingQueue, "ProgressTimeout", g_ProgressInterval, {});224 this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, {}); 112 225 } 113 226 } 114 227 else 115 228 { 116 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "The trainingqueue is full."};229 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "The production queue is full."}; 117 230 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 118 231 cmpGUIInterface.PushNotification(notification); 119 232 } 120 233 }; 121 234 122 235 /* 123 * Removes an existing batch of units from the trainingqueue.236 * Removes an existing batch of units from the production queue. 124 237 * Refunds resource costs and population reservations. 125 238 */ 126 TrainingQueue.prototype.RemoveBatch = function(id)239 ProductionQueue.prototype.RemoveBatch = function(id) 127 240 { 128 241 // Destroy any cached entities (those which didn't spawn for some reason) 129 242 for (var i = 0; i < this.entityCache.length; ++i) … … 139 252 continue; 140 253 141 254 // Now we've found the item to remove 142 255 143 256 var cmpPlayer = QueryPlayerIDInterface(item.player, IID_Player); 144 257 145 258 // Refund the resource cost for this batch 146 259 var totalCosts = {}; 147 260 for each (var r in ["food", "wood", "stone", "metal"]) 148 261 totalCosts[r] = Math.floor(item.count * item.resources[r]); 149 262 150 263 cmpPlayer.AddResources(totalCosts); 151 264 152 265 // Remove reserved population slots if necessary 153 if (item. trainingStarted)266 if (item.productionStarted && item.unitTemplate) 154 267 cmpPlayer.UnReservePopulationSlots(item.population * item.count); 155 268 269 // Mark the research as stopped if we cancel it 270 if (item.technologyTemplate) 271 { 272 var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager); 273 cmpTechMan.StoppedResearch(item.technologyTemplate); 274 } 275 156 276 // Remove from the queue 157 277 // (We don't need to remove the timer - it'll expire if it discovers the queue is empty) 158 278 this.queue.splice(i, 1); 159 Engine.PostMessage(this.entity, MT_ TrainingQueueChanged, { });279 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); 160 280 161 281 return; 162 282 } 163 283 }; 164 284 165 285 /* 166 * Returns basic data from all batches in the trainingqueue.286 * Returns basic data from all batches in the production queue. 167 287 */ 168 TrainingQueue.prototype.GetQueue = function()288 ProductionQueue.prototype.GetQueue = function() 169 289 { 170 290 var out = []; 171 291 for each (var item in this.queue) 172 292 { 173 293 out.push({ 174 294 "id": item.id, 175 "template": item.template, 295 "unitTemplate": item.unitTemplate, 296 "technologyTemplate": item.technologyTemplate, 176 297 "count": item.count, 177 298 "progress": 1-(item.timeRemaining/item.timeTotal), 178 299 "metadata": item.metadata, … … 184 305 /* 185 306 * Removes all existing batches from the queue. 186 307 */ 187 TrainingQueue.prototype.ResetQueue = function()308 ProductionQueue.prototype.ResetQueue = function() 188 309 { 189 // Empty the trainingqueue and refund all the resource costs310 // Empty the production queue and refund all the resource costs 190 311 // to the player. (This is to avoid players having to micromanage their 191 312 // buildings' queues when they're about to be destroyed or captured.) 192 313 … … 194 315 this.RemoveBatch(this.queue[0].id); 195 316 }; 196 317 197 TrainingQueue.prototype.OnOwnershipChanged = function(msg)318 ProductionQueue.prototype.OnOwnershipChanged = function(msg) 198 319 { 199 320 if (msg.from != -1) 200 321 { 201 // Unset flag that previous owner's training queuemay be blocked322 // Unset flag that previous owner's training may be blocked 202 323 var cmpPlayer = QueryPlayerIDInterface(msg.from, IID_Player); 203 324 if (cmpPlayer && this.queue.length > 0) 204 cmpPlayer.UnBlockTraining Queue();325 cmpPlayer.UnBlockTraining(); 205 326 } 206 327 207 // Reset the trainingqueue whenever the owner changes.328 // Reset the production queue whenever the owner changes. 208 329 // (This should prevent players getting surprised when they capture 209 330 // an enemy building, and then loads of the enemy's civ's soldiers get 210 331 // created from it. Also it means we don't have to worry about … … 212 333 this.ResetQueue(); 213 334 }; 214 335 215 TrainingQueue.prototype.OnDestroy = function()336 ProductionQueue.prototype.OnDestroy = function() 216 337 { 217 338 // Reset the queue to refund any resources 218 339 this.ResetQueue(); … … 228 349 * This function creates the entities and places them in world if possible. 229 350 * returns the number of successfully spawned entities. 230 351 */ 231 TrainingQueue.prototype.SpawnUnits = function(templateName, count, metadata)352 ProductionQueue.prototype.SpawnUnits = function(templateName, count, metadata) 232 353 { 233 354 var cmpFootprint = Engine.QueryInterface(this.entity, IID_Footprint); 234 355 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); … … 302 423 }; 303 424 304 425 /* 305 * Increments progress on the first batch in the trainingqueue, and blocks the426 * Increments progress on the first batch in the production queue, and blocks the 306 427 * queue if population limit is reached or some units failed to spawn. 307 428 */ 308 TrainingQueue.prototype.ProgressTimeout = function(data)429 ProductionQueue.prototype.ProgressTimeout = function(data) 309 430 { 310 431 // Allocate the 1000msecs to as many queue items as it takes 311 432 // until we've used up all the time (so that we work accurately … … 316 437 while (time > 0 && this.queue.length) 317 438 { 318 439 var item = this.queue[0]; 319 if (!item. trainingStarted)440 if (!item.productionStarted) 320 441 { 321 // Batch's training hasn't started yet. 322 // Try to reserve the necessary population slots 323 if (!cmpPlayer.TryReservePopulationSlots(item.population * item.count)) 442 // If the item is a unit then do population checks 443 if (item.unitTemplate) 324 444 { 325 // No slots available - don't train this batch now 326 // (we'll try again on the next timeout) 445 // Batch's training hasn't started yet. 446 // Try to reserve the necessary population slots 447 if (item.unitTemplate && !cmpPlayer.TryReservePopulationSlots(item.population * item.count)) 448 { 449 // No slots available - don't train this batch now 450 // (we'll try again on the next timeout) 327 451 328 // Set flag that training queue is blocked 329 cmpPlayer.BlockTrainingQueue(); 330 break; 452 // Set flag that training is blocked 453 cmpPlayer.BlockTraining(); 454 break; 455 } 456 457 // Unset flag that training is blocked 458 cmpPlayer.UnBlockTraining(); 331 459 } 332 460 333 // Unset flag that training queue is blocked 334 cmpPlayer.UnBlockTrainingQueue(); 335 336 item.trainingStarted = true; 461 item.productionStarted = true; 337 462 } 338 463 339 464 // If we won't finish the batch now, just update its timer … … 343 468 break; 344 469 } 345 470 346 var numSpawned = this.SpawnUnits(item.template, item.count, item.metadata); 347 if (numSpawned == item.count) 471 if (item.unitTemplate) 348 472 { 349 // All entities spawned, this batch finished 350 cmpPlayer.UnReservePopulationSlots(item.population * numSpawned); 351 time -= item.timeRemaining; 352 this.queue.shift(); 353 // Unset flag that training queue is blocked 354 cmpPlayer.UnBlockTrainingQueue(); 355 this.spawnNotified = false; 356 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { }); 357 } 358 else 359 { 360 if (numSpawned > 0) 473 var numSpawned = this.SpawnUnits(item.unitTemplate, item.count, item.metadata); 474 if (numSpawned == item.count) 361 475 { 362 // Only partiallyfinished476 // All entities spawned, this batch finished 363 477 cmpPlayer.UnReservePopulationSlots(item.population * numSpawned); 364 item.count -= numSpawned; 365 Engine.PostMessage(this.entity, MT_TrainingQueueChanged, { }); 478 time -= item.timeRemaining; 479 this.queue.shift(); 480 // Unset flag that training is blocked 481 cmpPlayer.UnBlockTraining(); 482 this.spawnNotified = false; 483 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); 366 484 } 485 else 486 { 487 if (numSpawned > 0) 488 { 489 // Only partially finished 490 cmpPlayer.UnReservePopulationSlots(item.population * numSpawned); 491 item.count -= numSpawned; 492 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); 493 } 367 494 368 // Some entities failed to spawn 369 // Set flag that training queue is blocked 370 cmpPlayer.BlockTrainingQueue(); 371 372 if (!this.spawnNotified) 373 { 374 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 375 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Can't find free space to spawn trained units" }; 376 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 377 cmpGUIInterface.PushNotification(notification); 378 this.spawnNotified = true; 495 // Some entities failed to spawn 496 // Set flag that training is blocked 497 cmpPlayer.BlockTraining(); 498 499 if (!this.spawnNotified) 500 { 501 var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); 502 var notification = {"player": cmpPlayer.GetPlayerID(), "message": "Can't find free space to spawn trained units" }; 503 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 504 cmpGUIInterface.PushNotification(notification); 505 this.spawnNotified = true; 506 } 507 break; 379 508 } 380 break;381 509 } 510 else if (item.technologyTemplate) 511 { 512 var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); 513 cmpTechnologyManager.ResearchTechnology(item.technologyTemplate); 514 515 this.queue.shift(); 516 Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { }); 517 } 382 518 } 383 519 384 520 // If the queue's empty, delete the timer, else repeat it … … 386 522 { 387 523 this.timer = undefined; 388 524 389 // Unset flag that training queueis blocked525 // Unset flag that training is blocked 390 526 // (This might happen when the player unqueues all batches) 391 cmpPlayer.UnBlockTraining Queue();527 cmpPlayer.UnBlockTraining(); 392 528 } 393 529 else 394 530 { 395 531 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 396 this.timer = cmpTimer.SetTimeout(this.entity, IID_ TrainingQueue, "ProgressTimeout", g_ProgressInterval, data);532 this.timer = cmpTimer.SetTimeout(this.entity, IID_ProductionQueue, "ProgressTimeout", g_ProgressInterval, data); 397 533 } 398 534 } 399 535 400 Engine.RegisterComponentType(IID_ TrainingQueue, "TrainingQueue", TrainingQueue);536 Engine.RegisterComponentType(IID_ProductionQueue, "ProductionQueue", ProductionQueue); -
binaries/data/mods/public/simulation/components/Player.js
12 12 this.popUsed = 0; // population of units owned or trained by this player 13 13 this.popBonuses = 0; // sum of population bonuses of player's entities 14 14 this.maxPop = 300; // maximum population 15 this.training QueueBlocked = false; // indicates whether any training queue is currently blocked15 this.trainingBlocked = false; // indicates whether any training queue is currently blocked 16 16 this.resourceCount = { 17 17 "food": 1000, 18 18 "wood": 1000, … … 104 104 return this.maxPop; 105 105 }; 106 106 107 Player.prototype.IsTraining QueueBlocked = function()107 Player.prototype.IsTrainingBlocked = function() 108 108 { 109 return this.training QueueBlocked;109 return this.trainingBlocked; 110 110 }; 111 111 112 Player.prototype.BlockTraining Queue= function()112 Player.prototype.BlockTraining = function() 113 113 { 114 this.training QueueBlocked = true;114 this.trainingBlocked = true; 115 115 }; 116 116 117 Player.prototype.UnBlockTraining Queue= function()117 Player.prototype.UnBlockTraining = function() 118 118 { 119 this.training QueueBlocked = false;119 this.trainingBlocked = false; 120 120 }; 121 121 122 122 Player.prototype.SetResourceCounts = function(resources) -
binaries/data/mods/public/simulation/components/Identity.js
68 68 "<element name='Icon'>" + 69 69 "<text/>" + 70 70 "</element>" + 71 "</optional>" + 72 "<optional>" + 73 "<element name='RequiredTechnology' a:help='Optional name of a technology which must be researched before the entity can be produced'>" + 74 "<text/>" + 75 "</element>" + 71 76 "</optional>"; 72 77 73 78 … … 126 131 Identity.prototype.GetSelectionGroupName = function() 127 132 { 128 133 return (this.template.SelectionGroupName || ""); 129 } 134 }; 130 135 131 136 Engine.RegisterComponentType(IID_Identity, "Identity", Identity); -
binaries/data/mods/public/simulation/components/GuiInterface.js
66 66 "popLimit": cmpPlayer.GetPopulationLimit(), 67 67 "popMax": cmpPlayer.GetMaxPopulation(), 68 68 "resourceCounts": cmpPlayer.GetResourceCounts(), 69 "training QueueBlocked": cmpPlayer.IsTrainingQueueBlocked(),69 "trainingBlocked": cmpPlayer.IsTrainingBlocked(), 70 70 "state": cmpPlayer.GetState(), 71 71 "team": cmpPlayer.GetTeam(), 72 72 "phase": cmpPlayer.GetPhase(), … … 176 176 ret.buildEntities = cmpBuilder.GetEntitiesList(); 177 177 } 178 178 179 var cmp TrainingQueue = Engine.QueryInterface(ent, IID_TrainingQueue);180 if (cmp TrainingQueue)179 var cmpProductionQueue = Engine.QueryInterface(ent, IID_ProductionQueue); 180 if (cmpProductionQueue) 181 181 { 182 ret.training = { 183 "entities": cmpTrainingQueue.GetEntitiesList(), 184 "queue": cmpTrainingQueue.GetQueue(), 182 ret.production = { 183 "entities": cmpProductionQueue.GetEntitiesList(), 184 "technologies": cmpProductionQueue.GetTechnologiesList(), 185 "queue": cmpProductionQueue.GetQueue(), 185 186 }; 186 187 } 187 188 … … 336 337 }; 337 338 ret.icon = template.Identity.Icon; 338 339 ret.tooltip = template.Identity.Tooltip; 340 ret.requiredTechnology = template.Identity.RequiredTechnology; 339 341 } 340 342 341 343 if (template.UnitMotion) … … 349 351 return ret; 350 352 }; 351 353 354 GuiInterface.prototype.GetTechnologyData = function(player, name) 355 { 356 var cmpTechTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_TechnologyTemplateManager); 357 var template = cmpTechTempMan.GetTemplate(name); 358 359 if (!template) 360 { 361 warn("tried to get data for invaalid technology: " + name); 362 return null; 363 } 364 365 var ret = {}; 366 367 ret.name = { 368 "specific": template.specificName, 369 "generic": template.genericName, 370 }; 371 ret.icon = template.icon; 372 ret.cost = { 373 "food": +template.cost.food, 374 "wood": +template.cost.wood, 375 "metal": +template.cost.metal, 376 "stone": +template.cost.stone, 377 } 378 ret.tooltip = template.tooltip; 379 380 if (template.requirementsTooltip) 381 ret.requirementsTooltip = template.requirementsTooltip; 382 else 383 ret.requirementsTooltip = ""; 384 385 ret.description = template.description; 386 387 return ret; 388 }; 389 390 GuiInterface.prototype.IsTechnologyResearched = function(player, tech) 391 { 392 var cmpTechMan = QueryPlayerIDInterface(player, IID_TechnologyManager); 393 394 if (!cmpTechMan) 395 return false; 396 397 return cmpTechMan.IsTechnologyResearched(tech); 398 } 399 400 // Checks whether the requirements for this technology have been met 401 GuiInterface.prototype.CheckTechnologyRequirements = function(player, tech) 402 { 403 var cmpTechMan = QueryPlayerIDInterface(player, IID_TechnologyManager); 404 405 if (!cmpTechMan) 406 return false; 407 408 return cmpTechMan.CanResearch(tech); 409 } 410 352 411 GuiInterface.prototype.PushNotification = function(notification) 353 412 { 354 413 this.notifications.push(notification); … … 802 861 "ClearRenamedEntities": 1, 803 862 "GetEntityState": 1, 804 863 "GetTemplateData": 1, 864 "GetTechnologyData": 1, 865 "IsTechnologyResearched": 1, 866 "CheckTechnologyRequirements": 1, 805 867 "GetNextNotification": 1, 806 868 807 869 "GetFormationRequirements": 1, -
binaries/data/mods/public/simulation/components/AIProxy.js
119 119 this.changes.unitAIOrderData = msg.to; 120 120 }; 121 121 122 AIProxy.prototype.On TrainingQueueChanged = function(msg)122 AIProxy.prototype.OnProductionQueueChanged = function(msg) 123 123 { 124 124 this.NotifyChange(); 125 125 126 var cmp TrainingQueue = Engine.QueryInterface(this.entity, IID_TrainingQueue);127 this.changes.trainingQueue = cmp TrainingQueue.GetQueue();126 var cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); 127 this.changes.trainingQueue = cmpProductionQueue.GetQueue(); 128 128 } 129 129 130 130 AIProxy.prototype.OnGarrisonedUnitsChanged = function(msg) … … 188 188 ret.unitAIOrderData = cmpUnitAI.GetOrderData(); 189 189 } 190 190 191 var cmp TrainingQueue = Engine.QueryInterface(this.entity, IID_TrainingQueue);192 if (cmp TrainingQueue)191 var cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); 192 if (cmpProductionQueue) 193 193 { 194 // Updated by On TrainingQueueChanged195 ret.trainingQueue = cmp TrainingQueue.GetQueue();194 // Updated by OnProductionQueueChanged 195 ret.trainingQueue = cmpProductionQueue.GetQueue(); 196 196 } 197 197 198 198 var cmpFoundation = Engine.QueryInterface(this.entity, IID_Foundation); -
binaries/data/mods/public/simulation/ai/common-api-v2/entity.js
127 127 }, 128 128 129 129 trainableEntities: function() { 130 if (!this._template. TrainingQueue)130 if (!this._template.ProductionQueue) 131 131 return undefined; 132 132 var civ = this.civ(); 133 var templates = this._template. TrainingQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);133 var templates = this._template.ProductionQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/); 134 134 return templates; 135 135 }, 136 136 -
binaries/data/mods/public/simulation/ai/common-api-v2/base.js
20 20 // CCmpTemplateManager::CopyFoundationSubset and only includes components 21 21 // that our EntityTemplate class currently uses.) 22 22 var g_FoundationForbiddenComponents = { 23 " TrainingQueue": 1,23 "ProductionQueue": 1, 24 24 "ResourceSupply": 1, 25 25 "ResourceDropsite": 1, 26 26 "GarrisonHolder": 1, -
binaries/data/mods/public/simulation/ai/common-api/entity.js
126 126 }, 127 127 128 128 trainableEntities: function() { 129 if (!this._template. TrainingQueue)129 if (!this._template.ProductionQueue) 130 130 return undefined; 131 131 var civ = this.civ(); 132 var templates = this._template. TrainingQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/);132 var templates = this._template.ProductionQueue.Entities._string.replace(/\{civ\}/g, civ).split(/\s+/); 133 133 return templates; 134 134 }, 135 135 -
binaries/data/mods/public/simulation/ai/common-api/base.js
43 43 // CCmpTemplateManager::CopyFoundationSubset and only includes components 44 44 // that our EntityTemplate class currently uses.) 45 45 var g_FoundationForbiddenComponents = { 46 " TrainingQueue": 1,46 "ProductionQueue": 1, 47 47 "ResourceSupply": 1, 48 48 "ResourceDropsite": 1, 49 49 "GarrisonHolder": 1, -
binaries/data/mods/public/gui/session/unit_commands.js
4 4 const GARRISON = "Garrison"; 5 5 const FORMATION = "Formation"; 6 6 const TRAINING = "Training"; 7 const RESEARCH = "Research"; 7 8 const CONSTRUCTION = "Construction"; 8 9 const COMMAND = "Command"; 9 10 const STANCE = "Stance"; … … 23 24 const BARTER_ACTIONS = ["Sell", "Buy"]; 24 25 25 26 // The number of currently visible buttons (used to optimise showing/hiding) 26 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, " Barter": 0, "Trading": 0, "Construction": 0, "Command": 0, "Stance": 0};27 var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, "Research": 0, "Barter": 0, "Trading": 0, "Construction": 0, "Command": 0, "Stance": 0}; 27 28 28 29 // Unit panels are panels with row(s) of buttons 29 30 var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Training", "Barter", "Trading", "Construction", "Research", "Stance", "Command"]; … … 163 164 if (numberOfItems > 24) 164 165 numberOfItems = 24; 165 166 break; 167 168 case RESEARCH: 169 if (numberOfItems > 8) 170 numberOfItems = 8; 171 break; 166 172 167 173 case CONSTRUCTION: 168 174 if (numberOfItems > 24) … … 183 189 for (i = 0; i < numberOfItems; i++) 184 190 { 185 191 var item = items[i]; 186 var entType = ((guiName == "Queue")? item.template : item); 192 193 // If a tech has been researched it leaves an empty slot 194 if (guiName == RESEARCH && !item) 195 { 196 getGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true; 197 continue; 198 } 199 200 // Get the entity type and load the template for that type if necessary 201 var entType; 187 202 var template; 188 if (guiName != "Formation" && guiName != "Command" && guiName != "Stance")203 switch (guiName) 189 204 { 190 template = GetTemplateData(entType); 191 if (!template) 192 continue; // ignore attempts to use invalid templates (an error should have been reported already) 205 case QUEUE: 206 // The queue can hold both technologies and units so we need to use the correct code for 207 // loading the templates 208 if (item.unitTemplate) 209 { 210 entType = item.unitTemplate; 211 template = GetTemplateData(entType); 212 } 213 else if (item.technologyTemplate) 214 { 215 entType = item.technologyTemplate; 216 template = GetTechnologyData(entType); 217 } 218 219 if (!template) 220 continue; // ignore attempts to use invalid templates (an error should have been 221 // reported already) 222 break; 223 case RESEARCH: 224 entType = item; 225 template = GetTechnologyData(entType); 226 if (!template) 227 continue; // TODO: should make some kind of warning happen somewhere in the code 228 break; 229 case SELECTION: 230 case GARRISON: 231 case TRAINING: 232 case CONSTRUCTION: 233 entType = item; 234 template = GetTemplateData(entType); 235 if (!template) 236 continue; // ignore attempts to use invalid templates (an error should have been 237 // reported already) 238 break; 193 239 } 194 240 195 241 switch (guiName) … … 233 279 if (template.tooltip) 234 280 tooltip += "\n[font=\"serif-13\"]" + template.tooltip + "[/font]"; 235 281 236 var [batchSize, batchIncrement] = getTraining QueueBatchStatus(unitEntState.id, entType);282 var [batchSize, batchIncrement] = getTrainingBatchStatus(unitEntState.id, entType); 237 283 var trainNum = batchSize ? batchSize+batchIncrement : batchIncrement; 238 284 239 285 tooltip += "\n" + getEntityCost(template); … … 250 296 tooltip += "\n\n[font=\"serif-bold-13\"]Shift-click[/font][font=\"serif-13\"] to train " + trainNum + ".[/font]"; 251 297 252 298 break; 299 300 case RESEARCH: 301 var tooltip = getEntityNameWithGenericType(template); 253 302 303 if (template.tooltip) 304 tooltip += "\n[font=\"serif-13\"]" + template.tooltip + "[/font]"; 305 306 tooltip += "\n" + getEntityCost(template); 307 break; 308 254 309 case CONSTRUCTION: 255 310 var tooltip = getEntityNameWithGenericType(template); 256 311 if (template.tooltip) … … 352 407 } 353 408 else if (template.icon) 354 409 { 355 icon.sprite = "stretched:session/portraits/" + template.icon; 410 var grayscale = ""; 411 button.enabled = true; 412 413 if (template.requiredTechnology && !Engine.GuiInterfaceCall("IsTechnologyResearched", template.requiredTechnology)) 414 { 415 button.enabled = false; 416 var techName = getEntityName(GetTechnologyData(template.requiredTechnology)); 417 button.tooltip += "\nRequires " + techName; 418 grayscale = "grayscale:"; 419 } 420 421 if (guiName == RESEARCH && !Engine.GuiInterfaceCall("CheckTechnologyRequirements", entType)) 422 { 423 button.enabled = false; 424 button.tooltip += "\n" + GetTechnologyData(entType).requirementsTooltip; 425 grayscale = "grayscale:"; 426 } 427 428 icon.sprite = "stretched:" + grayscale + "session/portraits/" + template.icon; 356 429 } 357 430 else 358 431 { … … 537 610 { 538 611 setupUnitPanel("Construction", usedPanels, entState, entState.buildEntities, startBuildingPlacement); 539 612 } 540 541 if (entState. training && entState.training.entities.length)613 614 if (entState.production && entState.production.entities.length) 542 615 { 543 setupUnitPanel("Training", usedPanels, entState, entState. training.entities,544 function (trainEntType) { addT oTrainingQueue(entState.id, trainEntType); } );616 setupUnitPanel("Training", usedPanels, entState, entState.production.entities, 617 function (trainEntType) { addTrainingToQueue(entState.id, trainEntType); } ); 545 618 } 619 620 if (entState.production && entState.production.technologies.length) 621 { 622 setupUnitPanel("Research", usedPanels, entState, entState.production.technologies, 623 function (researchType) { addResearchToQueue(entState.id, researchType); } ); 624 } 546 625 547 if (entState. training && entState.training.queue.length)548 setupUnitPanel("Queue", usedPanels, entState, entState. training.queue,549 function (item) { removeFrom TrainingQueue(entState.id, item.id); } );626 if (entState.production && entState.production.queue.length) 627 setupUnitPanel("Queue", usedPanels, entState, entState.production.queue, 628 function (item) { removeFromProductionQueue(entState.id, item.id); } ); 550 629 551 630 if (entState.trader) 552 631 { -
binaries/data/mods/public/gui/session/session.xml
727 727 </object> 728 728 729 729 <object name="unitResearchPanel" 730 style="TranslucentPanelThinBorder" 731 size="0 100%-56 100% 100%" 732 type="text" 730 size="14 100%-56 100% 100%" 733 731 > 734 732 <object size="0 0 100% 100%"> 733 <repeat count="8"> 734 <object name="unitResearchButton[n]" hidden="true" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottom"> 735 <object name="unitResearchIcon[n]" type="image" ghost="true" size="3 3 43 43"/> 736 </object> 737 </repeat> 738 </object> 735 739 [research commands] 736 740 </object> 737 741 -
binaries/data/mods/public/gui/session/session.js
15 15 16 16 // Indicate when one of the current player's training queues is blocked 17 17 // (this is used to support population counter blinking) 18 var g_IsTraining QueueBlocked = false;18 var g_IsTrainingBlocked = false; 19 19 20 20 // Cache EntityStates 21 21 var g_EntityStates = {}; // {id:entState} … … 53 53 return g_TemplateData[templateName]; 54 54 } 55 55 56 // Cache TechnologyData 57 var g_TechnologyData = {}; // {id:template} 58 59 function GetTechnologyData(technologyName) 60 { 61 if (!(technologyName in g_TechnologyData)) 62 { 63 var template = Engine.GuiInterfaceCall("GetTechnologyData", technologyName); 64 g_TechnologyData[technologyName] = template; 65 } 66 67 return g_TechnologyData[technologyName]; 68 } 69 56 70 // Init 57 71 function init(initData, hotloadData) 58 72 { … … 206 220 global.music.updateTimer(); 207 221 208 222 // When training is blocked, flash population (alternates colour every 500msec) 209 if (g_IsTraining QueueBlocked && (Date.now() % 1000) < 500)223 if (g_IsTrainingBlocked && (Date.now() % 1000) < 500) 210 224 getGUIObjectByName("resourcePop").textcolor = POPULATION_ALERT_COLOR; 211 225 else 212 226 getGUIObjectByName("resourcePop").textcolor = DEFAULT_POPULATION_COLOR; … … 257 271 g_Selection.dirty = false; 258 272 g_EntityStates = {}; 259 273 g_TemplateData = {}; 274 g_TechnologyData = {}; 260 275 261 276 var simState = Engine.GuiInterfaceCall("GetSimulationState"); 262 277 … … 345 360 getGUIObjectByName("resourceMetal").caption = playerState.resourceCounts.metal; 346 361 getGUIObjectByName("resourcePop").caption = playerState.popCount + "/" + playerState.popLimit; 347 362 348 g_IsTraining QueueBlocked = playerState.trainingQueueBlocked;363 g_IsTrainingBlocked = playerState.trainingBlocked; 349 364 } 350 365 351 366 function updateTimeElapsedCounter(simState) -
binaries/data/mods/public/gui/session/input.js
739 739 case "hotkeyup": 740 740 if (ev.hotkey == "session.batchtrain") 741 741 { 742 flushTraining QueueBatch();742 flushTrainingBatch(); 743 743 inputState = INPUT_NORMAL; 744 744 } 745 745 break; … … 1171 1171 var batchTrainingCount; 1172 1172 const batchIncrementSize = 5; 1173 1173 1174 function flushTraining QueueBatch()1174 function flushTrainingBatch() 1175 1175 { 1176 1176 Engine.PostNetworkCommand({"type": "train", "entity": batchTrainingEntity, "template": batchTrainingType, "count": batchTrainingCount}); 1177 1177 } 1178 1178 1179 1179 // Called by GUI when user clicks training button 1180 function addT oTrainingQueue(entity, trainEntType)1180 function addTrainingToQueue(entity, trainEntType) 1181 1181 { 1182 1182 if (Engine.HotkeyIsPressed("session.batchtrain")) 1183 1183 { … … 1192 1192 // Otherwise start a new one 1193 1193 else 1194 1194 { 1195 flushTraining QueueBatch();1195 flushTrainingBatch(); 1196 1196 // fall through to create the new batch 1197 1197 } 1198 1198 } … … 1208 1208 } 1209 1209 } 1210 1210 1211 // Called by GUI when user clicks training button 1212 function addResearchToQueue(entity, trainEntType) 1213 { 1214 Engine.PostNetworkCommand({"type": "research", "entity": entity, "template": trainEntType}); 1215 } 1216 1211 1217 // Returns the number of units that will be present in a batch if the user clicks 1212 1218 // the training button with shift down 1213 function getTraining QueueBatchStatus(entity, trainEntType)1219 function getTrainingBatchStatus(entity, trainEntType) 1214 1220 { 1215 1221 if (inputState == INPUT_BATCHTRAINING && batchTrainingEntity == entity && batchTrainingType == trainEntType) 1216 1222 return [batchTrainingCount, batchIncrementSize]; … … 1219 1225 } 1220 1226 1221 1227 // Called by GUI when user clicks production queue item 1222 function removeFrom TrainingQueue(entity, id)1228 function removeFromProductionQueue(entity, id) 1223 1229 { 1224 Engine.PostNetworkCommand({"type": "stop- train", "entity": entity, "id": id});1230 Engine.PostNetworkCommand({"type": "stop-production", "entity": entity, "id": id}); 1225 1231 } 1226 1232 1227 1233 // Called by unit selection buttons -
binaries/data/mods/internal/simulation/templates/structures/spart_syssiton.xml
33 33 <death>attack/destruction/building_collapse_large.xml</death> 34 34 </SoundGroups> 35 35 </Sound> 36 < TrainingQueue>36 <ProductionQueue> 37 37 <Entities datatype="tokens"> 38 38 units/hele_hero_leonidas 39 39 units/spart_champion_infantry_spear 40 40 </Entities> 41 </ TrainingQueue>41 </ProductionQueue> 42 42 <VisualActor> 43 43 <Actor>structures/hellenes/gymnasion.xml</Actor> 44 44 <FoundationActor>structures/fndn_6x6.xml</FoundationActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_gerousia.xml
34 34 <death>attack/destruction/building_collapse_large.xml</death> 35 35 </SoundGroups> 36 36 </Sound> 37 < TrainingQueue>37 <ProductionQueue> 38 38 <Entities datatype="tokens"> 39 39 units/hele_hero_leonidas 40 40 </Entities> 41 </ TrainingQueue>41 </ProductionQueue> 42 42 <VisualActor> 43 43 <Actor>structures/hellenes/tholos.xml</Actor> 44 44 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_fortress.xml
19 19 <Obstruction> 20 20 <Static width="24.0" depth="26.0"/> 21 21 </Obstruction> 22 < TrainingQueue>22 <ProductionQueue> 23 23 <Entities datatype="tokens"> 24 24 units/spart_mechanical_siege_ram 25 25 </Entities> 26 </ TrainingQueue>26 </ProductionQueue> 27 27 <VisualActor> 28 28 <Actor>structures/hellenes/fortress_new.xml</Actor> 29 29 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_dock.xml
11 11 <SpecificName>Limḗn</SpecificName> 12 12 <History>Greece is a sea country, which is why some of the greatest Hellenic and Hellenistic cities like Ephesus, Corinth, Alexandria and Antioch were built by the sea. It should also be noted that all colonies during the Great Colonisation were thriving port centres, which traded with the local population.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/spart_ship_bireme 17 17 units/spart_ship_trireme 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/hellenes/dock.xml</Actor> 22 22 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_corral.xml
18 18 <Obstruction> 19 19 <Static width="14.0" depth="14.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 gaia/fauna_goat 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/hellenes/corral.xml</Actor> 28 28 <FoundationActor>structures/fndn_3x3.xml</FoundationActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_civil_centre.xml
11 11 <SpecificName>Agorā́</SpecificName> 12 12 <History>The most important place in most Classical Greek poleis, the Agora served many purposes; it was a place for public speeches and was the stage for civic life and commercial interests.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/spart_infantry_spearman_b 17 17 units/spart_infantry_javelinist_b 18 18 units/spart_cavalry_javelinist_b 19 19 </Entities> 20 </ TrainingQueue>20 </ProductionQueue> 21 21 <VisualActor> 22 22 <Actor>structures/hellenes/civic_centre_new.xml</Actor> 23 23 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/spart_barracks.xml
15 15 <SpecificName>Stratēgeîon</SpecificName> 16 16 <History>The Stratigeion was the main military headquarters, where important decisions were taken and plans for battles discussed by the Hellene Generals, or "Strategoi".</History> 17 17 </Identity> 18 < TrainingQueue>18 <ProductionQueue> 19 19 <Entities datatype="tokens"> 20 20 units/spart_infantry_spearman_b 21 21 units/spart_champion_infantry_sword 22 22 units/spart_infantry_javelinist_b 23 23 units/spart_cavalry_javelinist_b 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/hellenes/barracks.xml</Actor> 28 28 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/mace_fortress.xml
19 19 <Obstruction> 20 20 <Static width="24.0" depth="26.0"/> 21 21 </Obstruction> 22 < TrainingQueue>22 <ProductionQueue> 23 23 <Entities datatype="tokens"> 24 24 units/mace_hero_philip 25 25 units/mace_hero_alexander … … 30 30 units/mace_mechanical_siege_lithobolos 31 31 units/mace_mechanical_siege_tower 32 32 </Entities> 33 </ TrainingQueue>33 </ProductionQueue> 34 34 <VisualActor> 35 35 <Actor>structures/hellenes/fortress_new.xml</Actor> 36 36 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/mace_dock.xml
11 11 <SpecificName>Limḗn</SpecificName> 12 12 <History>Greece is a sea country, which is why some of the greatest Hellenic and Hellenistic cities like Ephesus, Corinth, Alexandria and Antioch were built by the sea. It should also be noted that all colonies during the Great Colonisation were thriving port centres, which traded with the local population.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/hele_ship_bireme 17 17 units/hele_ship_trireme 18 18 </Entities> 19 </ TrainingQueue>19 </ProductionQueue> 20 20 <VisualActor> 21 21 <Actor>structures/hellenes/dock.xml</Actor> 22 22 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/mace_corral.xml
18 18 <Obstruction> 19 19 <Static width="14.0" depth="14.0"/> 20 20 </Obstruction> 21 < TrainingQueue>21 <ProductionQueue> 22 22 <Entities datatype="tokens"> 23 23 gaia/fauna_goat 24 24 </Entities> 25 </ TrainingQueue>25 </ProductionQueue> 26 26 <VisualActor> 27 27 <Actor>structures/hellenes/corral.xml</Actor> 28 28 <FoundationActor>structures/fndn_3x3.xml</FoundationActor> -
binaries/data/mods/internal/simulation/templates/structures/mace_civil_centre.xml
11 11 <SpecificName>Agorā́</SpecificName> 12 12 <History>The most important place in most Classical Greek poleis, the Agora served many purposes; it was a place for public speeches and was the stage for civic life and commercial interests.</History> 13 13 </Identity> 14 < TrainingQueue>14 <ProductionQueue> 15 15 <Entities datatype="tokens"> 16 16 units/mace_infantry_spearman_b 17 17 units/mace_infantry_javelinist_b 18 18 units/mace_cavalry_spearman_b 19 19 </Entities> 20 </ TrainingQueue>20 </ProductionQueue> 21 21 <VisualActor> 22 22 <Actor>structures/hellenes/civic_centre_new.xml</Actor> 23 23 </VisualActor> -
binaries/data/mods/internal/simulation/templates/structures/mace_barracks.xml
15 15 <SpecificName>Stratēgeîon</SpecificName> 16 16 <History>The Stratigeion was the main military headquarters, where important decisions were taken and plans for battles discussed by the Hellene Generals, or "Strategoi".</History> 17 17 </Identity> 18 < TrainingQueue>18 <ProductionQueue> 19 19 <Entities datatype="tokens"> 20 20 units/mace_infantry_spearman_b 21 21 units/mace_infantry_javelinist_b … … 24 24 units/mace_cavalry_spearman_b 25 25 units/mace_cavalry_javelinist_b 26 26 </Entities> 27 </ TrainingQueue>27 </ProductionQueue> 28 28 <VisualActor> 29 29 <Actor>structures/hellenes/barracks.xml</Actor> 30 30 </VisualActor> -
binaries/data/mods/internal/simulation/templates/campaigns/campaign_religious_test.xml
20 20 <Radius>100</Radius> 21 21 <Weight>65536</Weight> 22 22 </TerritoryInfluence> 23 < TrainingQueue disable=""/>23 <ProductionQueue disable=""/> 24 24 <VisualActor> 25 25 <Actor>structures/hellenes/temple_new.xml</Actor> 26 26 </VisualActor> -
binaries/data/mods/internal/simulation/templates/campaigns/campaign_city_test.xml
35 35 <Radius>300</Radius> 36 36 <Weight>35000</Weight> 37 37 </TerritoryInfluence> 38 < TrainingQueue>38 <ProductionQueue> 39 39 <Entities datatype="tokens"> 40 40 -units/{civ}_support_female_citizen 41 41 campaigns/army_mace_hero_alexander 42 42 campaigns/army_mace_standard 43 43 units/{civ}_support_trader 44 44 </Entities> 45 </ TrainingQueue>45 </ProductionQueue> 46 46 <VisualActor> 47 47 <Actor>campaigns/structures/hellenes/settlement_curtainwall.xml</Actor> 48 48 </VisualActor> -
binaries/data/mods/internal/simulation/templates/campaigns/campaign_city_minor_test.xml
35 35 <Radius>150</Radius> 36 36 <Weight>35000</Weight> 37 37 </TerritoryInfluence> 38 < TrainingQueue>38 <ProductionQueue> 39 39 <Entities datatype="tokens"> 40 40 -units/{civ}_support_female_citizen 41 41 campaigns/army_mace_hero_alexander 42 42 campaigns/army_mace_standard 43 43 </Entities> 44 </ TrainingQueue>44 </ProductionQueue> 45 45 <VisualActor> 46 46 <Actor>campaigns/structures/hellenes/settlement_curtainwall.xml</Actor> 47 47 </VisualActor>