Ticket #1234: #1234-2012-03-22.patch
File #1234-2012-03-22.patch, 18.4 KB (added by , 12 years ago) |
---|
-
binaries/data/mods/public/civs/cart.json
92 92 { 93 93 "Template": "units/cart_cavalry_javelinist_b" 94 94 } 95 ], 96 "Formations": 97 [ 98 "Scatter", 99 "Box", 100 "Column Closed", 101 "Line Closed", 102 "Column Open", 103 "Line Open", 104 "Flank", 105 "Skirmish", 106 "Wedge", 107 "Battle Line" 95 108 ] 96 109 } -
binaries/data/mods/public/civs/celt.json
140 140 { 141 141 "Template": "units/celt_cavalry_swordsman_b" 142 142 } 143 ], 144 "Formations": 145 [ 146 "Scatter", 147 "Box", 148 "Column Closed", 149 "Line Closed", 150 "Column Open", 151 "Line Open", 152 "Flank", 153 "Skirmish", 154 "Wedge", 155 "Battle Line" 143 156 ] 144 157 } -
binaries/data/mods/public/civs/hele.json
159 159 { 160 160 "Template": "units/hele_cavalry_swordsman_b" 161 161 } 162 ], 163 "Formations": 164 [ 165 "Scatter", 166 "Box", 167 "Column Closed", 168 "Line Closed", 169 "Column Open", 170 "Line Open", 171 "Flank", 172 "Skirmish", 173 "Wedge", 174 "Battle Line", 175 "Phalanx", 176 "Syntagma" 162 177 ] 163 178 } -
binaries/data/mods/public/civs/iber.json
99 99 { 100 100 "Template": "units/iber_cavalry_spearman_b" 101 101 } 102 ], 103 "Formations": 104 [ 105 "Scatter", 106 "Box", 107 "Column Closed", 108 "Line Closed", 109 "Column Open", 110 "Line Open", 111 "Flank", 112 "Skirmish", 113 "Wedge", 114 "Battle Line" 102 115 ] 103 116 } -
binaries/data/mods/public/civs/pers.json
100 100 { 101 101 "Template": "units/pers_cavalry_javelinist_b" 102 102 } 103 ], 104 "Formations": 105 [ 106 "Scatter", 107 "Box", 108 "Column Closed", 109 "Line Closed", 110 "Column Open", 111 "Line Open", 112 "Flank", 113 "Skirmish", 114 "Wedge", 115 "Battle Line" 103 116 ] 104 117 } -
binaries/data/mods/public/civs/rome.json
105 105 { 106 106 "Template": "units/rome_cavalry_spearman_b" 107 107 } 108 ], 109 "Formations": 110 [ 111 "Scatter", 112 "Box", 113 "Column Closed", 114 "Line Closed", 115 "Column Open", 116 "Line Open", 117 "Flank", 118 "Skirmish", 119 "Wedge", 120 "Battle Line", 121 "Testudo" 108 122 ] 109 123 } -
binaries/data/mods/public/gui/session/unit_commands.js
531 531 function (item) { unload(entState.id, groups.getEntsByName(item)); } ); 532 532 } 533 533 534 var formations = getEntityFormationsList(entState);534 var formations = Engine.GuiInterfaceCall("GetAvailableFormations"); 535 535 if (hasClass(entState, "Unit") && !hasClass(entState, "Animal") && !entState.garrisonHolder && formations.length) 536 536 { 537 537 setupUnitPanel("Formation", usedPanels, entState, formations, -
binaries/data/mods/public/gui/session/utility_functions.js
121 121 return dmgArray.join("[font=\"serif-12\"], [/font]"); 122 122 } 123 123 124 function getEntityFormationsList(entState)125 {126 var civ = g_Players[entState.player].civ;127 var formations = getCivFormations(civ);128 return formations;129 }130 131 function getCivFormations(civ)132 {133 // TODO: this should come from the civ JSON files instead134 135 var civFormations = ["Scatter", "Box", "Column Closed", "Line Closed", "Column Open", "Line Open", "Flank", "Skirmish", "Wedge", "Battle Line"];136 if (civ == "hele")137 {138 civFormations.push("Phalanx");139 civFormations.push("Syntagma");140 }141 else if (civ == "rome")142 {143 civFormations.push("Testudo");144 }145 return civFormations;146 }147 148 124 function getEntityCommandsList(entState) 149 125 { 150 126 var commands = []; -
binaries/data/mods/public/simulation/components/Formation.js
214 214 215 215 // Choose a sensible size/shape for the various formations, depending on number of units 216 216 var cols; 217 if (columnar || this.formationName == "Column Closed") 217 218 if (columnar) 219 this.formationName = "Column Closed"; 220 switch(this.formationName) 218 221 { 222 case "Column Closed": 219 223 // Have at most 3 files 220 224 if (count <= 3) 221 225 cols = count; 222 226 else 223 227 cols = 3; 224 228 shape = "square"; 225 } 226 else if (this.formationName == "Phalanx") 227 { 229 break; 230 case "Phalanx": 228 231 // Try to have at least 5 files (so batch training gives a single line), 229 232 // and at most 8 230 233 if (count <= 5) … … 238 241 else 239 242 cols = Math.ceil(count/6); 240 243 shape = "square"; 241 } 242 else if (this.formationName == "Line Closed") 243 { 244 break; 245 case "Line Closed": 244 246 if (count <= 3) 245 247 cols = count; 246 248 else if (count < 30) … … 248 250 else 249 251 cols = Math.ceil(count/3); 250 252 shape = "square"; 251 } 252 else if (this.formationName == "Testudo") 253 { 253 break; 254 case "Testudo": 254 255 cols = Math.ceil(Math.sqrt(count)); 255 256 shape = "square"; 256 } 257 else if (this.formationName == "Column Open") 258 { 259 cols = 2 257 break; 258 case "Column Open": 259 cols = 2; 260 260 shape = "opensquare"; 261 } 262 else if (this.formationName == "Line Open") 263 { 261 break; 262 case "Line Open": 264 263 if (count <= 5) 265 264 cols = 3; 266 265 else if (count <= 11) … … 270 269 else 271 270 cols = 6; 272 271 shape = "opensquare"; 273 } 274 else if (this.formationName == "Scatter") 275 { 272 break; 273 case "Scatter": 276 274 var width = Math.sqrt(count) * separation * 5; 277 275 278 276 for (var i = 0; i < count; ++i) 279 277 { 280 278 offsets.push({"x": Math.random()*width, "z": Math.random()*width}); 281 279 } 282 } 283 else if (this.formationName == "Circle") 284 { 280 break; 281 case "Circle": 285 282 var depth; 286 283 var pop; 287 284 if (count <= 36) … … 291 288 } 292 289 else 293 290 { 294 depth = 3 291 depth = 3; 295 292 pop = Math.ceil(count / depth); 296 293 } 297 294 … … 311 308 left--; 312 309 } 313 310 } 314 } 315 else if (this.formationName == "Box") 316 { 311 break; 312 case "Box": 317 313 var root = Math.ceil(Math.sqrt(count)); 318 314 319 315 var left = count; … … 334 330 meleeleft -= stodo; 335 331 } 336 332 else // compact 333 { 337 334 stodo = Math.max(0, left - (width-2)*(width-2)); 335 } 338 336 } 339 337 340 338 for (var r = -sq; r <= sq && stodo; ++r) … … 352 350 } 353 351 } 354 352 } 355 } 356 else if (this.formationName == "Skirmish") 357 { 353 break; 354 case "Skirmish": 358 355 cols = Math.ceil(count/2); 359 356 shape = "opensquare"; 360 } 361 else if (this.formationName == "Wedge") 362 { 357 break; 358 case "Wedge": 363 359 var depth = Math.ceil(Math.sqrt(count)); 364 360 365 361 var left = count; … … 387 383 } 388 384 } 389 385 } 390 } 391 else if (this.formationName == "Flank") 392 { 386 break; 387 case "Flank": 393 388 cols = 3; 394 389 var leftside = []; 395 390 leftside[0] = Math.ceil(count/2); … … 412 407 left -= n; 413 408 } 414 409 } 415 } 416 else if (this.formationName == "Syntagma") 417 { 418 var cols = Math.ceil(Math.sqrt(count)); 410 break; 411 case "Syntagma": 412 cols = Math.ceil(Math.sqrt(count)); 419 413 shape = "square"; 420 } 421 else if (this.formationName == "Battle Line") 422 { 414 break; 415 case "Battle Line": 423 416 if (count <= 5) 424 417 cols = count; 425 418 else if (count <= 10) … … 433 426 shape = "opensquare"; 434 427 separation /= 1.5; 435 428 ordering = "cavalryOnTheSides"; 429 break; 430 default: // We encountered an unknown formation (probably due to a modding attempt) -> Warn the user 431 warn("Formation.js: ComputeFormationOffsets: unknown formation: " + this.formationName); 432 break; 436 433 } 437 434 438 435 if (shape == "square") -
binaries/data/mods/public/simulation/components/GuiInterface.js
362 362 return ""; 363 363 }; 364 364 365 GuiInterface.prototype.GetAvailableFormations = function(player, data) 366 { 367 var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 368 var cmpPlayer = Engine.QueryInterface(cmpPlayerMan.GetPlayerByID(player), IID_Player); 369 return cmpPlayer.GetFormations(); 370 }; 371 365 372 GuiInterface.prototype.GetFormationRequirements = function(player, data) 366 373 { 367 374 return GetFormationRequirements(data.formationName); … … 804 811 "GetTemplateData": 1, 805 812 "GetNextNotification": 1, 806 813 814 "GetAvailableFormations": 1, 807 815 "GetFormationRequirements": 1, 808 816 "CanMoveEntsIntoFormation": 1, 809 817 "IsFormationSelected": 1, -
binaries/data/mods/public/simulation/components/Identity.js
123 123 return this.GetFormationsList().indexOf(name) != -1; 124 124 }; 125 125 126 Identity.prototype.CanUseFormations = function() 127 { 128 return this.GetFormationsList().length == 0 ? false : true; 129 }; 130 126 131 Identity.prototype.GetSelectionGroupName = function() 127 132 { 128 133 return (this.template.SelectionGroupName || ""); -
binaries/data/mods/public/simulation/components/Player.js
25 25 this.diplomacy = []; // array of diplomatic stances for this player with respect to other players (including gaia and self) 26 26 this.conquestCriticalEntitiesCount = 0; // number of owned units with ConquestCritical class 27 27 this.phase = "village"; 28 this.formations = []; 28 29 this.startCam = undefined; 29 30 this.controlAllUnits = false; 30 31 this.isAI = false; … … 233 234 this.phase = p; 234 235 }; 235 236 237 Player.prototype.GetFormations = function() 238 { 239 return this.formations; 240 }; 241 242 Player.prototype.SetFormations = function(formations) 243 { 244 this.formations = formations; 245 }; 246 236 247 Player.prototype.GetStartingCameraPos = function() 237 248 { 238 249 return this.startCam.position; -
binaries/data/mods/public/simulation/helpers/Commands.js
380 380 381 381 case "formation": 382 382 var entities = FilterEntityList(cmd.entities, player, controlAllUnits); 383 GetFormationUnitAIs(entities ).forEach(function(cmpUnitAI) {383 GetFormationUnitAIs(entities, cmd.name).forEach(function(cmpUnitAI) { 384 384 var cmpFormation = Engine.QueryInterface(cmpUnitAI.entity, IID_Formation); 385 385 if (!cmpFormation) 386 386 return; … … 481 481 * Returns a list of UnitAI components, each belonging either to a 482 482 * selected unit or to a formation entity for groups of the selected units. 483 483 */ 484 function GetFormationUnitAIs(ents )484 function GetFormationUnitAIs(ents, formName) 485 485 { 486 486 // If an individual was selected, remove it from any formation 487 487 // and command it individually … … 508 508 continue; 509 509 510 510 var cmpIdentity = Engine.QueryInterface(ent, IID_Identity); 511 // TODO: Currently we use LineClosed as effectively a boolean flag512 // to determine whether formations are allowed at all. Instead we513 // should check specific formation names and do something sensible514 // (like what?) when some units don't support them.515 // TODO: We'll also need to fix other formation code to use516 // "LineClosed" instead of "Line Closed" etc consistently.517 if (cmpIdentity && cmpIdentity.CanUseFormation("LineClosed"))511 // TODO: If formName is undefined we just check whether we can 512 // use LineClosed instead of checking the current formation. 513 // NOTE: We should keep "LineClosed" (instead of "Line Closed") 514 // to Commands.js, Identity.js and the xml files. If you need to 515 // access the formation data from the xml files use .replace(/\s+/,''). 516 if (cmpIdentity && cmpIdentity.CanUseFormations() 517 && cmpIdentity.CanUseFormation(formName === undefined ? "LineClosed" : formName.replace(/\s+/,''))) 518 518 formedEnts.push(ent); 519 519 else 520 520 nonformedUnitAIs.push(cmpUnitAI); … … 651 651 var count = ents.length; 652 652 653 653 // TODO: should check the player's civ is allowed to use this formation 654 // See simulation/components/Player.js GetFormations() for a list of all allowed formations 654 655 655 656 var requirements = GetFormationRequirements(formationName); 656 657 if (!requirements) -
binaries/data/mods/public/simulation/helpers/Player.js
118 118 } 119 119 } 120 120 121 // If formations are explicitly defined, use that; otherwise use civ defaults 122 if (getSetting(pData, pDefs, "Formations") !== undefined) 123 { 124 cmpPlayer.SetFormations(getSetting(pData, pDefs, "Formations")); 125 } 126 else 127 { 128 // We read the formation data from civ/{civ}.json 129 var rawFormations = Engine.ReadCivJSONFile(cmpPlayer.GetCiv()+".json"); 130 if (!(rawFormations && rawFormations.Formations)) 131 { 132 throw("Player.js: Error reading "+cmpPlayer.GetCiv()+".json"); 133 } 134 cmpPlayer.SetFormations(rawFormations.Formations); 135 } 136 121 137 var startCam = getSetting(pData, pDefs, "StartingCamera"); 122 138 if (startCam !== undefined) 123 139 { -
binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
26 26 <Builder> 27 27 <Rate>1.0</Rate> 28 28 <Entities datatype="tokens"> 29 29 structures/{civ}_house 30 30 structures/{civ}_mill 31 31 structures/{civ}_farmstead 32 32 structures/{civ}_field … … 51 51 <History>Women in the ancient world took on a variety of roles - from leadership (Celts) to servant (Greeks). Women are hard workers, the economic backbone of any civilisation. In history, it was typical when all the males (capable of fighting) were killed for the females, children, and elderly to be sold as slaves.</History> 52 52 <Tooltip>Gather resources, build civic structures, and inspire nearby males to work faster. Bonused at foraging and farming.</Tooltip> 53 53 <Classes datatype="tokens">Worker Female</Classes> 54 <Formations disable=""/> 54 55 </Identity> 55 56 <ResourceGatherer> 56 57 <MaxDistance>2.0</MaxDistance> … … 69 70 </ResourceGatherer> 70 71 <Sound> 71 72 <SoundGroups> 72 73 73 <select>voice/hellenes/civ/civ_female_select.xml</select> 74 <order_walk>voice/hellenes/civ/civ_female_select.xml</order_walk> 74 75 <order_attack>voice/hellenes/civ/civ_female_select.xml</order_attack> 75 76 <order_gather>voice/hellenes/civ/civ_female_select.xml</order_gather> 76 77 <order_repair>voice/hellenes/civ/civ_female_select.xml</order_repair> -
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<CScriptVal, std::wstring, CComponentManager::Script_ReadCivJSONFile> ("ReadCivJSONFile"); 84 85 } 85 86 86 87 // Define MT_*, IID_* as script globals, and store their names … … 938 939 939 940 CScriptVal CComponentManager::Script_ReadJSONFile(void* cbdata, std::wstring fileName) 940 941 { 942 return ReadJSONFile(cbdata, L"simulation/data", fileName); 943 } 944 945 CScriptVal CComponentManager::Script_ReadCivJSONFile(void* cbdata, std::wstring fileName) 946 { 947 return ReadJSONFile(cbdata, L"civs", fileName); 948 } 949 950 CScriptVal CComponentManager::ReadJSONFile(void* cbdata, std::wstring relativePath, std::wstring fileName) 951 { 941 952 CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata); 942 953 943 VfsPath path = VfsPath( "simulation/data") / fileName;954 VfsPath path = VfsPath(relativePath) / fileName; 944 955 945 956 return componentManager->GetScriptInterface().ReadJSONFile(path).get(); 946 957 } -
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 CScriptVal Script_ReadCivJSONFile(void* cbdata, std::wstring fileName); 237 238 static CScriptVal ReadJSONFile(void* cbdata, std::wstring relativePath, std::wstring fileName); 236 239 237 240 CMessage* ConstructMessage(int mtid, CScriptVal data); 238 241 void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const;