Changes you need to follow as Modder

Follow this forum if u are a modder (having the modded version)
Contains announcements and how-to guides
Useful for forumers who want to learn how to help out in the game
User avatar
makazuwr32
Posts: 7830
Joined: Tue Oct 17, 2017 9:29 am
Location: Moscow, Russia

Re: Changes you need to follow as Modder

Post by makazuwr32 »

About trnvalidtargets — we also can use logic operators similar way, right?
makazuwr32 wrote: Tue Aug 10, 2021 3:44 am «u_foot, u_land, NOT(u_melee)»
Like this (for example).
Midonik
Posts: 5325
Joined: Mon Sep 05, 2016 5:27 pm
Location: Poland

Re: Changes you need to follow as Modder

Post by Midonik »

Yes - this is what I did in one of the AoG techs: "trnValidTargets":{"categories":["AND(","U_ARTILLERY_FIELD_GUN","U_HUM","NOT","U_ARTILLERY_FIELD_GUN_LASER",")","AND(","U_CHEMICAL_ARTILLERY","U_HUM",")","AND(","U_ARTILLERY_AA","U_HUM","NOT","U_ENERGY",")","AND(","U_HUM","U_ARTILLERY_AT","NOT","U_ENERGY",")","NOT","U_EMP"]},
And it works just right.
Support new AoS variant, Age of Galaxy: http://ageofstrategy.net/viewforum.php? ... 608408ebc8
All help will be welcome.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

Midonik wrote: Tue Aug 10, 2021 9:14 am Yes - this is what I did in one of the AoG techs: "trnValidTargets":{"categories":["AND(","U_ARTILLERY_FIELD_GUN","U_HUM","NOT","U_ARTILLERY_FIELD_GUN_LASER",")","AND(","U_CHEMICAL_ARTILLERY","U_HUM",")","AND(","U_ARTILLERY_AA","U_HUM","NOT","U_ENERGY",")","AND(","U_HUM","U_ARTILLERY_AT","NOT","U_ENERGY",")","NOT","U_EMP"]},
And it works just right.
gosh :)

also if i try to translate it :
Midoniks case valid targets are:
All Human Artilleries (field, chemical, AA, AT) except Field laser, energy guns and EMP units

as i see
User avatar
makazuwr32
Posts: 7830
Joined: Tue Oct 17, 2017 9:29 am
Location: Moscow, Russia

Re: Changes you need to follow as Modder

Post by makazuwr32 »

Thanks. That's good to know.
makazuwr32 wrote: Mon Sep 16, 2019 7:54 amWhen you ask to change something argument why...
Put some numbers, compare to what other races have and so on...
© by Makazuwr32™.
AoF Dev Co-Leader
Image
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

I have just cleared all trnInValidTargets from AOW and AOMW - i turned them to be trnValidTargets
Midonik
Posts: 5325
Joined: Mon Sep 05, 2016 5:27 pm
Location: Poland

Re: Changes you need to follow as Modder

Post by Midonik »

Oh I missed that I was supposed to remove invalid targets too. Is that gone cause crashes?
I guess I can just change to valid tragets and "U_ALL","NOT","category_that_was_in_invalid_targets"
Support new AoS variant, Age of Galaxy: http://ageofstrategy.net/viewforum.php? ... 608408ebc8
All help will be welcome.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

i am sure there is a more sophisticated way to set it.

eg. if invalid was air units than valids can be ground+naval units

and so on.

also i can help in it i just did it in 2 alternatives relatively fast(as there were mosty used template referencing), just send me a pack and i will do.
i will send about 8 eamils asking if the "negate" i figured out is ok or not, this worked fine with Harchie.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

During Unity development i debugged for more than 1.5 hour to find this problem:

in several jsons there is wrongly set the spec cost, like:
"specCost":0,

This does not make any problem in android version but in unity version it misbehaves (like it would have SACRIFICE_UNIT spec cost)

so please replace all
"specCost":0,
to
"specCost":null,

in your assets, this TAG must have null if ment to be unset.

same tru to
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

for unity version these ones will go out for modders to be able to change.
and unity version will not work without these, so pelase everyone put these lines into textures part of graphics.json

Code: Select all

,   
		{
			"idString": "TEXTURE_MULTIPLE_EFFECTS",
            "imgColumns":1,
            "imgName":"indicator_multi_effected.png",
			"withColoring": false
		},   
		{
			"idString": "TEXTURE_MULTIPLE_AURAS",
            "imgColumns":1,
            "imgName":"indicator_aura_multi.png",
			"withColoring": false
		},   
		{
			"idString": "TEXTURE_INDICATOR_WAYPOINT",
            "imgColumns":1,
            "imgName":"indicators/indicator_waypoint.png",
			"withColoring": false
		},   
		{
			"idString": "TEXTURE_INDICATOR_LAZY_FACTORY",
            "imgColumns":1,
            "imgName":"indicator_lazyfactory.png",
			"withColoring": false
		}
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

