#! /bin/bash SOURCEMOD='public' DESTMOD='new_mod' #modify these constants for simple gamewide modification #change the move speed and build time of all units MOVESPEEDMODIFIER='1.25' TRAINSPEEDMODIFIER='1.75' #women train faster but move a bit slower WOMANMOVESPEEDMODIFIER='1.2' WOMANTRAINSPEEDMODIFIER='1.25' #The population cost of various unit types INFANTRYPOP='1' CAVALRYPOP='2' SIEGEPOP='4' ELEPHANTPOP='4' #Building health and defence modifiers STRUCT_HEALTH_MOD='.5' STRUCT_HACK_MOD='.5' STRUCT_PIERCE_MOD='.5' STRUCT_CRUSH_MOD='.5' #Siege engine modifications #Note, under these defaults, seige engines are faster, change form (catapults) more quickly, #and deal massive damage to buildings, (even though damage is reduced, building armor is reduced more). #Seige engines in general are however less effective vs other units. SIEGECHANGETIME='.5' SIEGEDMG='.75' #how much wood trees give WOODAMTMODIFIER='.75' #Reusable functions for different unit types function processWalkSpeed { OLDWALKSPEED=($(xmlstarlet sel -t -v "/Entity/UnitMotion/WalkSpeed" $INFILE)) NEWWALKSPEED='' if [ ! -z $OLDWALKSPEED ] then NEWWALKSPEED=$(echo "scale=3;$OLDWALKSPEED"'*'$1 | bc) fi #cap walk speed at run speed OLDRUNSPEED=($(xmlstarlet sel -t -v "/Entity/UnitMotion/Run/Speed" $INFILE)) if [ ! -z $OLDRUNSPEED ] && [ ! -z $NEWWALKSPEED ] && [ $(echo "scale=3;$NEWWALKSPEED>$OLDRUNSPEED" | bc | xargs printf "%1.0f") == "1" ] then NEWWALKSPEED=$OLDRUNSPEED fi } function processTrainTime { OLDBUILDTIME=($(xmlstarlet sel -t -v "/Entity/Cost/BuildTime" $INFILE)) NEWBUILDTIME='' if [ ! -z $OLDBUILDTIME ] then NEWBUILDTIME=$(echo "scale=3;$OLDBUILDTIME"'*'$1 | bc) fi } #6 explicit arguments, hack *, pierce *, crush *, hack +, pierce +, crush + function processArmour { HACK=($(xmlstarlet sel -t -v "/Entity/Armour/Hack" $INFILE)) if [ ! -z $HACK ] then HACK=$(echo $HACK'*'$1'+'$4 | bc | xargs printf "%1.0f") fi PIERCE=($(xmlstarlet sel -t -v "/Entity/Armour/Pierce" $INFILE)) if [ ! -z $PIERCE ] then PIERCE=$(echo $PIERCE'*'$2'+'$5 | bc | xargs printf "%1.0f") fi CRUSH=($(xmlstarlet sel -t -v "/Entity/Armour/Crush" $INFILE)) if [ ! -z $CRUSH ] then CRUSH=$(echo $CRUSH'*'$3'+'$6 | bc | xargs printf "%1.0f") fi } #provide the new population value in $1 function processPopulation { POPULATION=($(xmlstarlet sel -t -v "/Entity/Cost/Population" $INFILE)) if [ ! -z $POPULATION ] then POPULATION=$1 fi } function fixUnusedVars { #declare all unused to variables 0 (they won't be inserted by xmlstarlet, but '' will break the script. if [ -z $NEWBUILDTIME ] then NEWBUILDTIME=0 fi if [ -z $NEWWALKSPEED ] then NEWWALKSPEED=0 fi if [ -z $CRUSH ] then CRUSH=0 fi if [ -z $HACK ] then HACK=0 fi if [ -z $PIERCE ] then PIERCE=0 fi if [ -z $HEAL ] then HEAL=0 fi if [ -z $HEALTH ] then HEALTH=0 fi if [ -z $POPULATION ] then POPULATION=0 fi } function clearVars { NEWBUILDTIME='' NEWWALKSPEED='' CRUSH='' HACK='' PIERCE='' HEAL='' HEALTH='' } function checkVars { if [ -z "$NEWBUILDTIME" ] || [ -z "$NEWWALKSPEED" ] then echo a fi } #Process infantry units function processInfantry { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #infantry take 1 population processPopulation 1 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] then fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION $INFILE > $OUTFILE fi } function processCavalry { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #cavalry cost 2 population processPopulation 2 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $POPULATION ] then fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION $INFILE > $OUTFILE fi } function processFemale { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $WOMANMOVESPEEDMODIFIER #change train speed processTrainTime $WOMANTRAINSPEEDMODIFIER #woment cost 1 population processPopulation 1 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $POPULATION ] then fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION $INFILE > $OUTFILE fi } function processSupport { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #might be interesting to have some support units cost 2 population "-u "/Entity/Cost/Population" -v $POPULATION" #processPopulation 1 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] then fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED $INFILE > $OUTFILE fi } function processShip { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed TODO this might be too big for a ship. processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #TODO find a better way to raise population if [ $1 == *'fishin'* ] || [ $1 == *'merchan'* ] then processPopulation 1 else processPopulation 2 fi #Ships can see quite far, raise vision. #Half packing time OLDVISION=($(xmlstarlet sel -t -v "/Entity/Vision/Range" $INFILE)) NEWVISION='' if [ ! -z $OLDVISION ] then NEWVISION=$(echo $OLDVISION'+10' | bc | xargs printf "%1.0f") fi if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $NEWVISION ] then fixUnusedVars if [ -z $NEWVISION ] then NEWVISION=0 fi #xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION $INFILE > $OUTFILE xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Vision/Range" -v $NEWVISION -s "/Entity/Cost" -t elem -n "Population" -v $POPULATION $INFILE > $OUTFILE fi } function processElephant { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #elephants cost 4 population processPopulation 4 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $POPULATION ] then fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION $INFILE > $OUTFILE fi #TODO cavalry units should cost an extra population #must add the xmltag /Entity/Cost/Population 2 } function processSiege { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #change train speed processTrainTime $TRAINSPEEDMODIFIER #seige cost 4 population processPopulation 4 #Friendly Fire /Entity/Attack/Ranged/Splash #Params include Range (real number) FriendlyFire (t/f), Hack, Pierce and Crush #Half packing time OLDPACKTIME=($(xmlstarlet sel -t -v "/Entity/UnitMotion/WalkSpeed" $INFILE)) NEWPACKTIME='' if [ ! -z $OLDPACKTIME ] then NEWPACKTIME=$(echo $OLDPACKTIME'*.5' | bc | xargs printf "%1.0f") fi if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $POPULATION ] || [ ! -z $NEWPACKTIME ] then fixUnusedVars if [ -z $NEWPACKTIME ] then NEWPACKTIME=0 fi xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Cost/Population" -v $POPULATION -u "/Entity/Pack/Time" -v $NEWPACKTIME $INFILE > $OUTFILE fi } function processFauna { #TODO is there a way to lower the health of small fauna and boost that of large fauna? #I would like to make large fauna more aggressive/dangerous INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #change movement speed processWalkSpeed $MOVESPEEDMODIFIER #corrales are game breaking, allowing exponential food growth. processTrainTime 2 #Animals have thick skins. +3 crush, +2 hack, +1 pierce Armour processArmour 0 0 0 2 1 3 if [ ! -z $NEWBUILDTIME ] || [ ! -z $NEWWALKSPEED ] || [ ! -z $HACK ] || [ ! -z $PIERCE ] || [ ! -z $CRUSH ] then #declare all unused to 0 (they won't be inserted by xmlstarlet) fixUnusedVars xmlstarlet ed -u "/Entity/Cost/BuildTime" -v $NEWBUILDTIME -u "/Entity/UnitMotion/WalkSpeed" -v $NEWWALKSPEED -u "/Entity/Armour/Hack" -v $HACK -u "/Entity/Armour/Pierce" -v $PIERCE -u "/Entity/Armour/Crush" -v $CRUSH $INFILE > $OUTFILE fi } function processStructure { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 #Garissons need to heal. Temples heal around 3 or 4; we want this to stay the same but have healing for other buildings too. HEAL=($(xmlstarlet sel -t -v "/Entity/GarrisonHolder/BuffHeal" $INFILE)) if [ ! -z $HEAL ] then HEAL=$(echo $HEAL'*.75+1' | bc | xargs printf "%1.0f") fi #Buildings have too much health. Half all building health HEALTH=($(xmlstarlet sel -t -v "/Entity/Health/Max" $INFILE)) if [ ! -z $HEALTH ] then #HEALTH=$(($HEALTH/2)) #HEALTH=$(expr $HEALTH/2) HEALTH=$(echo $HEALTH'*'$STRUCT_HEALTH_MOD | bc | xargs printf "%1.0f") fi #Buildings have too much armor. Half and add 1 (to reduce Armour but keep above 0) processArmour $STRUCT_HACK_MOD $STRUCT_PIERCE_MOD $STRUCT_CRUSH_MOD 1 1 1 if [ ! -z $HEAL ] || [ ! -z $HEALTH ] || [ ! -z $HACK ] || [ ! -z $PIERCE ] || [ ! -z$CRUSH ] then fixUnusedVars xmlstarlet ed -u "/Entity/GarrisonHolder/BuffHeal" -v $HEAL -u "/Entity/Health/Max" -v $HEALTH -u "/Entity/Armour/Hack" -v $HACK -u "/Entity/Armour/Pierce" -v $PIERCE -u "/Entity/Armour/Crush" -v $CRUSH $INFILE > $OUTFILE fi } function processTree { INFILE=$SOURCEMOD'/'$1 OUTFILE=$DESTMOD'/'$1 CHANGES=0 #TODO make sure the resource is wood (not food #trees have too much wood WOODAMT=($(xmlstarlet sel -t -v "/Entity/ResourceSupply/Amount" $INFILE)) if [ -z $WOODAMT ] then return fi TYPE=($(xmlstarlet sel -t -v "/Entity/ResourceSupply/Type" $INFILE)) if [[ $TYPE != "wood.tree" ]] then return fi WOODAMT=$(echo $WOODAMT'*'$WOODAMTMODIFIER | bc | xargs printf "%1.0f" ) xmlstarlet ed -u "/Entity/ResourceSupply/Amount" -v $WOODAMT $INFILE > $OUTFILE } function processEntitiesDirectory { echo "Processing Directory: \""$SOURCEMOD'/'$1"\"" mkdir -p $DESTMOD'/'$1 for f in $SOURCEMOD'/'$1'/'* do ftrim=${f#$SOURCEMOD/} if [ -d $f ] then processEntitiesDirectory $ftrim & else TRIED="true" if [[ $ftrim == *'infantry'*'xml' ]] then #echo "INFANTRY: "$ftrim processInfantry $ftrim else if [[ $f == *'cavalry'*'xml' ]] then #echo "CAVALRY: "$ftrim processCavalry $ftrim else if [[ $f == *'mechanical_siege'*'xml' ]] then processSiege $ftrim else if [[ $f == *'ship'*'xml' ]] then processShip $ftrim else if [[ $f == *'female'*'xml' ]] then processFemale $ftrim else if [[ $f == *'support'*'xml' ]] #after females to disambiguate then processSupport $ftrim else if [[ $f == *'structure'*'xml' ]] then #echo "STRUCTURE: "$ftrim processStructure $ftrim else if [[ $f == *'fauna'*'xml' ]] then #echo "FAUNA: "$ftrim processFauna $ftrim else #elephant comes after fauna to disambiguate from wild elephannts if [[ $f == *'elephant'*'xml' ]] then processElephant $ftrim else if [[ $f == *'flora_tree'*'xml' ]] then processTree $ftrim else TRIED="false" fi fi fi fi fi fi fi fi fi fi fi OUTFILE="$DESTMOD/$ftrim" if [ -e $OUTFILE ] then FILESIZE=$(stat -c%s "$OUTFILE") echo "Created \"$OUTFILE\" $FILESIZE bytes." if [ "$FILESIZE" -eq "0" ] then echo "ERROR: For an unknown reasor, processing of \"$OUTFILE\" failed." rm $OUTFILE fi else if [ $TRIED == "true" ] then echo "Did not modify \"$OUTFILE.\" No data needed to be changed." else echo "Did not modify \"$OUTFILE.\" No rules to apply to this type." fi fi done } #Some special files need unique processing, such as parents. function processSingletons { #correct populations of various unit types #cavalry FILE="simulation/templates/template_unit_cavalry.xml" INFILE="$SOURCEMOD/$FILE" OUTFILE="$DESTMOD/$FILE" xmlstarlet ed -s "/Entity/Cost" -t elem -n "Population" -v 2 $INFILE > $OUTFILE } echo "Modding Script Initialized. Processing from \"$SOURCEMOD\" to \"$DESTMOD\"" #Remove old data from destination mod folder rm -r $DESTMOD processEntitiesDirectory 'simulation/templates' wait exit