Page 3 of 4

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 8:30 am
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).

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 9:14 am
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.

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 9:29 am
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

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 10:31 am
by makazuwr32
Thanks. That's good to know.

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 12:45 pm
by Stratego (dev)
I have just cleared all trnInValidTargets from AOW and AOMW - i turned them to be trnValidTargets

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 12:55 pm
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"

Re: Changes you need to follow as Modder

Posted: Tue Aug 10, 2021 1:52 pm
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.

Re: Changes you need to follow as Modder

Posted: Thu Aug 12, 2021 4:08 pm
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

Re: Changes you need to follow as Modder

Posted: Fri Aug 13, 2021 12:33 pm
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
		}

Re: Changes you need to follow as Modder

Posted: Wed Sep 08, 2021 9:02 am
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.

Re: Changes you need to follow as Modder

Posted: Tue Oct 05, 2021 9:12 am
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 },



Re: Changes you need to follow as Modder

Posted: Tue Oct 05, 2021 2:30 pm
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.

Re: Changes you need to follow as Modder

Posted: Wed Jan 05, 2022 10:18 am
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.

Re: Changes you need to follow as Modder

Posted: Fri Jan 07, 2022 6:51 pm
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

Re: Changes you need to follow as Modder

Posted: Fri Jan 07, 2022 8:00 pm
by Stratego (dev)
4. AOW: new usages set: READY Deprecated tags removed from jsons: READY

Re: Changes you need to follow as Modder

Posted: Fri Jan 07, 2022 9:40 pm
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

Re: Changes you need to follow as Modder

Posted: Sat Jan 08, 2022 11:40 am
by Stratego (dev)
5. AOMW: new usages set: READY Deprecated tags removed from jsons: READY

Re: Changes you need to follow as Modder

Posted: Wed Jan 12, 2022 7:47 pm
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

Re: Changes you need to follow as Modder

Posted: Wed Jan 12, 2022 9:42 pm
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.

Re: Changes you need to follow as Modder

Posted: Sat Jan 15, 2022 3:59 pm
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...")





Re: Changes you need to follow as Modder

Posted: Fri Jan 28, 2022 11:38 am
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.

Re: Changes you need to follow as Modder

Posted: Sat Jan 29, 2022 6:29 am
by makazuwr32
Hm. This will affect gold mines of dwarves and maybe corpses of undeads from dig up corpse ability.

Re: Changes you need to follow as Modder

Posted: Sat Jan 29, 2022 7:33 am
by Stratego (dev)
yes

Re: Changes you need to follow as Modder

Posted: Mon Mar 07, 2022 2:10 pm
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?

Re: Changes you need to follow as Modder

Posted: Mon Mar 07, 2022 2:18 pm
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.

Re: Changes you need to follow as Modder

Posted: Mon Mar 07, 2022 2:28 pm
by L4cus
ok, how do i run the script?

Re: Changes you need to follow as Modder

Posted: Mon Mar 07, 2022 3:12 pm
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.

Re: Changes you need to follow as Modder

Posted: Thu Jan 12, 2023 2:04 pm
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

Re: Changes you need to follow as Modder

Posted: Thu Jan 12, 2023 3:20 pm
by Stratego (dev)
they python is here:
<there is newer below, get that>

Re: Changes you need to follow as Modder

Posted: Sun Feb 05, 2023 9:05 pm
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...")