please put these 2 definition into the graphics.json.
if u miss to the game will crash.

Code: Select all

		{
			"idString": "TEXTURE_ATTACK_DEFAULT",
            "imgColumns":1,
            "imgName":"templates/damage_vs_armor_default.png",
			"withColoring": false
		},   
		{
			"idString": "TEXTURE_ATTACK_SECOND",
            "imgColumns":1,
            "imgName":"templates/damage_vs_armor_second.png",
			"withColoring": false
		}
		

i placed it in AOF/AOS/AOG/AOW/AOMW in my local assets.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

from next update the special shopitems will only work or appear if you place these lines into the shopconfig file
they are mostly same in all variants, except maybe a few image differences.

this is the Cure, Clone and such special buttons in the column 3 and 4.


Code: Select all

  {"shopItemId": 100, "columnNr": 3, "gemCost": 2, "imgName": "shop_lurking.png",  "txtNiceNameStringID": "SHOP_REVEAL_NAME",   "messageTextIdent": "SHOP_REVEAL", "spec":"SHOP_REVEAL", "reSellable": true, "unitTypeName": null },  
  {"shopItemId": 110, "columnNr": 3, "gemCost": 2, "imgName": "shop_cure2.png",    "txtNiceNameStringID": "SHOP_CURE_NAME",     "messageTextIdent": "SHOP_CURE", "spec":"SHOP_CURE", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 145, "columnNr": 3, "gemCost": 3, "imgName": "shop_strength.png", "txtNiceNameStringID": "SHOP_STRENGTH_NAME", "messageTextIdent": "SHOP_STRENGTH", "spec":"SHOP_STRENGTH", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 130, "columnNr": 3, "gemCost": 5, "imgName": "units/unit_moneyman.png",  "txtNiceNameStringID": "SHOP_PROD_COIN_NAME",   "messageTextIdent": "SHOP_PROD_COIN", "spec":null, "reSellable": false, "unitTypeName": null },
  
  
  
  
  {"shopItemId": 200, "columnNr": 4, "gemCost": 2, "imgName": "shop_unlock.png", "txtNiceNameStringID": "SHOP_UNLOCK_NAME", "messageTextIdent": "SHOP_UNLOCK", "spec":"SHOP_UNLOCK", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 150, "columnNr": 4, "gemCost": 2, "imgName": "shop_stuffy_doll.png", "txtNiceNameStringID": "SHOP_STUFFY_DOLL_NAME", "messageTextIdent": "SHOP_STUFFY_DOLL", "spec":"SHOP_STUFFY_DOLL", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 140, "columnNr": 4, "gemCost": 3, "imgName": "shop_incinerate.png", "txtNiceNameStringID": "SHOP_INCINERATE_NAME", "messageTextIdent": "SHOP_INCINERATE", "spec":"SHOP_INCINERATE", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 160, "columnNr": 4, "gemCost": 5, "imgName": "32_convert.png", "txtNiceNameStringID": "SHOP_CONVERT_NAME", "messageTextIdent": "SHOP_CONVERT", "spec":"SHOP_CONVERT", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 120, "columnNr": 4, "gemCost": 3, "imgName": "shop_production_transfer.png", "txtNiceNameStringID": "SHOP_PROD_TRN_NAME", "messageTextIdent": "SHOP_PROD_TRN", "spec":"SHOP_PROD_TRN", "reSellable": true, "unitTypeName": null },
  {"shopItemId": 155, "columnNr": 4, "gemCost": 4, "imgName": "shop_clone.png", "txtNiceNameStringID": "SHOP_CLONE_NAME", "messageTextIdent": "SHOP_CLONE", "spec":"SHOP_CLONE", "reSellable": true, "unitTypeName": null },


Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

i just saw that the ""shopItemId": 130" line (so the moneyman) only exists in AOF and AOS.
in other variants ignore that line.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

I realized this post should be here:
-------------------------------------------------
I am working on the "on-demand" unit load version in all alternatives.
for that these tags are now only used from specunitactions so these Units json tags are obsolete from now:

1. "isFactoryThatNotAffectsFactoryLimits" -> use spec IS_FACTORY_NOT_COUNTED
2. "buildableSubType" eg. TECH_LEVEL_UP -> use spec TECH_LEVEL_UP instead
3. "isOccupiableBuilding" -> use spec IS_TC or IS_OCCUPIABLE instead
4. "isFunModeBuildable" -> use spec IS_FUN_UNIT
5. "grantorShopItems" -> use the new unit-list option in shoplist.json
6. "isStealthUnit" -> use spec STEALTH_UNIT or STEALTH_ONLY_UNIT
7. "trnRequires" + "trnRevokerTechs" + "upgradeAncestor": all these are to be set in the new unit_relations.txt

