wowgetoffyourcellphone Posted January 15, 2022 Report Share Posted January 15, 2022 Standards appearing over battalions looks really nice and do help with gameplay. Now, I wonder how to make them civ-specific. I tried using the waypoint/rally point flag hack in the actor, which names variants based on civ codes ("athen", "spart", "cart", etc.). It works for the waypoint actor (obviously), but not for my formation standard actor. In the above screenshot, you see that the standards pick random variants instead of the civ-specific one. Both flags should be the "athen" variant, but they are not. Also, a new flag variant is chosen each time the formation is created. Here is the waypoint flag code, which works: <?xml version="1.0" encoding="utf-8"?> <actor version="1"> <castshadow/> <float/> <group> <variant frequency="100"> <animations> <animation file="mechanical/waypoint_flag_idle.dae" name="Idle" speed="30"/> </animations> <mesh>props/waypoint_flag.dae</mesh> </variant> </group> <group> <variant name="hele"> <textures> <texture file="props/banner_greek.png" name="baseTex"/> </textures> </variant> <variant name="pers"> <textures> <texture file="props/banner_persian.png" name="baseTex"/> </textures> </variant> <variant name="celt"> <textures> <texture file="props/banner_celt.png" name="baseTex"/> </textures> </variant> <variant name="cart"> <textures> <texture file="props/banner_carthage.png" name="baseTex"/> </textures> </variant> <variant name="iber"> <textures> <texture file="props/banner_iberians.png" name="baseTex"/> </textures> </variant> <variant name="scyth"> <textures> <texture file="props/banner_scythians.png" name="baseTex"/> </textures> </variant> <variant name="xion"> <textures> <texture file="props/banner_scythians.png" name="baseTex"/> </textures> </variant> <variant name="rome"> <textures> <texture file="props/banner_romans.png" name="baseTex"/> </textures> </variant> <variant name="imp"> <textures> <texture file="props/banner_romans.png" name="baseTex"/> </textures> </variant> <variant name="spart"> <textures> <texture file="props/banner_spartans.png" name="baseTex"/> </textures> </variant> <variant name="mace"> <textures> <texture file="props/banner_macedonians.png" name="baseTex"/> </textures> </variant> <variant name="athen"> <textures> <texture file="props/banner_greek.png" name="baseTex"/> </textures> </variant> <variant name="brit"> <textures> <texture file="props/banner_celt.png" name="baseTex"/> </textures> </variant> <variant name="gaul"> <textures> <texture file="props/banner_celt.png" name="baseTex"/> </textures> </variant> <variant name="maur"> <textures> <texture file="props/banner_mauryas.png" name="baseTex"/> </textures> </variant> <variant name="ptol"> <textures> <texture file="props/banner_ptolemies.png" name="baseTex"/> </textures> </variant> <variant name="sele"> <textures> <texture file="props/banner_seleucids.png" name="baseTex"/> </textures> </variant> <variant name="theb"> <textures> <texture file="props/banner_thebans.png" name="baseTex"/> </textures> </variant> <variant name="epir"> <textures> <texture file="props/banner_epirotes.png" name="baseTex"/> </textures> </variant> <variant name="han"> <textures> <texture file="props/banner_chinese.png" name="baseTex"/> </textures> </variant> <variant name="kush"> <textures> <texture file="props/banner_kushites.png" name="baseTex"/> </textures> </variant> <variant name="noba"> <textures> <texture file="props/banner_kushites.png" name="baseTex"/> </textures> </variant> <variant name="sueb"> <textures> <texture file="props/banner_germans.png" name="baseTex"/> </textures> </variant> <variant name="goth"> <textures> <texture file="props/banner_norse.png" name="baseTex"/> </textures> </variant> <variant name="zapo"> <textures> <texture file="props/banner_maya.png" name="baseTex"/> </textures> </variant> </group> <material>basic_trans.xml</material> </actor> Here is the Standard code, which does not work: <?xml version="1.0" encoding="utf-8"?> <actor version="1"> <castshadow/> <float/> <group> <variant frequency="100"> <mesh>props/standards/formation_pole.dae</mesh> <textures> <texture file="props/kart_standard.png" name="baseTex"/> <texture file="props/kart_standard_norm.png" name="normTex"/> <texture file="props/kart_standard_spec.png" name="specTex"/> </textures> </variant> </group> <group> <variant name="athen"> <props> <prop actor="props/units/standards/formation_flag_athen.xml" attachpoint="root"/> </props> </variant> <variant name="cart"> <props> <prop actor="props/units/standards/formation_flag_cart.xml" attachpoint="root"/> </props> </variant> <variant name="spart"> <props> <prop actor="props/units/standards/formation_flag_spart.xml" attachpoint="root"/> </props> </variant> </group> <material>no_trans_parallax_spec.xml</material> </actor> formation_flag_athen: <?xml version="1.0" encoding="utf-8"?> <actor version="1"> <castshadow/> <group> <variant> <mesh>props/standards/formation_flag.dae</mesh> <textures> <texture file="props/standards/athen_infantry_1.png" name="baseTex"/> </textures> </variant> </group> <material>player_trans.xml</material> </actor> 5 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 16, 2022 Author Report Share Posted January 16, 2022 (edited) Won't work with a single actor with civ variants inside (as shown in the op). Tried it with civ-specific actors and making new formations for Athen, as a test. That all works fine, until I realize all the hacking I'll have to do: A flag actor for every civ (had to do that anyway, no problem). Redundant formations for every civ, so that the civ-specific flag actors show up. errr Making sure those formations show up correctly for each unit. So, use a mixin for each civ to pull the right civ-specific formations, then edit the parent template lines of every unit to grab the civ-specific mixin. Editing each civ.json file to list the right civ-specific formations. Then try to fix the very common edge case where you have mercenaries that aren't of the player's civ. Redundant formation icons could show up in the formation UI panel. No idea how to prevent this. If it wasn't for this last bullet, I would proceed, but... All of the above is an inelegant hack. More elegant is to edit Formations.js so that formations take the civ of the player, so we can just use 1 actor as originally planned (similar to how rally points use the waypoint flag actor with civ variants inside it). I don't see that happening unless the base game wants to add these too. Edited January 16, 2022 by wowgetoffyourcellphone Quote Link to comment Share on other sites More sharing options...
Silier Posted January 16, 2022 Report Share Posted January 16, 2022 https://github.com/SilierTheVixen/0ad-gameplay-mode/blob/f082021413165c3c8d3a45c9c59d146db0d264e2/simulation/components/Formation.js#L1807 https://github.com/SilierTheVixen/0ad-gameplay-mode/blob/f082021413165c3c8d3a45c9c59d146db0d264e2/simulation/templates/template_formation.xml#L50 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 16, 2022 Author Report Share Posted January 16, 2022 1 hour ago, Silier said: https://github.com/SilierTheVixen/0ad-gameplay-mode/blob/f082021413165c3c8d3a45c9c59d146db0d264e2/simulation/components/Formation.js#L1807 https://github.com/SilierTheVixen/0ad-gameplay-mode/blob/f082021413165c3c8d3a45c9c59d146db0d264e2/simulation/templates/template_formation.xml#L50 Formation.js seems to have been changed in the intervening 3 years. Quote Link to comment Share on other sites More sharing options...
Silier Posted January 16, 2022 Report Share Posted January 16, 2022 for a26 yes. Commands.js L1654: const cmpVisual = Engine.QueryInterface(formationEnt, IID_Visual); if (cmpVisual) { const civ = QueryPlayerIDInterface(player).GetCiv(); cmpVisual.SetVariant("animationVariant", civ); } Formation.js LoadFormation function: Formation.prototype.LoadFormation = function(newTemplate) { const newFormation = ChangeEntityTemplate(this.entity, newTemplate); let cmpVisual = Engine.QueryInterface(newFormation, IID_Visual); if (cmpVisual) { const cmpNewOwnership = Engine.QueryInterface(newFormation, IID_Ownership); const player = cmpNewOwnership.GetOwner(); const civ = QueryPlayerIDInterface(player).GetCiv(); cmpVisual.SetVariant("animationVariant", civ); } return Engine.QueryInterface(newFormation, IID_UnitAI); }; template_formation.xml Commands.js Formation.js 1 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 16, 2022 Author Report Share Posted January 16, 2022 (edited) 10 hours ago, Silier said: for a26 yes. Commands.js L1654: const cmpVisual = Engine.QueryInterface(formationEnt, IID_Visual); if (cmpVisual) { const civ = QueryPlayerIDInterface(player).GetCiv(); cmpVisual.SetVariant("animationVariant", civ); } Formation.js LoadFormation function: Formation.prototype.LoadFormation = function(newTemplate) { const newFormation = ChangeEntityTemplate(this.entity, newTemplate); let cmpVisual = Engine.QueryInterface(newFormation, IID_Visual); if (cmpVisual) { const cmpNewOwnership = Engine.QueryInterface(newFormation, IID_Ownership); const player = cmpNewOwnership.GetOwner(); const civ = QueryPlayerIDInterface(player).GetCiv(); cmpVisual.SetVariant("animationVariant", civ); } return Engine.QueryInterface(newFormation, IID_UnitAI); }; template_formation.xml 2 kB · 0 downloads Commands.js 61 kB · 0 downloads Formation.js 32 kB · 0 downloads Thank you for this. There's 1 issue: The first time the formation is created, it chooses a variation randomly, but when choosing a different formation with those same troops it chooses the correct one. Also, this error when playing a game. Happens when formationed units temporarily disband the formation when constructing or grabbing a treasure and then reform the formation afterward: Spoiler ERROR: Error in timer on entity 10888, IID105, function TimerHandler: TypeError: cmpFormationUnitAI.GetTargetPositions()[0] is undefined Formation.prototype.MoveMembersIntoFormation@simulation/components/Formation.js:534:61 Timer@simulation/components/UnitAI.js:1011:19 FSM.prototype.ProcessMessage@globalscripts/FSM.js:265:17 UnitAI.prototype.TimerHandler@simulation/components/UnitAI.js:4210:15 Timer.prototype.OnUpdate@simulation/components/Timer.js:139:44 Edited January 17, 2022 by wowgetoffyourcellphone Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 17, 2022 Author Report Share Posted January 17, 2022 1 Quote Link to comment Share on other sites More sharing options...
Silier Posted January 17, 2022 Report Share Posted January 17, 2022 Are you using svn or a25? Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 17, 2022 Author Report Share Posted January 17, 2022 Just now, Silier said: Are you using svn or a25? SVN. Quote Link to comment Share on other sites More sharing options...
Silier Posted January 17, 2022 Report Share Posted January 17, 2022 8 hours ago, wowgetoffyourcellphone said: The first time the formation is created, it chooses a variation randomly, but when choosing a different formation with those same troops it chooses the correct one Also this is strange because Commands file should take care about this case. Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 17, 2022 Author Report Share Posted January 17, 2022 I am also using just those lines of code that you added/changed in the js files, and not the entire file. Mods can do this by using a suffix to the file name (in my case, "_DE") without having to maintain the entire file (some of the component files are quite large). I will try by using the entire files and see if that fixes things? Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 17, 2022 Author Report Share Posted January 17, 2022 ERROR: JavaScript error: simulation/components/Commands.js line 1858 SetGlobal "GetFormationRequirements" called multiple times @simulation/components/Commands.js:1858:8 launchGame@gui/gamesettings/GameSettings.js:128:11 launchGame@gui/gamesetup/Controllers/GameSettingsController.js:273:18 onPress@gui/gamesetup/Pages/GameSetupPage/Panels/Buttons/StartGameButton.js:60:52 Quote Link to comment Share on other sites More sharing options...
Silier Posted January 17, 2022 Report Share Posted January 17, 2022 Did you use the suffix thing? This shouldn't be the case of you use the whole file as is. 1 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 17, 2022 Author Report Share Posted January 17, 2022 6 hours ago, Silier said: Did you use the suffix thing? This shouldn't be the case of you use the whole file as is. I used formations.js and commands.js as-is and I still get the original issue (incorrect flag when first formed, correct flag chosen thereafter), and the error code: ERROR: Error in timer on entity 10888, IID105, function TimerHandler: TypeError: cmpFormationUnitAI.GetTargetPositions()[0] is undefined Formation.prototype.MoveMembersIntoFormation@simulation/components/Formation.js:534:61 Timer@simulation/components/UnitAI.js:1011:19 FSM.prototype.ProcessMessage@globalscripts/FSM.js:265:17 UnitAI.prototype.TimerHandler@simulation/components/UnitAI.js:4210:15 Timer.prototype.OnUpdate@simulation/components/Timer.js:139:44 Quote Link to comment Share on other sites More sharing options...
Freagarach Posted January 18, 2022 Report Share Posted January 18, 2022 8 hours ago, wowgetoffyourcellphone said: I used formations.js and commands.js as-is and I still get the original issue (incorrect flag when first formed, correct flag chosen thereafter), and the error code: ERROR: Error in timer on entity 10888, IID105, function TimerHandler: TypeError: cmpFormationUnitAI.GetTargetPositions()[0] is undefined Formation.prototype.MoveMembersIntoFormation@simulation/components/Formation.js:534:61 Timer@simulation/components/UnitAI.js:1011:19 FSM.prototype.ProcessMessage@globalscripts/FSM.js:265:17 UnitAI.prototype.TimerHandler@simulation/components/UnitAI.js:4210:15 Timer.prototype.OnUpdate@simulation/components/Timer.js:139:44 This sounds _a lot_ like https://code.wildfiregames.com/D4294 is applied? 1 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 18, 2022 Author Report Share Posted January 18, 2022 33 minutes ago, Freagarach said: This sounds _a lot_ like https://code.wildfiregames.com/D4294 is applied? Ah yes. Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 18, 2022 Author Report Share Posted January 18, 2022 1 hour ago, Freagarach said: This sounds _a lot_ like https://code.wildfiregames.com/D4294 is applied? Okay, reverting D4294 fixes that particular error. However, the flag selection issue remains. Quote Link to comment Share on other sites More sharing options...
Lion.Kanzen Posted January 22, 2022 Report Share Posted January 22, 2022 On 17/01/2022 at 1:53 AM, wowgetoffyourcellphone said: You could make some generics, like the pegasus. This is how it is used for new factions. Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 22, 2022 Author Report Share Posted January 22, 2022 22 minutes ago, Lion.Kanzen said: You could make some generics, like the pegasus. This is how it is used for new factions. A pegasus to "fall back on" would be okay. Quote Link to comment Share on other sites More sharing options...
Silier Posted January 23, 2022 Report Share Posted January 23, 2022 On 17/01/2022 at 9:46 PM, wowgetoffyourcellphone said: I used formations.js and commands.js as-is and I still get the original issue (incorrect flag when first formed, correct flag chosen thereafter), and the error code: You need to put whole Commands.js under simulation/helpers 1 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 23, 2022 Author Report Share Posted January 23, 2022 6 minutes ago, Silier said: You need to put whole Commands.js under simulation/helpers Thank you! I was putting it in simulation/components. The wrong folder. Quote Link to comment Share on other sites More sharing options...
Lion.Kanzen Posted January 23, 2022 Report Share Posted January 23, 2022 To simulate a combat, in theory, as in Total War, not the entire formation would be disorganized, only the first units of each formation would fight. they would have to move little bite but without disorder. This is how it works in total war. In 0 A.D it continues as a classic RTS and it is still very buggy On many occasions, under certain circumstances, for example mixing it with civilian units or giving orders to build (etc). I speak about what is already in the svn. Quote Link to comment Share on other sites More sharing options...
Freagarach Posted January 30, 2022 Report Share Posted January 30, 2022 @wowgetoffyourcellphone My quick try for SVN: D4467. 1 Quote Link to comment Share on other sites More sharing options...
wowgetoffyourcellphone Posted January 30, 2022 Author Report Share Posted January 30, 2022 8 hours ago, Freagarach said: @wowgetoffyourcellphone My quick try for SVN: D4467. Thank you. At least the code won't be lost on the forums now. 1 Quote Link to comment Share on other sites More sharing options...
Freagarach Posted February 9, 2022 Report Share Posted February 9, 2022 (Committed in vanilla. @wowgetoffyourcellphone feel free to improve those banners. ) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.