Please every modder post here if
a) ready with updating these
b) asks me to help making it in their pack.

Current status i know in alternatives:
1. AOS: new usages set: READY Deprecated tags removed from jsons: READY
2. AOG: new usages set: READY Deprecated tags removed from jsons: READY
3. AOF: new usages set: READY Deprecated tags removed from jsons: READY
4. AOW: new usages set: READY Deprecated tags removed from jsons: READY
5. AOMW: new usages set: READY Deprecated tags removed from jsons: READY
others?



"Deprecated tags removed from jsons" hopefuly will be removed with same clearing scipt Endru made, and i will run in all alternatives.
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

Endru made cute regex to delete an attribute from all files, i used it to clear AOW

i used 7 replaces with notepad++ (row by row) and now all jsons are clear.

Code: Select all

[ \t]+"grantorShopItems"\s*:\s*[^\n]*\n
[ \t]+"trnRequires"\s*:\s*[^\n]*\n
[ \t]+"trnUpgradeAncestor"\s*:\s*[^\n]*\n
[ \t]+"trnRevokerTechs"\s*:\s*[^\n]*\n
[ \t]+"isFactoryThatNotAffectsFactoryLimits"\s*:\s*[^\n]*\n
[ \t]+"isOccupiableBuilding"\s*:\s*[^\n]*\n
[ \t]+"isStealthUnit"\s*:\s*[^\n]*\n
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

4. AOW: new usages set: READY Deprecated tags removed from jsons: READY
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

2. AOG: new usages set: READY Deprecated tags removed from jsons: READY
3. AOF: new usages set: READY Deprecated tags removed from jsons: READY
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

5. AOMW: new usages set: READY Deprecated tags removed from jsons: READY
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

I would need a confirmation that in ALL variants ALL units first "visuals" item is the Default unit image.

(i want to rely on that)

thanks!

daniel
User avatar
Endru1241
Posts: 2717
Joined: Fri Sep 11, 2015 8:43 am
Location: Poland

Re: Changes you need to follow as Modder

Post by Endru1241 »

I counted regex hits:
\[\s+\{\s+"imgName":[^\n]+\n([^\n\}]+\n)*\s+"type":"DEFAULT"
against regex count of :
\[\s+\{\s+"imgName":[^\n]+\n([^\n\}]+\n)*\s+"type":

It's the same 783 files, so must be always first.
Age of Strategy design leader
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

from next update new python scriot will be needed (a new field in the gen_units.txt file)
here

Code: Select all


from os import listdir
from os.path import isfile, join
import json

path_units="units/"
fname_unit_id_filename_rel = "id/gen_unit_id.txt"
fname_unit_categories = "id/gen_unit_categories.txt"
fname_unit_builders = "id/gen_unit_builders.json"

onlyfiles = [f for f in listdir(path_units) if isfile(join(path_units, f)) and f.endswith(".json")]


f_unit_id_filename_rel = open(fname_unit_id_filename_rel, 'w')
f_unit_categories = open(fname_unit_categories, 'w')
f_unit_builders = open(fname_unit_builders, 'w')
f_unit_builders.write("{\"list\":[" + "\n")

collected_errors = ""

for filename in onlyfiles :
    with open(path_units+filename) as f:
      print("processing:" + filename)
      data = json.load(f)
      specs=""
      races=""
      is_fact="N"
      is_tech="N"
      default_image=""
      default_image_imgcolumns="1"
      unit_cost="0"
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']:
          if 'trnRaces' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnRaces'] is not None:
              races=str(data['unitStatSheet']['unit']['trnRaces']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'trnSpecUnitActions' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnSpecUnitActions'] is not None:
              specs=str(data['unitStatSheet']['unit']['trnSpecUnitActions']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'isTechnology' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isTechnology']==True:
              is_tech="Y"
          if 'isFactory' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isFactory']==True:
              is_fact="Y"
          if 'costTurn' in data['unitStatSheet']['unit']:      
            unit_cost=str(data['unitStatSheet']['unit']['costTurn'])
      if 'uiDefinition' in data:
        if 'visuals' in data['uiDefinition']:
          if len(data['uiDefinition']['visuals'])>0:
            if 'imgName' in data['uiDefinition']['visuals'][0]:
              default_image = data['uiDefinition']['visuals'][0]['imgName']
              if data['uiDefinition']['visuals'][0]['type'] != "DEFAULT":
                collected_errors = collected_errors + "ERROR: 0th visual is not default:" + filename + "\n"
              default_image_imgcolumns = str(data['uiDefinition']['visuals'][0]['imgColumns'])
      f_unit_id_filename_rel.write(str(data['unitType']) + "|" + data['unitTypeName']   + "|" + filename  + "|" + unit_cost + "|"  + default_image + "|" + default_image_imgcolumns + "|"  + specs + "|" + races +  "|" + is_tech + "|" + is_fact + ";" + "\n")
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']: 
          if 'trnCategories' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnCategories'] is not None: 
              if str(data['unitStatSheet']['unit']['trnCategories']) != '[]': 
                f_unit_categories.write(data['unitTypeName'] + ":" + str(data['unitStatSheet']['unit']['trnCategories']) + ";" + "\n")
          if 'trnBuilders' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnBuilders'] is not None: 
              if str(data['unitStatSheet']['unit']['trnBuilders']) != '[]': 
                if str(data['unitStatSheet']['unit']['trnBuilders']) != '{}': 
                  f_unit_builders.write("{\"unitIdString\":" + "\""  + data['unitTypeName'] + "\"," + "\"trnBuilders\":" + str(data['unitStatSheet']['unit']['trnBuilders']).replace("'", "\"") + "}")
                  if filename == onlyfiles[-1]:
                    f_unit_builders.write("\n")
                  else:
                    f_unit_builders.write("," + "\n")
                  

f_unit_builders.write("]}" + "\n")
      
print(fname_unit_id_filename_rel + " written\n")
print(fname_unit_categories + " written\n")
print(fname_unit_builders + " written\n")

print("Errors:" + collected_errors)
input("Press Enter to continue...")




Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

new section in unit realtions file:
viewtopic.php?f=215&t=12132&p=132667#p132652

and from next update we need to delete ALL RndProd setting from unit jsons, all are deprecated.
luckily these are only a few jsons in all alternatives - rarely used option.
User avatar
makazuwr32
Posts: 7830
Joined: Tue Oct 17, 2017 9:29 am
Location: Moscow, Russia

Re: Changes you need to follow as Modder

Post by makazuwr32 »

Hm. This will affect gold mines of dwarves and maybe corpses of undeads from dig up corpse ability.
makazuwr32 wrote: Mon Sep 16, 2019 7:54 amWhen you ask to change something argument why...
Put some numbers, compare to what other races have and so on...
© by Makazuwr32™.
AoF Dev Co-Leader
Image
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

yes
User avatar
L4cus
Posts: 2358
Joined: Fri Jan 31, 2020 7:51 pm
Location: Perú

Re: Changes you need to follow as Modder

Post by L4cus »

Stratego (dev) wrote: Sat Jan 15, 2022 3:59 pm from next update new python scriot will be needed (a new field in the gen_units.txt file)
here

Code: Select all


from os import listdir
from os.path import isfile, join
import json

path_units="units/"
fname_unit_id_filename_rel = "id/gen_unit_id.txt"
fname_unit_categories = "id/gen_unit_categories.txt"
fname_unit_builders = "id/gen_unit_builders.json"

onlyfiles = [f for f in listdir(path_units) if isfile(join(path_units, f)) and f.endswith(".json")]


f_unit_id_filename_rel = open(fname_unit_id_filename_rel, 'w')
f_unit_categories = open(fname_unit_categories, 'w')
f_unit_builders = open(fname_unit_builders, 'w')
f_unit_builders.write("{\"list\":[" + "\n")

collected_errors = ""

for filename in onlyfiles :
    with open(path_units+filename) as f:
      print("processing:" + filename)
      data = json.load(f)
      specs=""
      races=""
      is_fact="N"
      is_tech="N"
      default_image=""
      default_image_imgcolumns="1"
      unit_cost="0"
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']:
          if 'trnRaces' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnRaces'] is not None:
              races=str(data['unitStatSheet']['unit']['trnRaces']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'trnSpecUnitActions' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnSpecUnitActions'] is not None:
              specs=str(data['unitStatSheet']['unit']['trnSpecUnitActions']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'isTechnology' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isTechnology']==True:
              is_tech="Y"
          if 'isFactory' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isFactory']==True:
              is_fact="Y"
          if 'costTurn' in data['unitStatSheet']['unit']:      
            unit_cost=str(data['unitStatSheet']['unit']['costTurn'])
      if 'uiDefinition' in data:
        if 'visuals' in data['uiDefinition']:
          if len(data['uiDefinition']['visuals'])>0:
            if 'imgName' in data['uiDefinition']['visuals'][0]:
              default_image = data['uiDefinition']['visuals'][0]['imgName']
              if data['uiDefinition']['visuals'][0]['type'] != "DEFAULT":
                collected_errors = collected_errors + "ERROR: 0th visual is not default:" + filename + "\n"
              default_image_imgcolumns = str(data['uiDefinition']['visuals'][0]['imgColumns'])
      f_unit_id_filename_rel.write(str(data['unitType']) + "|" + data['unitTypeName']   + "|" + filename  + "|" + unit_cost + "|"  + default_image + "|" + default_image_imgcolumns + "|"  + specs + "|" + races +  "|" + is_tech + "|" + is_fact + ";" + "\n")
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']: 
          if 'trnCategories' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnCategories'] is not None: 
              if str(data['unitStatSheet']['unit']['trnCategories']) != '[]': 
                f_unit_categories.write(data['unitTypeName'] + ":" + str(data['unitStatSheet']['unit']['trnCategories']) + ";" + "\n")
          if 'trnBuilders' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnBuilders'] is not None: 
              if str(data['unitStatSheet']['unit']['trnBuilders']) != '[]': 
                if str(data['unitStatSheet']['unit']['trnBuilders']) != '{}': 
                  f_unit_builders.write("{\"unitIdString\":" + "\""  + data['unitTypeName'] + "\"," + "\"trnBuilders\":" + str(data['unitStatSheet']['unit']['trnBuilders']).replace("'", "\"") + "}")
                  if filename == onlyfiles[-1]:
                    f_unit_builders.write("\n")
                  else:
                    f_unit_builders.write("," + "\n")
                  

f_unit_builders.write("]}" + "\n")
      
print(fname_unit_id_filename_rel + " written\n")
print(fname_unit_categories + " written\n")
print(fname_unit_builders + " written\n")

print("Errors:" + collected_errors)
input("Press Enter to continue...")




is "gen_unit_id.txt" a new file in id folder?
Extra ecclesiam nulla salus...
AOD, a new variant...
viewforum.php?f=230
User avatar
Endru1241
Posts: 2717
Joined: Fri Sep 11, 2015 8:43 am
Location: Poland

Re: Changes you need to follow as Modder

Post by Endru1241 »

L4cus wrote: Mon Mar 07, 2022 2:10 pm
Stratego (dev) wrote: Sat Jan 15, 2022 3:59 pm from next update new python scriot will be needed (a new field in the gen_units.txt file)
here

Code: Select all


from os import listdir
from os.path import isfile, join
import json

path_units="units/"
fname_unit_id_filename_rel = "id/gen_unit_id.txt"
fname_unit_categories = "id/gen_unit_categories.txt"
fname_unit_builders = "id/gen_unit_builders.json"

onlyfiles = [f for f in listdir(path_units) if isfile(join(path_units, f)) and f.endswith(".json")]


f_unit_id_filename_rel = open(fname_unit_id_filename_rel, 'w')
f_unit_categories = open(fname_unit_categories, 'w')
f_unit_builders = open(fname_unit_builders, 'w')
f_unit_builders.write("{\"list\":[" + "\n")

collected_errors = ""

for filename in onlyfiles :
    with open(path_units+filename) as f:
      print("processing:" + filename)
      data = json.load(f)
      specs=""
      races=""
      is_fact="N"
      is_tech="N"
      default_image=""
      default_image_imgcolumns="1"
      unit_cost="0"
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']:
          if 'trnRaces' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnRaces'] is not None:
              races=str(data['unitStatSheet']['unit']['trnRaces']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'trnSpecUnitActions' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnSpecUnitActions'] is not None:
              specs=str(data['unitStatSheet']['unit']['trnSpecUnitActions']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'isTechnology' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isTechnology']==True:
              is_tech="Y"
          if 'isFactory' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isFactory']==True:
              is_fact="Y"
          if 'costTurn' in data['unitStatSheet']['unit']:      
            unit_cost=str(data['unitStatSheet']['unit']['costTurn'])
      if 'uiDefinition' in data:
        if 'visuals' in data['uiDefinition']:
          if len(data['uiDefinition']['visuals'])>0:
            if 'imgName' in data['uiDefinition']['visuals'][0]:
              default_image = data['uiDefinition']['visuals'][0]['imgName']
              if data['uiDefinition']['visuals'][0]['type'] != "DEFAULT":
                collected_errors = collected_errors + "ERROR: 0th visual is not default:" + filename + "\n"
              default_image_imgcolumns = str(data['uiDefinition']['visuals'][0]['imgColumns'])
      f_unit_id_filename_rel.write(str(data['unitType']) + "|" + data['unitTypeName']   + "|" + filename  + "|" + unit_cost + "|"  + default_image + "|" + default_image_imgcolumns + "|"  + specs + "|" + races +  "|" + is_tech + "|" + is_fact + ";" + "\n")
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']: 
          if 'trnCategories' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnCategories'] is not None: 
              if str(data['unitStatSheet']['unit']['trnCategories']) != '[]': 
                f_unit_categories.write(data['unitTypeName'] + ":" + str(data['unitStatSheet']['unit']['trnCategories']) + ";" + "\n")
          if 'trnBuilders' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnBuilders'] is not None: 
              if str(data['unitStatSheet']['unit']['trnBuilders']) != '[]': 
                if str(data['unitStatSheet']['unit']['trnBuilders']) != '{}': 
                  f_unit_builders.write("{\"unitIdString\":" + "\""  + data['unitTypeName'] + "\"," + "\"trnBuilders\":" + str(data['unitStatSheet']['unit']['trnBuilders']).replace("'", "\"") + "}")
                  if filename == onlyfiles[-1]:
                    f_unit_builders.write("\n")
                  else:
                    f_unit_builders.write("," + "\n")
                  

f_unit_builders.write("]}" + "\n")
      
print(fname_unit_id_filename_rel + " written\n")
print(fname_unit_categories + " written\n")
print(fname_unit_builders + " written\n")

print("Errors:" + collected_errors)
input("Press Enter to continue...")




is "gen_unit_id.txt" a new file in id folder?
When no file exist script should create new one.
If file with such name already exist - script will write over it.
Age of Strategy design leader
User avatar
L4cus
Posts: 2358
Joined: Fri Jan 31, 2020 7:51 pm
Location: Perú

Re: Changes you need to follow as Modder

Post by L4cus »

ok, how do i run the script?
Extra ecclesiam nulla salus...
AOD, a new variant...
viewforum.php?f=230
User avatar
Endru1241
Posts: 2717
Joined: Fri Sep 11, 2015 8:43 am
Location: Poland

Re: Changes you need to follow as Modder

Post by Endru1241 »

L4cus wrote: Mon Mar 07, 2022 2:28 pm ok, how do i run the script?
On windows?
Install python, include adding python folders to PATH in installation, restart system.
Then open cmd in script folder and write:
python scriptfilename.py
Or double click on it if you associated .py files with python during installation.
Age of Strategy design leader
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

ok, there is a new python script please use this
- will check if you use proper existing effect reference in unit jsons (in trnWeaponEffects)
- the script now generates an ID file for effects too
- checks if effect names are unique
- checks if effect ID-s are unique
- handles AOF non jsoned effects too

i have found many format problems in effects folder among several alternatives (AOS was impeccable though) eg:
- there were many TEXTURE_XY references without quotes (")
- there were wrong float formats like 1.3f instead of 1.3
- and so on
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

they python is here:
<there is newer below, get that>
Stratego (dev)
Site Admin
Posts: 15734
Joined: Fri Apr 25, 2014 9:28 pm

Re: Changes you need to follow as Modder

Post by Stratego (dev) »

ok, the python again changed showing new error and warning messages, please check and fix if you see them.
- error if "effectDefIDRelated" is used instead of "trnEffectDefIDRelated"
- warning if "effDefault" is not set on a spell definition.

Code: Select all

from os import listdir
from os.path import isfile, join
import json


print("Effects start")

path_work="effects/"
fname_output = "id/gen_effect_id.txt"


collected_errors = ""
used_effect_names=","
used_effect_ids=","
used_effect_id_max=0

onlyfiles = [f for f in listdir(path_work) if isfile(join(path_work, f)) and f.endswith(".json")]
f_workfile = open(fname_output, 'w')
cnt=0
sum=len(onlyfiles)
for filename in onlyfiles :    
    with open(path_work+filename) as f:
      cnt=cnt+1
      print(str(cnt)+"/"+str(sum)+ " effect processing:" + filename)
      data = json.load(f)
      effect_id=str(data['effectDefID'])
      effect_name_string=data['effectNameString']
      if 'effectDefIDRelated' in data and data['effectDefIDRelated'] is not None and data['effectDefIDRelated'] != 0:
        collected_errors = collected_errors + "ERROR effectDefIDRelated must not be used!:" + effect_name_string + "\n"
      if ","+effect_name_string+"," in used_effect_names:
        collected_errors = collected_errors + "duplicate effect name:" + effect_name_string + "\n"
      else:
        used_effect_names=used_effect_names+effect_name_string+","      
      if ","+effect_id+"," in used_effect_ids:
        collected_errors = collected_errors + "duplicate effect id:" + effect_id + "\n"
      else:
        used_effect_ids=used_effect_ids+effect_id+","        
      if used_effect_id_max < int(effect_id):
        used_effect_id_max = int(effect_id)
      f_workfile.write(effect_id + "," + effect_name_string + "," + filename + ";" + "\n")
   
print("\n\n")   
print(fname_output + " written\n")


print("Units start")

path_units="units/"
fname_unit_id_filename_rel = "id/gen_unit_id.txt"
fname_unit_categories = "id/gen_unit_categories.txt"
fname_unit_builders = "id/gen_unit_builders.json"

onlyfiles = [f for f in listdir(path_units) if isfile(join(path_units, f)) and f.endswith(".json")]


f_unit_id_filename_rel = open(fname_unit_id_filename_rel, 'w')
f_unit_categories = open(fname_unit_categories, 'w')
f_unit_builders = open(fname_unit_builders, 'w')
f_unit_builders.write("{\"list\":[" + "\n")


used_ids=","
used_id_max=0
used_unit_type_names=","
collected_non_jsoned=","
cnt=0
sum=len(onlyfiles)
known_non_jsoneds=",EFFECT_INSTANT_SWING_AROUND_EFFECT,EFFECT_ENCHANT_VANISHING,EFFECT_FIRE_ARROWS,EFFECT_FIRE_ARROWS_INSTANT,EFFECT_FIRE_ARROWS_ON_EVERYONE,EFFECT_ENCHANT_VANISHING_SILENT,EFFECT_ENCHANT_POISONED_WEAPON,EFFECT_TRAMPLE,EFFECT_ENCHANT_FIRE_WEAPON,EFFECT_ENCHANT_LIGHTNING_WEAPON,EFFECT_INSTANT_THUNDER_STRIKE,EFFECT_INSTANT_FIREBALL_UNDEAD,EFFECT_INSTANT_FIREBALL_EFFECT,EFFECT_INSTANT_THUNDER_STORM,EFFECT_ENCHANTMENT_CURSED,EFFECT_INSTANT_DRAGON_FIRE,EFFECT_INSTANT_DRAGON_BREATH,EFFECT_INSTANT_BANSHEE_SCREAM,EFFECT_ENCHANT_FEAR,EFFECT_IMMEDIATE_CONVERSION,EFFECT_INSTANT_SACRI_HP_DAMAGE,EFFECT_SLOWING,EFFECT_SLOWING_1,EFFECT_INSTANT_TROLL_ROT,EFFECT_DISARMOR,EFFECT_INSTANT_PAIN_DAMAGER,EFFECT_INSTANT_CASTER_AND_TARGET_DIES,EFFECT_INSTANT_SUMMON_SKELETON,EFFECT_ANIMATE_DEAD,EFFECT_ANIMATE_DEAD_CLOSE,EFFECT_INSTANT_INCREMENT_VANISHING,EFFECT_INSTANT_MAGIC_ARROW,EFFECT_AURA_LIFELINK,EFFECT_ENCHANT_VISION,EFFECT_AURA_VISION_ULIMITED,EFFECT_VISION,EFFECT_ENCHANT_STRENGTHEN,EFFECT_ENCHANT_STRENGTHEN_MYSELF,EFFECT_INSTANT_TRAMPLE,EFFECT_INSTANT_HEAL_3,EFFECT_INSTANT_EAT_CORPSE_TO_HEAL,EFFECT_STRENGTH_1ATTACK,EFFECT_STRENGTH_2ATTACK,EFFECT_STRENGTH_3ATTACK,EFFECT_AURA_STRENGTH_1ATTACK_ULIMITED,EFFECT_AURA_STRENGTH_2ATTACK_ULIMITED,EFFECT_AURA_STRENGTH_3ATTACK_ULIMITED,EFFECT_CAST_AURA_STRENGTH_1ATTACK,EFFECT_AURA_STRENGTH_1ATTACK,EFFECT_CAST_FIRE_WEAPON,EFFECT_CAST_LIGHTNING_WEAPON,EFFECT_ENCHANT_FORESTWALK,"
for filename in onlyfiles :
    with open(path_units+filename) as f:
      cnt=cnt+1
      print(str(cnt)+"/"+str(sum)+ " unit processing:" + filename)
      data = json.load(f)
      specs=""
      races=""
      is_fact="N"
      is_tech="N"
      default_image=""
      default_image_imgcolumns="1"
      unit_cost="0"
      unit_typeid=str(data['unitType'])
      unit_typename=data['unitTypeName']
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']:
          if 'trnRaces' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnRaces'] is not None:
              races=str(data['unitStatSheet']['unit']['trnRaces']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'trnSpecUnitActions' in data['unitStatSheet']['unit']:
            if data['unitStatSheet']['unit']['trnSpecUnitActions'] is not None:
              specs=str(data['unitStatSheet']['unit']['trnSpecUnitActions']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
          if 'trnWeaponEffects' in data['unitStatSheet']['unit']:
            we=data['unitStatSheet']['unit']['trnWeaponEffects']
            if we is not None:
              for weaponeffect in we:                
                  if 'effOptions' in weaponeffect:                 
                    if weaponeffect['effOptions'] is not None:
                      effects=str(weaponeffect['effOptions']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
                      effectssplit=effects.split(sep=",")                  
                      if ('effDefault' not in weaponeffect):
                        collected_errors = collected_errors + ".........................MISSING trnWeaponEffects/effDefault in:" + unit_typename + "\n"
                      else:
                        if (weaponeffect['effDefault'] is None): 
                          collected_errors = collected_errors + ".........................EMPTY trnWeaponEffects/effDefault in:" + unit_typename + "\n"
                      if ('effDefault' in weaponeffect) and (weaponeffect['effDefault'] is not None):
                        effect_default_option=str(weaponeffect['effDefault']).replace("'", "").replace(" ", "").replace("[", "").replace("]", "")
                        effectssplit.append(effect_default_option)
                      for effectitem in effectssplit:
                        if ","+effectitem+"," not in used_effect_names:
                          if ","+effectitem+"," in known_non_jsoneds:
                            if ","+effectitem+"," not in collected_non_jsoned:
                              collected_non_jsoned = collected_non_jsoned  + effectitem + ","
                          else:
                            collected_errors = collected_errors + "MISSING effect definition:" + effectitem + " in:" + unit_typename + "\n"
          if 'isTechnology' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isTechnology']==True:
              is_tech="Y"
          if 'isFactory' in data['unitStatSheet']['unit']:  
            if data['unitStatSheet']['unit']['isFactory']==True:
              is_fact="Y"
          if 'costTurn' in data['unitStatSheet']['unit']:      
            unit_cost=str(data['unitStatSheet']['unit']['costTurn'])
      if 'uiDefinition' in data:
        if 'visuals' in data['uiDefinition']:
          if len(data['uiDefinition']['visuals'])>0:
            if 'imgName' in data['uiDefinition']['visuals'][0]:
              default_image = data['uiDefinition']['visuals'][0]['imgName']
              if data['uiDefinition']['visuals'][0]['type'] != "DEFAULT":
                collected_errors = collected_errors + "ERROR: 0th visual is not default:" + filename + "\n"
              default_image_imgcolumns = str(data['uiDefinition']['visuals'][0]['imgColumns'])            
      if ","+unit_typeid+"," in used_ids:
        collected_errors = collected_errors + "duplicate id:" + unit_typeid + "\n"
      else:
        used_ids=used_ids+unit_typeid+","
      if used_id_max < int(unit_typeid):
        used_id_max = int(unit_typeid)
      if ","+unit_typename+"," in used_unit_type_names:        
        collected_errors = collected_errors + "duplicate type name:" + unit_typename + "\n"
      else:
        used_unit_type_names=used_unit_type_names+unit_typename+","        
      f_unit_id_filename_rel.write( unit_typeid + "|" +  unit_typename  + "|" + filename  + "|" + unit_cost + "|"  + default_image + "|" + default_image_imgcolumns + "|"  + specs + "|" + races +  "|" + is_tech + "|" + is_fact + ";" + "\n")
      if 'unitStatSheet' in data: 
        if 'unit' in data['unitStatSheet']: 
          if 'trnCategories' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnCategories'] is not None: 
              if str(data['unitStatSheet']['unit']['trnCategories']) != '[]': 
                f_unit_categories.write(data['unitTypeName'] + ":" + str(data['unitStatSheet']['unit']['trnCategories']) + ";" + "\n")
          if 'trnBuilders' in data['unitStatSheet']['unit']: 
            if data['unitStatSheet']['unit']['trnBuilders'] is not None: 
              if str(data['unitStatSheet']['unit']['trnBuilders']) != '[]': 
                if str(data['unitStatSheet']['unit']['trnBuilders']) != '{}': 
                  f_unit_builders.write("{\"unitIdString\":" + "\""  + data['unitTypeName'] + "\"," + "\"trnBuilders\":" + str(data['unitStatSheet']['unit']['trnBuilders']).replace("'", "\"") + "}")
                  if filename == onlyfiles[-1]:
                    f_unit_builders.write("\n")
                  else:
                    f_unit_builders.write("," + "\n")
                  

f_unit_builders.write("]}" + "\n")
print("\n\n")      

print(fname_unit_id_filename_rel + " written\n")
print(fname_unit_categories + " written\n")
print(fname_unit_builders + " written\n")

print("Last effect id:" + str(used_effect_id_max))
print("Last unit id:" + str(used_id_max) + "\n(warning! in many alternatives the biggest ID-s  are spec ids - so not the real last one among units...)\n")


if collected_non_jsoned!=",":
  print("Error " + str(collected_non_jsoned.count(",") - 1) + " NON JSONED EFFECTS:\n"   + collected_non_jsoned + "\n")  

print("Errors:\n" + collected_errors)
input("Press Enter to continue...")



Post Reply

Return to “Modders lounge”