diff --git a/xtrn/war/convert_game.js b/xtrn/war/convert_game.js new file mode 100644 index 0000000000000000000000000000000000000000..3c3a14a8ed41cdd5c04d5dd94c9546f051773fa0 --- /dev/null +++ b/xtrn/war/convert_game.js @@ -0,0 +1,282 @@ +var game={ + ncnt:0, + nations:[], + cities:[], + ttypes:[], + armies:[], + move_table:[] +}; + +var fp; +var inbuf=''; +var p=''; +var cnt, ttcnt, acnt, mcnt, nt, i, j; +var nbytes; +var a_nation, a_r, a_c, a_combat, a_hero, + a_move_rate, a_move_tbl, a_special_mv, a_eparm1; + +/* initialize armies table */ +game.armies=[]; + +/* open the game save */ + +fp = new File(js.exec_dir+'/'+'game.orig'); +if(!fp.open("rb")) { + alert("Unable to open "+fp.name); + exit(1); +} + +if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read first line of "+fp.name); + exit(1); +} + +if(inbuf.substr(0,2) != 'G ') { + fp.close(); + alert("Invalid Header in "+fp.name); + exit(1); +} + +cnt = ttcnt = acnt = mcnt = -1; + +gen = 0; + +game.world = ''; + +m=inbuf.match(/^G ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) g([0-9]+) ([^\s]{0,40})\s*$/); +if(m==null) { + fp.close(); + alert("Invalid header in "+fp.name); + exit(1); +} +game.ncnt=parseInt(m[1],10); +cnt=parseInt(m[2],10); +ttcnt=parseInt(m[3],10); +acnt=parseInt(m[4],10); +mcnt=parseInt(m[5],10); +game.gen=parseInt(m[6],10); +game.world=m[7]; + +game.world=game.world.replace(/_/g, ' '); + +/* load nations table */ + +if(game.ncnt == 0) { + game.ncnt = 1; + game.nations[0] = { + name:'God', + uid:0, + city:0, + mark:0, + idle_turns:0 + }; +} else { + if(fp.readln()==null) { + fp.close(); + alert("Unable to read nation header"); + exit(1); + } + + for(i=0; i<game.ncnt; i++) { + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read nation "+(game.nations.length+1)+" from "+fp.name); + exit(1); + } + if((m=inbuf.match(/^(.*?): U([0-9]+) C([0-9]+) M(.) I([0-9]+)\s*$/))==null) { + alert("Unable to parse nation "+(game.nations.length+1)+" from "+fp.name); + exit(1); + } + game.nations[i]={ + name:m[1], + uid:parseInt(m[2], 10), + city:parseInt(m[3], 10), + mark:"*ABCDEFGHIJKLMNOPQRSTUVWXYZ?".substr(parseInt(m[4], 10), 1), + idle_turns:parseInt(m[5], 10) + }; + } +} +for(i=game.ncnt; i<27; i++) { + game.nations[i] = { + name:'', + uid:0, + city:0, + mark:'*', + idle_turns:0 + }; +} + +/* set up the Rogue nation */ + +game.nations[27] = { + name:'Rogue', + uid:-1, + city:0, + mark:'?', + idle_turns:0 +}; + +/* load cities table */ + +for(i = 0; i < cnt; i++) { + if(fp.readln()==null) { + fp.close(); + alert("Unable to read city header"); + exit(1); + } + + /* city id line */ + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read city "+(game.cities.length+1)+" from "+fp.name); + exit(1); + } + + if((m=inbuf.match(/^(.*?): C([0-9]+) N([0-9]+) @([0-9]+):([0-9]+) P([0-9]+):([0-9]+) D([0-9]+) T([0-9]+)\s*$/))==null) { + fp.close(); + alert("Unable to parse city "+(game.cities.length+1)+" from "+fp.name); + exit(1); + } + + game.cities[i] = { + name:m[1], + cluster:parseInt(m[2], 10), + nation:parseInt(m[3], 10), + r:parseInt(m[4], 10), + c:parseInt(m[5], 10), + prod_type:parseInt(m[6], 10), + turns_left:parseInt(m[7], 10), + defense:parseInt(m[8], 10), + ntypes:parseInt(m[9], 10), + types:[], + times:[], + instance:[] + }; + + /* troop types */ + + nt = 0; + + for(j = 0; j < 4; j++) { + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read city "+(game.cities.length+1)+" troop "+(j)+" from "+fp.name); + exit(1); + } + if((m=inbuf.match(/^([-0-9]+) ([-0-9]+) ([-0-9]+)\s*$/))==null) { + fp.close(); + alert("Unable to parse city "+(game.cities.length+1)+" troop "+(j)+" from "+fp.name); + exit(1); + } + game.cities[i].types[j]=parseInt(m[1], 10); + game.cities[i].times[j]=parseInt(m[2], 10); + game.cities[i].instance[j]=parseInt(m[3], 10); + + if(game.cities[i].types[j] != -1) + nt = j + 1; + } + + if(game.cities[i].ntypes == -1) + game.cities[i].ntypes = nt; +} + +/* load troop types table */ + +if(fp.readln()==null) { + fp.close(); + alert("Unable to read troop type header"); + exit(1); +} + +for(i = 0; i < ttcnt; i++) { + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read troop type "+(game.ttypes.length+1)+" from "+fp.name); + exit(1); + } + if((m=inbuf.match(/^(.*?): C([0-9]+) M([0-9]+):([0-9]+):([0-9]+)\s*$/))==null) { + fp.close(); + alert("Unable to parse troop type "+(game.ttypes.length+1)+" from "+fp.name); + exit(1); + } + game.ttypes[i]={ + name:m[1], + combat:parseInt(m[2], 10), + move_rate:parseInt(m[3], 10), + move_tbl:parseInt(m[4], 10), + special_mv:parseInt(m[5], 10), + }; +} + +/* load armies table */ + +if(acnt > 0) { + if(fp.readln()==null) { + fp.close(); + alert("Unable to read armies header"); + exit(1); + } + + for(i = 0; i < acnt; i++) { + + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read army type "+(game.armies.length+1)+" from "+fp.name); + exit(1); + } + if((m=inbuf.match(/^(.*?): N([0-9]+) @([0-9]+):([0-9]+) C([0-9]+):([0-9]+) M([0-9]+):([0-9]+) S([0-9]+) L([0-9]+)\s*$/))==null) { + fp.close(); + alert("Unable to parse army type "+(game.armies.length+1)+" from "+fp.name); + exit(1); + } + game.armies[i] = { + name:m[1], + nation:parseInt(m[2], 10), + r:parseInt(m[3], 10), + c:parseInt(m[4], 10), + combat:parseInt(m[5], 10), + hero:parseInt(m[6], 10), + move_rate:parseInt(m[7], 10), + move_tbl:parseInt(m[8], 10), + special_mv:parseInt(m[9], 10), + eparm1:parseInt(m[10], 10), + move_left:parseInt(m[7], 10), + }; + } +} + +/* load move table */ + +if(fp.readln()==null) { + fp.close(); + alert("Unable to read move table header"); + exit(1); +} + + +for(i = 0; i < mcnt; i++) { + + if((inbuf = fp.readln())==null) { + fp.close(); + alert("Unable to read move table "+(game.move_table.length+1)+" from "+fp.name); + exit(1); + } + if((m=inbuf.match(/^([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)\s*$/))==null) { + fp.close(); + alert("Unable to parse move table "+(game.move_table.length+1)+" from "+fp.name); + exit(1); + } + + game.move_table[i] = {}; + game.move_table[i].cost=[]; + for(j = 0; j < 5; j++) + game.move_table[i].cost[j] = parseInt(m[j+1], 10); +} + +fp.close(); +fp=new File(js.exec_dir+'/'+'game.orig.json'); +if(fp.open('wb')) { + fp.write(JSON.stringify(game, null, '\t')); +} +fp.close(); diff --git a/xtrn/war/docs/Manual b/xtrn/war/docs/Manual new file mode 100644 index 0000000000000000000000000000000000000000..9e7601f40cf803d77fadd8bb7d66b1b320efc34e --- /dev/null +++ b/xtrn/war/docs/Manual @@ -0,0 +1,108 @@ + + S O L O M O R I A H ' S + + X X XX XXXXX XXX + X X X X X X XXX + X X X X X X XXX + X X XXXXXX XXXXX X + X XX X X X X X + XX XX X X X X XXX + X X X X X X XXX + + +WAR Version 4.4 "Code by Solomoriah" +Copyright 1993, 1994, 2001, 2013 Chris Gonnerman +All Rights Reserved. + + +INTRODUCTION + +Two separate doc files are included with WAR! The one you +are reading, Manual, explains how to set up and run the +game. The other file, Rules, explains the user +interface and basic game rules. + + +GAME SETUP + +Since you are reading this file, you have obviously unZIPped +the game archive WARPROG.ZIP. Put all the program files in +a directory by themselves. + +Several basic game worlds are included with WAR! A game +world is stored in two files: map and game.sav. map is +never changed by the game programs (except WARTOOL), while +game.sav will be. game.sav will be backed up in the form of +files named game.000, game.001, etc. WAR! will clean up +(remove) old game save backups when they are five +generations out of date. + +A third file, master.cmd, is supplied. Generally you should +not tamper with the contents of any files you find in the +WAR! directory. + +To install a game world, the easiest thing to do is to unZIP +the world file (WARSOLO.ZIP, WARALDER.ZIP, or WARROOK.ZIP) +in the directory you put the game programs in. Other +arrangements will be explained later under the CONTROL FILES +heading. + + +PLAYING WAR! STANDALONE + +To play WAR! change to the WAR directory and enter the +command WAR. For example, if you installed WAR! in the +directory C:\WAR, you would start WAR! as follows: + + C:\> cd \war + C:\WAR> war + +When WAR! starts, it will ask you for your UID. Any number +from 1 to 32,768 is legal. The first time you play a turn +in WAR! you will be assigned a home city and asked for the +name of your national leader. You may use any name you +like, up to 14 characters in length. WAR! will then go to +the main screen. See the Rules file for information on +actually playing the game. + + +RUNNING UPDATES + +Running updates is done the same way. Change to the +directory WAR! is installed in and enter the command WARUPD. +WARUPD sends progress messages to stdout, so you can collect +them as follows: + + C:\WAR> warupd >message.txt + +On a BBS system you may want or need to automate the update +processing. Note that WARUPD will run even if someone is +actively playing WAR! (I'm still thinking about how to fix +that), so you should try to run the updates when no one will +be playing the game. + +It is recommended for normal BBS game play that updates be +run every 24 hours. + + +WARNEWS + +WARNEWS is a stand-alone news viewer for WAR! It presents +the same user interface that the regular WAR program does in +newsreader mode. + + +WARMAP + +WARMAP combines the MAP and GAME.SAV files to create an +up-to-date map of the WAR! world. As with WARUPD, the map +is printed to stdout and may be collected in a file as +follows: + + C:\WAR> warmap >file.txt + +To print most maps you will need to put your printer in +condensed print. To view the map on the screen you will +need a file viewer or editor that can scroll sideways. The +MS-DOS 5 EDIT command can do this. + diff --git a/xtrn/war/docs/Rules b/xtrn/war/docs/Rules new file mode 100644 index 0000000000000000000000000000000000000000..f7e01e3c0420c103af1cce49cbba99c6e5a9bdff --- /dev/null +++ b/xtrn/war/docs/Rules @@ -0,0 +1,246 @@ + + S O L O M O R I A H ' S + + X X XX XXXXX XXX + X X X X X X XXX + X X X X X X XXX + X X XXXXXX XXXXX X + X XX X X X X X + XX XX X X X X XXX + X X X X X X XXX + + WAR Version 4.4 "Code by Solomoriah" + Copyright 1993, 1994, 2001, 2013 Chris Gonnerman + All Rights Reserved. + + +Starting the Game: + +If you have never played WAR! before, you will be asked for your name +and your nation mark. You may use any name you wish, up to 14 +characters long. This name will be used for your national leader (your +first hero) and will be shown on status displays. You do not have to +use your real name. + +Enter a single exclamation mark (!) in place of the name to try for a +different city. + +The nation mark is the letter you wish to be used to represent your +nation's cities and armies in the game. (Cities are uppercase, armies +are lowercase.) + +Next, you will be instructed to press a key to continue. When you do, +the following screen will appear: + + + -------------------------------- + | . .| -> Victor (Hero) 8:8 + | . .| Verdant 1st Lt. Infantry 6:6 + | # # | + | . . . . | + | . . . . | + | . . . . % % | + | . . . % % * % V % % | + | . . ^ * % % % % ^| + | . ^ ^ ^ ^ ^ ^| + | . ^ ^ ^ ^ * . . % % ^ ^| + | % % % % % % # # . . . % % % ^| + | % % % % % % # * # . . . . % % %| + | % % % % % % # # # . . . . . % %| + | # # % % . . . . . % %| + | # # # ^ ^ . . . % %| + | # # # # ^ # # % % %| + -------------------------------- + City: Verdant (Verdant) + + Welcome to Solomoriah's WAR! Press ? for Help. + +(Of course, your screen may show a different city, and you probably +will name your hero something other than Victor...) + +If you enter the game before the first turn update, you will have your +hero, your city, and one army. For each turn after the first that +passes before you enter the game, you will have an additional army, up +to the limit of militia production (usually four or six). This ensures +you will not be helpless if you enter the game late. + +The map uses the following symbols: + + . Plains * Neutral City + % Forest ! Battle Zone + # Hills + ^ Mountains + +(Blank space represents water.) + + +Playing WAR! + +Your first act upon entering the game will probably be to attack a +neutral city nearby. To do so you will need to move your army(s) into +the city. + +Note the pointer (->) beside the hero, Victor, on the screen view +above. You use the <j> and <k> keys to move the pointer down or up. +If you press the <space bar> a * will appear next to the army the +pointer is pointing at. (Pressing <space bar> again will remove the +*.) You may also press <*> to select all, or </> to unselect all. + +Once you have selected your armies, press <m> to move them. A message +will appear at the bottom of the screen, as follows: + + Move Army 7 8 9 y k u SPACE to Stop. + 4 6 or h l + 1 2 3 n j m + +The keys shown move your army stack in the corresponding direction. +Note that if any army you have marked can't make a move, the entire +stack can't. + +Next to each army name in the screen view, you will see a pair of +numbers separated by a colon. The first number is the army's maximum +movement allowance, and the second is the amount remaining. Note that +different armies may have different costs for moving through a given +space. Some terrain types may be totally impassable to a given army +type; for instance, cavalry can't move through mountains, and most +armies can't cross water. + +When you reach the neutral city, note that it will cost 2 movement +points to enter. (Entering a hostile city always costs 2 points; +friendly cities always cost 1 point.) Once you have entered you will +see an exclamation point (!) indicating a battle zone. You may not +move armies out of a battle zone... so you should then just press +<space bar> to finish moving. + +You may stop an army or an army stack anywhere, not just in a city; +your remaining movement will still be available in that case. + +When the turn update runs, all battles will be resolved. Note that if +you attack a player-owned city, and he has moved additional armies +into the city, the results may not be as you expect. + +The reason is, player commands are executed in random order. The +nation list is scrambled, then each nation's commands are executed, +followed by battles. + +For instance, say you and your neighbor, both players, go to war. You +attack, moving a large army stack into a poorly-defended city. He +expects this, and moves a large army stack into the same city to +defend it. + +If his commands execute first, there will be one large battle, as +your army stack confronts his. If your commands execute first, you may +capture his city, only to be crushed when his defensive force arrives. + +Players may have as many as twelve armies in a friendly city. +However, no more than ten armies belonging to a given nation may be in +any other space, including an enemy city. Note also that cities give +a bonus to the combat ratings of friendly units (the defense value). + +Heros also give a bonus to friendly units they are grouped with. Only +the most powerful hero in a stack grants the stack his bonus. (Only +one commander per group.) + + +Changing the View: + +The map shows your current group near the center; the cursor will be +on the exact spot. To move the "focus" to another group, use the +(n)ext and (p)revious commands. + +Pressing <n> for next moves the focus to the next group, in map order, +which you own. A group consists of a city and/or one or more armies. +All armies in the group will be displayed in the right-hand column. +Enemy army counts will be below your armies. If the focus is on a +city, the city name and owning nation will be below the map display. + +Similarly, <p> for previous moves to the previous group in map order. +If there are no previous groups (or no more groups for next), a +message will appear. + +You may also press <N> or <P> (capitalized) to move to the very last +(for N) or very first (for P) group. + + +Viewing the Map: + +You may gain "recon" information about the map around any focus position +by entering (i)nformation mode. While in "info mode" you may move the +cursor around the screen, to any spot visible. Notice that the focus +remains in the same place. + +Information about the terrain and armies present in each spot you move the +cursor over is shown just above the info mode help display, at the bottom +of the screen. + + +Status Display: + +The (s)tatus display shows the names of all nations, their rulers and nation +marks, and a count of their currently owned cities, armies, and heros. +While in status display, you may use (n)ext and (p)revious to view other +pages, or press ESC to return to the normal display. + + +Drafting Armies: + +Each city can produce as many as four different types of units. +Initially, each city is set up to produce the lowest-ranked unit type +it can produce. You can change this for friendly cities by pressing +<a> for the armies command. The available unit types will be shown, +along with the time to produce in parenthesis. The current type in +production is also shown, along with the remaining time to produce the +unit. + +If you change unit production, you lose any time spent producing a +different type. For instance, if one of your cities is producing Lt. +Cavalry and needs four turns to produce a unit, and you have only two +turns left to produce, then changing unit types causes you to lose the +two turns you have spent already. + +Not all cities take the same time to produce the same unit type. Some +cities are better at producing certain types. Also, not all cities +produce the same types of armies. + + +Transporting Armies: + +Certain special army types have the ability to transport other armies. +For instance, a Navy unit can transport an entire stack of armies over +water spaces. There are units able to transport entire stacks, single +armies, or single heros. + +To use a transporting unit, simply select it along with the units you +wish to have transported. When you begin moving the stack, the movement +costs will be applied to the transporting army. Armies being carried +pay a cost of 1 point per space moved through regardless of terrain +type, and do not have to stop when they reach 0 movement (as long as +the transporting army can still move). + + +Special Hero Rules: + +As previously noted, a hero adds a bonus to all units stacked under him +(or her). This bonus, called the Command value, varies from hero to hero. + +Heros may make use of hero-transporting armies (such as Hippogryffs) as +noted above. + +When a hero joins your nation, he or she has the movement capability (or +costs) of the lowest-ranked unit produced in the hero's home city. For +most heros, this results in the hero moving like Lt. Infantry. Elf +heros, however, have regular Elf movement (making it easier to move +through forests). + + +Reading the News and Mail: + +You can read the News by pressing (R). The News consists of information +about recent battles (in capsule form), captured cities, etc. of all +nations. + +You can read your Mail by pressing (M). The results of your military +actions will be mailed to you in detail; also, you may receive mail from +other national leaders this way. To send Mail, press (S). You may enter +the name of the leader, or the word All to post a message in the News. + diff --git a/xtrn/war/war.js b/xtrn/war/war.js new file mode 100644 index 0000000000000000000000000000000000000000..184d607afcca99c0f4820f03567227547973a963 --- /dev/null +++ b/xtrn/war/war.js @@ -0,0 +1,2614 @@ +var game_dir = js.exec_dir; +/* + Solomoriah's WAR! + + war.js -- main procedure file for war user interface + + Copyright 2013 Stephen Hurd + All rights reserved. + + 3 Clause BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, self list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, self list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the author nor the names of any contributors + may be used to endorse or promote products derived from self software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +// Based on: +/* + Solomoriah's WAR! + + war.c -- main procedure file for war user interface + + Copyright 1993, 1994, 2001, 2013 Chris Gonnerman + All rights reserved. + + 3 Clause BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, self list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, self list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the author nor the names of any contributors + may be used to endorse or promote products derived from self software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +load("sbbsdefs.js"); +load(game_dir+'/warcommon.js'); + +// From display.c +const gran = 2; +const terminate = "\033q "; +var avcnt = 0; +var avpnt = 0; +var enemies = [ + {nation:0, armies:0, heros:0}, + {nation:0, armies:0, heros:0} +]; +var armyview = [ + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '}, + {id:0, mark:' '} +]; +var mvcnt = 0; +var movestack = [ + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 } +]; + +// These were extern... +var trans; +var pfile; + +// From data.c +const terrain = "~.%#^"; /* standard types only. */ +const terr_attr = { + ' ':'HB4', + '~':'HB4', + '.':'HY3', + '%':'HG2', + '#':'NW3', + '^':'HW7' +}; + +const terr_names = [ + "Water", + "Plains", + "Forest", + "Hills", + "Mountains", +]; + +// From reader.c +var r_index = []; +var killed=[]; +var index_cnt = 0; +var pages = []; +var page_cnt = 0; + +function nationname(n) +{ + return nations[n].name; +} + +function turn() +{ + return gen; +} + +function mainscreen() +{ + var i; + + console.clear(7); + + console.gotoxy(2, 1); + console.print(ascii(201)); + console.gotoxy(2, 18); + console.print(ascii(200)); + console.gotoxy(35, 1); + console.print(ascii(205)+ascii(187)); + console.gotoxy(35, 18); + console.print(ascii(205)+ascii(188)); + + for(i = 0; i < 16; i++) { + console.gotoxy(2, i+2); + console.print(ascii(186)); + console.gotoxy(35, i+2); + console.print(' '+ascii(186)); + console.gotoxy(i*2+3, 1); + console.print(ascii(205)+ascii(205)); + console.gotoxy(i*2+3, 18); + console.print(ascii(205)+ascii(205)); + } + + console.gotoxy(1, 20); + console.print((new Array(81)).join(ascii(196))); + + console.gotoxy(41, 1); + console.attributes = 'K7'; + console.print(format(" %-20s Turn %d ", world, gen)); + console.attributes = 'N'; +} + +function saystat(msg) +{ + console.gotoxy(2, 21); + console.print(msg); + console.cleartoeol(); +} + +function mailer(from, to) +{ + var heading; + var logf; + var fp; + var f; + var fname; + var inbuf; + + if(to > 0) { + heading = format("From %s of %s to %s of %s (Turn %d)", + nationname(from), nationcity(from), + nationname(to), nationcity(to), turn()); + } else { + heading = format("From %s of %s (Turn %d)", + nationname(from), nationcity(from), turn()); + } + + console.clear(7); + console.gotoxy(1,1); + + f = new File(format("%s/%04d.tmpmsg", game_dir, nations[from].uid)); + if(!f.open("wb")) { + console.clear(7); + mainscreen(); + saystat("Message Creation Failed (System Error)"); + return; + } + f.close(); + if(console.editfile(f.name)) { + if(file_size(f.name) > 0) { + if(to > 0) + fname = game_dir+'/'+format(MAILFL, to); + else + fname = game_dir + '/' + NEWSFL; + + if(!f.open('rb')) { + file_remove(f.name); + console.clear(7); + mainscreen(); + saystat("Mail Could Not Be Read... Cancelled."); + return; + } + + fp = new File(fname); + + if(!fp.open('ab')) { + file_remove(f.name); + console.clear(7); + mainscreen(); + saystat("Mail Could Not Be Sent... Cancelled."); + return; + } + + fp.write(HEADERMARK); + fp.write(heading); + fp.write("\n\n"); + + while((inbuf = f.readln()) != null) + fp.writeln(inbuf); + + f.close(); + fp.close(); + + logf = new File(game_dir+'/'+MAILLOG); + if(logf.open('ab')) { + logf.write(HEADERMARK); + logf.write(heading); + logf.write("\n\n"); + } + } + } + file_remove(f.name); + console.clear(7); + mainscreen(); + saystat("Mail Sent."); + +} + +/* + showpage() shows a page of text from the current file, starting at + the file position in pages[pg], for 19 lines. +*/ + +function showpage(fp, pg) +{ + var i, len; + var inbuf; + + fp.position = pages[pg]; + + len = HEADERMARK.length; + + for(i = 0; i < 19; i++) { + if((inbuf = fp.readln(1024)) == null) + break; + inbuf = inbuf.substr(0, 77); + + if(inbuf.substr(0, 2) == HEADERMARK) + break; + + console.gotoxy(3, i+1); + console.print(inbuf); + console.cleartoeol(); + } + + for(; i < 19; i++) { + console.gotoxy(3, i+1); + console.cleartoeol(); + } + + console.gotoxy(56, 22); + console.print(format("Page %d of %d", pg + 1, page_cnt)); + console.cleartoeol(); + + console.gotoxy(71, 22); + console.print("< >"); +} + +function show_killed(pos) +{ + console.gotoxy(41, 22); + + if(killed[pos]) + console.print("[Deleted]"); + else + console.print(" "); +} + +function viewerscr(mode) +{ + console.clear(7); + + console.gotoxy(3, 21); + + if(mode) + console.print("Mail: (d)elete "); + else + console.print("News: "); + + console.print("(j)down (k)up"); + + console.gotoxy(3, 22); + console.print("Press SPACE to Exit."); + + console.gotoxy(71, 22); + console.print("< >"); +} + +/* + delete_msgs() deletes messages from the named file, using the + information in the r_index[] and killed[] arrays. +*/ + +function delete_msgs(fn) +{ + var i, done, len; + var tmp, inbuf; + var inf, outf; + + len = HEADERMARK.length; + + tmp = 'tmp'+fn; + + inf = new File(game_dir+'/'+fn); + outf = new File(game_dir+'/'+tmp); + if(!inf.open("rb")) { + log("Message Deletion Failed (System Error)"); + saystat("Message Deletion Failed (System Error)"); + return; + } + if(!outf.open("wb")) { + inf.close(); + log("Message Deletion Failed (System Error)"); + saystat("Message Deletion Failed (System Error)"); + return; + } + + for(i = 0; i < index_cnt; i++) { + if(!killed[i]) { + outf.write(HEADERMARK); + inf.position = r_index[i]; + done = 0; + while((inbuf = inf.readln(1024)) != null && !done) { + inbuf = inbuf.substr(0, 77); + if(inbuf.substr(0, len) == HEADERMARK) + done = 1; + else + outf.write(inbuf+'\n'); + } + } + } + + inf.close(); + outf.close(); + + file_remove(inf.name); + file_rename(outf.name, inf.name); +} + +function readerscr(mode) +{ + console.clear(7); + + console.gotoxy(3, 21); + + if(mode) + console.print("Mail: (v)iew current (d)elete "); + else + console.print("News: (v)iew current "); + + console.print("(j)down (k)up (n)ext (p)revious"); + + console.gotoxy(3, 22); + console.print("Press SPACE to Exit."); +} + +/* + viewer() displays text from the given file, from the given + index offset to the end of file or until a line beginning with + a HEADERMARK is encountered. +*/ + +function viewer(fp, pos, mode) +{ + var ch, i, len, done, pg, opg; + var dummy; + + len = HEADERMARK.length; + + fp.position = r_index[pos]; + + viewerscr(mode); + show_killed(pos); + + done = 0; + + page_cnt = 0; + + do { + pages[page_cnt++] = fp.position; + + for(i = 0; i < 15; i++) { + if((dummy = fp.readln(1024)) == null) { + done = 1; + break; + } + dummy = dummy.substr(0, 77); + if(dummy.substr(0, len) == HEADERMARK) { + done = 1; + break; + } + } + + } while(!done); + + pg = 0; + + showpage(fp, pg); + + do { + console.gotoxy(72, 22); + ch = console.getkey(); + + opg = pg; + + switch(ch) { + + case 'j' : + case 'n' : + case KEY_DOWN: + pg++; + break; + + case 'k' : + case 'p' : + case KEY_UP: + pg--; + break; + + case 'd' : + killed[pos] = killed[pos] ? 0 : 1; + show_killed(pos); + break; + + case ' ' : + case 'q' : + ch = '\033'; + break; + + } + + if(pg < 0) pg = 0; + if(pg >= page_cnt) pg = page_cnt - 1; + + if(pg != opg) + showpage(fp, pg); + + } while(ch != '\033'); + + readerscr(mode); +} + +/* + show_screen() shows headers from the given file, centering at the + header number given. +*/ + +function show_screen(pos, fp) +{ + var i; + var inbuf; + + pos -= 8; + + for(i = 0; i < 18; i++) { + console.gotoxy(3, i+1); + + if(pos + i < index_cnt && pos + i >= 0) { + if(killed[pos+i]) + console.print('*'); + else + console.print(' '); + fp.position = r_index[pos+i]; + inbuf = fp.readln(1024); + if(inbuf != null) { + inbuf = inbuf.substr(0, 77); + console.print(inbuf); + } + } else if(pos + i == -1) + console.print("*** Top of List ***"); + else if(pos + i == index_cnt) + console.print("*** End of List ***"); + + console.cleartoeol(); + } +} + +/* + indexer() reads the given file, scanning for headings. headings + are flagged with a space-backspace combination (" \b") which is + not shown on most printouts but is easily recognized. + + the array r_index[] contains the seek positions of each heading. + it is limited by index_cnt. +*/ + +function indexer(fp) +{ + var inbuf, len, pos; + + index_cnt = 0; + + len = HEADERMARK.length; + + fp.rewind(); + + for(pos = fp.position; (inbuf = fp.readln(1024)) != null; pos = fp.position) { + inbuf=inbuf.substr(0, 77); + if(inbuf.substr(0, len)==HEADERMARK) { + killed[index_cnt] = 0; + r_index[index_cnt++] = pos + len; + } + } +} + +/* + reader() displays a list of headings from the given file. the + user may page or "arrow" up or down to view long listings. when + a heading is selected with the (v)iew command, viewer() is called. + + mode is 0 for news, 1 for mail. mode 1 enables deletion of headings. +*/ + +function reader(fname, mode) +{ + var top, pos, ch, killcnt; + var fp = new File(game_dir+'/'+fname); + + if(!fp.open("rb")) { + if(mode) + saystat("No Mail in your box."); + else + saystat("No News to Read."); + return; + } + + readerscr(mode); + + indexer(fp); + + top = pos = index_cnt - 1; + + show_screen(top, fp); + + do { + console.gotoxy(2, pos - top + 9); + console.print('>'); + + ch = console.getkey(); + + console.gotoxy(2, pos - top + 9); + console.print(' '); + + switch(ch) { + + case 'j' : + case KEY_DOWN: + pos++; + break; + + case 'k' : + case KEY_UP: + pos--; + break; + + case 'n' : + //case KEY_PAGEDOWN: + pos += 11; + break; + + case 'p' : + //case KEY_PAGEUP: + pos -= 10; + break; + + case 'd' : + if(!mode) + break; + + killed[pos]++; + killed[pos] %= 2; + + show_screen(top, fp); + + break; + + case 'v' : + viewer(fp, pos, mode); + show_screen(top, fp); + break; + + case ' ' : + case 'q' : + ch = '\033'; + break; + + } + + if(pos < 0) pos = 0; + if(pos >= index_cnt) pos = index_cnt - 1; + + if(pos > top + 8 || pos < top - 7) { + top = pos; + show_screen(top, fp); + } + + } while(ch != '\033'); + + fp.close(); + + console.clear(7); + mainscreen(); + + /* handle deletion. */ + + if(mode) { + for(killcnt = 0, pos = 0; pos < index_cnt; pos++) + killcnt += killed[pos]; + + if(killcnt != 0) { /* deleted some... */ + + if(killcnt == index_cnt) /* deleted ALL */ + file_remove(game_dir+'/'+fname); + else + delete_msgs(fname); + } + } +} + +function analyze_stack(ms, mc) +{ + var i, j, a, b, mmode; + + mmode = 0; + + for(i = 0; i < mc; i++) + if(armies[ms[i].id].special_mv > mmode) + mmode = armies[ms[i].id].special_mv; + + switch(mmode) { + + case TRANS_ALL : + + /* locate fastest transporter */ + j = -1; + for(i = 0; i < mc; i++) { + a = ms[i].id; + if(armies[a].special_mv == TRANS_ALL) { + if(j == -1 || armies[a].move_left > armies[j].move_left) + j = a; + ms[i].dep = a; + } + } + + /* set (almost) all */ + for(i = 0; i < mc; i++) { + a = ms[i].id; + if(armies[a].special_mv == TRANS_ALL) + ms[i].dep = a; + else if(ms[i].dep == -1) + ms[i].dep = j; + } + + break; + + case TRANS_SELF : + + /* easy... all move by themselves */ + for(i = 0; i < mc; i++) + ms[i].dep = ms[i].id; + + break; + + default : + /* transport hero and/or one army */ + + /* set all heros for transportation */ + for(i = 0; i < mc; i++) { + a = ms[i].id; + if(armies[a].hero > 0) + for(j = 0; j < mc; j++) { + b = ms[j].id; + if(armies[b].special_mv == TRANS_HERO + && ms[j].dep == -1) { + ms[j].dep = b; + ms[i].dep = b; + break; + } + } + } + + /* set remaining for transportation */ + for(i = 0; i < mc; i++) { + a = ms[i].id; + if(ms[i].dep == -1 + && armies[a].special_mv == TRANS_SELF) { + for(j = 0; j < mc; j++) { + b = ms[j].id; + if(armies[b].special_mv == TRANS_ONE + && ms[j].dep == -1) { + ms[j].dep = b; + ms[i].dep = b; + break; + } + } + } + } + + /* leftovers transport self. */ + for(i = 0; i < mc; i++) + if(ms[i].dep == -1) + ms[i].dep = ms[i].id; + + break; + } +} + +function movecost(a, r, c) +{ + var t, tbl, mv, city, cost, a2; + + city = city_at(r, c); + + if(city == -1) { + /* not a city */ + + /* search for a TRANS_ALL unit there */ + if(!(armies[a].r == r && armies[a].c == c) + && armies[a].special_mv != TRANS_ALL) + for(a2 = 0; a2 < armycnt; a2++) + if(a != a2 + && armies[a2].r == r + && armies[a2].c == c + && armies[a2].nation == armies[a].nation + && armies[a2].special_mv == TRANS_ALL) + return 1; + + /* else do this: */ + t = terrain.indexOf(map[r][c]); + if(t != -1) { + tbl = armies[a].move_tbl; + mv = move_table[tbl].cost[t]; + + if(mv == 0 + /* otherwise can't move, and */ + && map[r][c] != '~' + /* target space is not water, and */ + && map[armies[a].r][armies[a].c] == '~' + /* current space is water, and */ + && (cost = move_table[tbl].cost[0]) > 0) + /* this unit moves on water, then */ + mv = cost * 2; /* beaching is allowed */ + } else { + if(map[r][c] == '+') + mv = 1; + else + mv = 3; + } + } else { + + /* city */ + + if(armies[a].nation == cities[city].nation) + mv = 1; + else + mv = 2; + } + + return mv; +} + +function clearstat(mode) +{ + if(mode == -1) { + console.gotoxy(2, 21); console.cleartoeol(); + console.gotoxy(2, 22); console.cleartoeol(); + console.gotoxy(2, 23); console.cleartoeol(); + console.gotoxy(2, 24); console.cleartoeol(); + } else { + console.gotoxy(2, 21+mode); console.cleartoeol(); + } +} + +function mark_of(a) +{ + var i; + + if(mvcnt < 1) + return 0; + + for(i = 0; i < mvcnt; i++) + if(movestack[i].id == a) + return 1; + + return 0; +} + +function sortview() +{ + var gap, i, j, temp; + + avpnt = 0; + + for(gap = parseInt(avcnt / 2); gap > 0; gap = parseInt(gap / 2)) { + for(i = gap; i < avcnt; i++) { + for(j = i - gap; j >= 0 && isgreater(armyview[j+gap].id, armyview[j].id); j -= gap) { + temp = armyview[j].id; + armyview[j].id = armyview[j+gap].id; + armyview[j+gap].id = temp; + temp = armyview[j].mark; + armyview[j].mark = armyview[j+gap].mark; + armyview[j+gap].mark = temp; + } + } + } +} + +function setfocus(ntn, r, c) +{ + var i, j, e; + + avcnt = 0; + + /* clear the enemies list */ + + for(e = 0; e < 2; e++) { + enemies[e].nation = -1; + enemies[e].armies = 0; + enemies[e].heros = 0; + } + + /* clear the map overlay */ + + for(i = 0; i < map_height; i++) + for(j = 0; j < map_height; j++) + mapovl[i][j] = ' '; + + /* find the player's armies */ + + for(i = 0; i < armycnt; i++) { + if(r == armies[i].r + && c == armies[i].c) + if(armies[i].nation == ntn || ntn == -1) { + armyview[avcnt].id = i; + armyview[avcnt++].mark = mark_of(i); + } else { + + e = 0; + + if(enemies[0].nation != armies[i].nation + && enemies[0].nation != -1) + e = 1; + + enemies[e].nation = armies[i].nation; + + if(armies[i].hero > 0) + enemies[e].heros++; + else + enemies[e].armies++; + } + + if(armies[i].nation >= 0) { + if(mapovl[armies[i].r][armies[i].c] == ' ' + || mapovl[armies[i].r][armies[i].c] == + marks[1].substr(marks[0].indexOf([nations[armies[i].nation].mark]), 1)) { + mapovl[armies[i].r][armies[i].c] = + marks[1].substr(marks[0].indexOf([nations[armies[i].nation].mark]), 1); + } + else { + mapovl[armies[i].r][armies[i].c] = '!'; + } + } + } + + sortview(); + + /* update map overlay with cities */ + + for(i = 0; i < citycnt; i++) { + if(mapovl[cities[i].r][cities[i].c] == ' ' + || marks[1].indexOf(mapovl[cities[i].r][cities[i].c]) != -1) { + mapovl[cities[i].r][cities[i].c] = + nations[cities[i].nation].mark; + } + else { + mapovl[cities[i].r][cities[i].c] = '!'; + } + } +} + +function showarmies() +{ + var i, a; + var buff; + + for(i = 0; i < 12; i++) { + + console.gotoxy(38, i + 3); + + if(i < avcnt) { + a = armyview[i].id; + console.print(format("%s %c ", + i == avpnt ? "=>" : " ", + armyview[i].mark ? '*' : ' ')); + buff = armyname(a); + + if(armies[a].name.length == 0 && armies[a].hero > 0) + buff = "(Nameless Hero)"; + else if(armies[a].hero > 0) + buff += " (Hero)"; + + console.print(format("%-31.31s %d:%d", buff, + armies[a].move_rate, armies[a].move_left)); + } + + console.cleartoeol(); + } + + console.gotoxy(38, 14); + if(avcnt > 0) + console.print(format(" Total %d Armies", avcnt)); + console.cleartoeol(); + + for(i = 0; i < 2; i++) { + console.gotoxy(43, i + 16); + + if(enemies[i].nation != -1) + console.print(format("%-15.15s %3d Armies, %3d Heros", + i == 1 + ? "(Other Nations)" + : nationcity(enemies[i].nation), + enemies[i].armies, enemies[i].heros)); + + console.cleartoeol(); + } +} + +function gmapspot(r, c, terr, mark, focus) +{ + if(mark == ' ') + mark = terr; + + if(terr == '~') + terr = ' '; + + if(mark == '~') + mark = ' '; + + console.gotoxy(c * 2 + 4, r + 2); + if(terr_attr[mark]==undefined) + console.attributes='N'; + else + console.attributes=terr_attr[mark]; + console.print(mark); + console.attributes = terr_attr[terr]; + console.print(terr); + + console.gotoxy(c * 2 + 4, r + 2); + + return 0; +} + +function cityowner(c) +{ + var n; + + n = cities[c].nation; + + if(n == 0) return "Neutral"; + if(n == 27) return "Rogue"; + + return cities[nations[n].city].name; +} + +function showcity(r, c) +{ + var i; + var buff = ''; + + console.gotoxy(4, 19); + + i = city_at(r, c); + + if(i != -1) { + buff = format("City: %s (%s)", + cities[i].name, cityowner(i)); + } + + console.print(format("%-40.40s", buff)); +} + +var old_ul_r = -1; +var old_ul_c = -1; +function showmap(r, c, force) +{ + var ul_r, ul_c, f_r, f_c; + var i, j, zr, zc; + var rem; + + showarmies(); + + rem = parseInt((16 - gran) / 2); + f_r = r % gran; + f_c = c % gran; + + ul_r = ((parseInt(r / gran) * gran - rem) + map_height) % map_height; + ul_c = ((parseInt(c / gran) * gran - rem) + map_width) % map_width; + + if(old_ul_r != ul_r || old_ul_c != ul_c || force) + for(i = 0; i < 16; i++) + for(j = 0; j < 16; j++) { + zr = (ul_r+i) % map_height; + zc = (ul_c+j) % map_width; + gmapspot(i, j, map[zr][zc], mapovl[zr][zc], 0); + } + + console.attributes='N'; + old_ul_r = ul_r; + old_ul_c = ul_c; + + if(mapovl[r][c] != ' ') + showcity(r, c); + + console.gotoxy(f_c * 2 + 16, f_r + 8); +} + +function showfocus(r, c, mode) +{ + var f_r, f_c, rem; + + rem = parseInt((16 - gran) / 2); + + f_r = (r % gran) + rem; + f_c = (c % gran) + rem; + + gmapspot(f_r, f_c, map[r][c], mapovl[r][c], 1); + console.attributes='N'; +} + +function fixrow(r) +{ + r += map_height; + r %= map_height; + + return r; +} + +function fixcol(c) +{ + c += map_width; + c %= map_width; + + return c; +} + +function move_mode(ntn, rp, cp) +{ + var i, j, mv, ch, city, army, t_r, t_c, a, b, ok, cnt, max, flag; + var ac, hc, mmode; + var mvc = new Array(TRANS_ALL+1); + var gap, temp; + var unmarked = [ + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 }, + { id:0, moved:0, dep:0 } + ]; + var uncnt; + + var buff; + + if(avcnt < 1) { + saystat("No Army to Move."); + return {r:rp,c:cp}; + } + + mvcnt = 0; + flag = 0; + + for(i = 0; i < avcnt; i++) { + if(armyview[i].mark) + flag = 1; + if(armyview[i].mark + && (armies[armyview[i].id].move_left > 0 || ntn == -1)) { + if(mvcnt >= 10 && ntn >= 0) { + saystat("Too Many Armies for Group."); + return {r:rp,c:cp}; + } + movestack[mvcnt].moved = 0; + movestack[mvcnt].dep = -1; + movestack[mvcnt++].id = armyview[i].id; + } + } + + if(mvcnt < 1 && !flag + && (armies[armyview[avpnt].id].move_left > 0 || ntn == -1)) { + movestack[mvcnt].moved = 0; + movestack[mvcnt].dep = -1; + movestack[mvcnt++].id = armyview[avpnt].id; + armyview[avpnt].mark = 1; + } + + if(mvcnt < 1 && ntn > -1) { + saystat("Armies Have No Movement Left."); + return {r:rp,c:cp}; + } + + /* + prevent stranding: + analyze the unmarked armies + + create a "movestack" of the unmarked. + if they can move, stranding can't occur. + */ + + if(ntn > -1) { + + uncnt = 0; + + for(i = 0; i < avcnt; i++) { + if(!armyview[i].mark) { + unmarked[uncnt].moved = 0; + unmarked[uncnt].dep = -1; + unmarked[uncnt++].id = armyview[i].id; + } + } + + analyze_stack(unmarked, uncnt); + + for(i = 0; i < uncnt; i++) { + a = unmarked[i].id; + if(unmarked[i].dep == a + && armies[a].special_mv != TRANS_ALL + && movecost(a, armies[a].r, armies[a].c) == 0) { + saystat("Armies Would Be Stranded... Movement Cancelled."); + return {r:rp,c:cp}; + } + } + } + + /* analyze move stack */ + + if(ntn > -1) + analyze_stack(movestack, mvcnt); + + /* perform movement */ + + clearstat(-1); + + console.gotoxy(2, 22); + console.print(format("Move %s", mvcnt > 1 ? "Armies" : "Army")); + + console.gotoxy(21, 23); + console.print("4 6 or h l"); + + console.gotoxy(21, 24); + console.print("1 2 3 n j m"); + + console.gotoxy(21, 22); + console.print("7 8 9 y k u SPACE to Stop. "); + + setfocus(ntn, rp, cp); + showmap(rp, cp, 0); + showfocus(rp, cp, 1); + + while(mvcnt > 0 && (ch = console.getkey()) != ' ' + && terminate.indexOf(ch) == -1) { + + showfocus(rp, cp, 0); + clearstat(0); + + t_r = rp; + t_c = cp; + + switch(ch) { /* directions */ + + case '7' : + case 'y' : + t_r--; + t_c--; + break; + + case '8' : + case 'k' : + t_r--; + break; + + case '9' : + case 'u' : + t_r--; + t_c++; + break; + + case '4' : + case 'h' : + t_c--; + break; + + case '6' : + case 'l' : + t_c++; + break; + + case '1' : + case 'n' : + t_r++; + t_c--; + break; + + case '2' : + case 'j' : + t_r++; + break; + + case '3' : + case 'm' : + t_r++; + t_c++; + break; + + case '\f' : + // TODO: Refresh + break; + } + + t_r = fixrow(t_r); + t_c = fixcol(t_c); + + if(t_r != rp || t_c != cp) { + /* actual move code... */ + + ok = 1; + + /* verify that all units can make the move. */ + + if(ntn > -1) { + + for(i = 0; i < mvcnt; i++) { + + a = movestack[i].id; + + if(movestack[i].dep == a) { + + mv = movecost(a, t_r, t_c); + + if(mv > armies[a].move_left + || mv == 0) { + ok = 0; + buff = format("%s Can't Move There.", + armyname(a)); + saystat(buff); + break; + } + } + } + } + + /* prevent overstacking. */ + + if(ok && ntn > -1) { + cnt = 0; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == ntn + && armies[i].r == t_r + && armies[i].c == t_c) + cnt++; + + city = city_at(t_r, t_c); + + max = 10; + + if(city != -1 + && cities[city].nation == ntn) + max = 12; + + if(mvcnt + cnt > max) { + ok = 0; + saystat("Too Many Armies There."); + } + } + + /* can't leave combat. */ + + if(ok && ntn > -1) + for(i = 0; i < armycnt; i++) + if(armies[i].nation != ntn + && armies[i].r == rp + && armies[i].c == cp) { + ok = 0; + saystat("Can't Leave Combat."); + break; + } + + /* do it! */ + + if(ok) { + for(i = 0; i < mvcnt; i++) { + a = movestack[i].id; + + if(ntn > -1) { + if(movestack[i].dep == a) + mv = movecost(a, t_r, t_c); + else + mv = armies[a].move_left ? 1 : 0; + } else + mv = 0; + + movestack[i].moved += mv; + armies[a].move_left -= mv; + armies[a].r = t_r; + armies[a].c = t_c; + } + rp = t_r; + cp = t_c; + } + + /* redo screen. */ + + setfocus(ntn, rp, cp); + showmap(rp, cp, ok); + } + + showfocus(rp, cp, 1); + } + + if(ntn > -1) + for(i = 0; i < mvcnt; i++) + if(movestack[i].moved > 0 || ntn == -1) + pfile.write(format("move-army %d %d %d %d %d\n", + movestack[i].id, movestack[i].moved, + rp, cp, movestack[i].dep)); + + clearstat(-1); + + mvcnt = 0; + + return {r:rp,c:cp}; +} + +function my_army_at(r, c, n) +{ + var i; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n + && armies[i].r == r + && armies[i].c == c) + return i; + + return -1; +} + +function show_info(r, c) +{ + var buff, buf2; + var i, ch, city, ntn, ac, hc; + + buff = ''; + city = city_at(r, c); + + if(city != -1) { + buff = format("City: %s (%s)", cities[city].name, + nationcity(cities[city].nation)); + } else { + ch = map[r][c]; + + i=terrain.indexOf(ch); + if(i==-1 && ch==' ') + buff = "Ocean"; + else + buff = terr_names[i]; + } + + ac = 0; + hc = 0; + + for(i = 0; i < armycnt; i++) + if(armies[i].r == r && armies[i].c == c) + if(armies[i].hero > 0) + hc++; + else + ac++; + + buf2 = format(" %d Armies, %d Heros", ac, hc); + buff += buf2; + + saystat(buff); +} + +function info_mode(rp, cp, n, ch) +{ + var done, r, c, ul_r, ul_c, f_r, f_c, t_r, t_c; + var city, army, i, flag; + var rem; + + rem = parseInt((16 - gran) / 2); + + showfocus(rp, cp, 1); + + clearstat(-1); + + console.gotoxy(21,23); + console.print("4 6 or h l"); + + console.gotoxy(21,24); + console.print("1 2 3 n j m"); + + console.gotoxy(2,22); + console.print("Info Mode: 7 8 9 y k u ESC to Stop. "); + + r = rp; + c = cp; + + ul_r = ((parseInt(r / gran) * gran - rem) + map_height) % map_height; + ul_c = ((parseInt(c / gran) * gran - rem) + map_width) % map_width; + + f_r = (r % gran) + rem; + f_c = (c % gran) + rem; + + done = 0; + + do { + flag = 1; + + switch(ch) { + + case '7' : + case 'y' : + f_r--; + f_c--; + break; + + case '8' : + case 'k' : + f_r--; + break; + + case '9' : + case 'u' : + f_r--; + f_c++; + break; + + case '6' : + case 'l' : + f_c++; + break; + + case '3' : + case 'm' : + f_r++; + f_c++; + break; + + case '2' : + case 'j' : + f_r++; + break; + + case '1' : + case 'n' : + f_r++; + f_c--; + break; + + case '4' : + case 'h' : + f_c--; + break; + + case '\f' : + // TODO: refresh + break; + + default : + done = 1; + } + + if(f_r < 0) f_r = 0; + if(f_c < 0) f_c = 0; + + if(f_r > 15) f_r = 15; + if(f_c > 15) f_c = 15; + + t_r = (ul_r + f_r + map_height) % map_height; + t_c = (ul_c + f_c + map_width) % map_width; + + city = my_city_at(t_r, t_c, n); + army = my_army_at(t_r, t_c, n); + + if(city >= 0 || army >= 0) { + showfocus(rp, cp, 0); + r = rp = t_r; + c = cp = t_c; + setfocus(n, rp, cp); + showmap(rp, cp, 0); + showfocus(rp, cp, 1); + ul_r = ((parseInt(r / gran) * gran - rem) + map_height) + % map_height; + ul_c = ((parseInt(c / gran) * gran - rem) + map_width) + % map_width; + f_r = (r % gran) + rem; + f_c = (c % gran) + rem; + done = 1; + } + + if(flag) + show_info((ul_r + f_r + map_height) % map_height, + (ul_c + f_c + map_width) % map_width); + + console.gotoxy(f_c * 2 + 4, f_r + 2); + + if(!done) + ch = console.getkey(); + + } while(!done); + + clearstat(-1); + + showfocus(rp, cp, 0); + return {r:rp,c:cp}; +} + +function groupcmp(r1, c1, r2, c2) +{ + /* quadrant check */ + + if(parseInt(r1 / 16) > parseInt(r2 / 16)) + return 1; + + if(parseInt(r1 / 16) < parseInt(r2 / 16)) + return -1; + + if(parseInt(c1 / 16) > parseInt(c2 / 16)) + return 1; + + if(parseInt(c1 / 16) < parseInt(c2 / 16)) + return -1; + + /* exact check */ + + if(r1 > r2) + return 1; + + if(r1 < r2) + return -1; + + if(c1 > c2) + return 1; + + if(c1 < c2) + return -1; + + return 0; +} + +function prevgroup(ntn, rp, cp) +{ + var i, t_r, t_c; + + t_r = -1; + t_c = -1; + + for(i = 0; i < citycnt; i++) { + if(cities[i].nation == ntn) { + if(groupcmp(cities[i].r, cities[i].c, rp, cp) < 0 + && (t_r == -1 + || groupcmp(cities[i].r, cities[i].c, t_r, t_c) > 0)) { + t_r = cities[i].r; + t_c = cities[i].c; + } + } + } + + for(i = 0; i < armycnt; i++) { + if(armies[i].nation == ntn) { + if(groupcmp(armies[i].r, armies[i].c, rp, cp) < 0 + && (t_r == -1 + || groupcmp(armies[i].r, armies[i].c, t_r, t_c) > 0)) { + t_r = armies[i].r; + t_c = armies[i].c; + } + } + } + + if(t_r != -1) + return {r:t_r,c:t_c,ret:true}; + else + return {r:rp,c:cp,ret:false}; +} + +function prevarmy(ntn, rp, cp) +{ + var i, t_r, t_c; + + t_r = -1; + t_c = -1; + + for(i = 0; i < armycnt; i++) { + if(armies[i].nation == ntn && armies[i].move_left > 0) { + if(groupcmp(armies[i].r, armies[i].c, rp, cp) < 0 + && (t_r == -1 + || groupcmp(armies[i].r, armies[i].c, t_r, t_c) > 0)) { + t_r = armies[i].r; + t_c = armies[i].c; + } + } + } + + if(t_r != -1) + return {r:t_r,c:t_c,ret:true}; + else + return {r:rp,c:cp,ret:false}; +} + +function nextgroup(ntn, rp, cp) +{ + var i, t_r, t_c; + + t_r = -1; + t_c = -1; + + for(i = 0; i < citycnt; i++) { + if(cities[i].nation == ntn) { + if(groupcmp(cities[i].r, cities[i].c, rp, cp) > 0 + && (t_r == -1 + || groupcmp(cities[i].r, cities[i].c, t_r, t_c) < 0)) { + t_r = cities[i].r; + t_c = cities[i].c; + } + } + } + + for(i = 0; i < armycnt; i++) { + if(armies[i].nation == ntn) { + if(groupcmp(armies[i].r, armies[i].c, rp, cp) > 0 + && (t_r == -1 + || groupcmp(armies[i].r, armies[i].c, t_r, t_c) < 0)) { + t_r = armies[i].r; + t_c = armies[i].c; + } + } + } + + if(t_r != -1) + return {r:t_r,c:t_c,ret:true}; + else + return {r:rp,c:cp,ret:false}; +} + +function nextarmy(ntn, rp, cp) +{ + var i, t_r, t_c; + + t_r = -1; + t_c = -1; + + for(i = 0; i < armycnt; i++) { + if(armies[i].nation == ntn && armies[i].move_left > 0) { + if(groupcmp(armies[i].r, armies[i].c, rp, cp) > 0 + && (t_r == -1 + || groupcmp(armies[i].r, armies[i].c, t_r, t_c) < 0)) { + t_r = armies[i].r; + t_c = armies[i].c; + } + } + } + + if(t_r != -1) + return {r:t_r,c:t_c,ret:true}; + else + return {r:rp,c:cp,ret:false}; +} + +var help_mode = 0; +function help() +{ + console.gotoxy(2, 21); + console.print(format("Commands, Page %d (Press ? for More Help)", help_mode + 1)); + console.cleartoeol(); + + switch(help_mode) { + + case 0 : + console.gotoxy(2, 22); + console.print(" (n)ext group (p)revious group (N)last (P)first"); + console.cleartoeol(); + + console.gotoxy(2, 23); + console.print(" (s)tatus display (i)nformation mode"); + console.print(" (a)rmy production"); + console.cleartoeol(); + + console.gotoxy(2, 24); + console.print(" (R)ead news read (M)ail (S)end mail (q)uit"); + console.cleartoeol(); + + break; + + case 1 : + console.gotoxy(2, 22); + console.print(" (j)pointer down (k)pointer up (SPACE)mark (*)mark all"); + console.cleartoeol(); + + console.gotoxy(2, 23); + console.print(" (m)ove marked armies (r)ename hero (q)uit"); + console.cleartoeol(); + + console.gotoxy(2, 24); + console.cleartoeol(); + + break; + } + + help_mode++; + help_mode %= 2; +} + +function status() +{ + var ch, pos, i, j, hc, ac, cc; + + /* set up screen */ + + console.clear(7); + + console.gotoxy(21, 2); + console.print("Nation Status Display"); + + console.gotoxy(2, 4); console.print("Nation:"); + console.gotoxy(2, 5); console.print("Ruler:"); + console.gotoxy(2, 6); console.print("Mark:"); + console.gotoxy(2, 8); console.print("Cities:"); + console.gotoxy(2, 9); console.print("Heros:"); + console.gotoxy(2, 10); console.print("Armies:"); + + console.gotoxy(2, 12); console.print("(n)ext page (p)revious page (SPACE) to exit"); + + /* display loop */ + + pos = 0; + + do { + /* show the nations. */ + + for(i = 4; i <= 11; i++) { + console.gotoxy(17, i); + console.cleartoeol(); + } + + for(i = 0; i < 4; i++) + if(pos + 1 + i < nationcnt) { + console.gotoxy(i * 16 + 17, 4); + console.print(nationcity(pos+1+i)); + + console.gotoxy(i * 16 + 17, 5); + console.print(nations[pos+1+i].name); + + console.gotoxy(i * 16 + 20, 6); + console.print(nations[pos+1+i].mark); + + cc = 0; + + for(j = 0; j < citycnt; j++) + if(cities[j].nation == pos + 1 + i) + cc++; + + hc = 0; + ac = 0; + + for(j = 0; j < armycnt; j++) + if(armies[j].nation == pos + 1 + i) + if(armies[j].hero > 0) + hc++; + else + ac++; + + console.gotoxy(i * 16 + 17, 8); + console.print(format("%5d", cc)); + + console.gotoxy(i * 16 + 17, 9); + console.print(format("%5d", hc)); + + console.gotoxy(i * 16 + 17, 10); + console.print(format("%5d", ac)); + } + + /* handle input. */ + + console.gotoxy(71, 12); + console.print("< >\b\b"); + + switch((ch = console.getkey())) { + + case ' ' : + case 'q' : + ch = '\033'; + break; + + case 'n' : + if(pos + 5 < nationcnt) + pos += 4; + break; + + case 'p' : + if(pos - 3 > 0) + pos -= 4; + break; + } + + } while(ch != '\033'); + + /* clean up */ + + mainscreen(); +} + +function produce(city) +{ + var i, t, ch; + var buff=''; + var okstring=''; + + console.gotoxy(2, 22); console.cleartoeol(); + console.gotoxy(2, 23); console.cleartoeol(); + + for(i = 0; i < cities[city].ntypes; i++) { + if(cities[city].types[i] != -1) { + console.gotoxy(parseInt(i / 2) * 30 + 2, (i % 2) + 22); + console.print(format("%d) %-14.14s (%d)", i + 1, + ttypes[cities[city].types[i]].name, + cities[city].times[i])); + okstring += (i+1); + } + } + + console.gotoxy(2, 24); + t = cities[city].types[cities[city].prod_type]; + console.print(format("Current: %s (%d turns left) ESC to Cancel", + ttypes[t].name, + cities[city].turns_left)); + console.cleartoeol(); + + saystat(format("Set Army Production for %s: ", cities[city].name)); + + if(okstring.indexOf(ch = console.getkeys(okstring+'\x1b', 0)) != -1) { + buff = format("set-produce %d %d\n", city, ch - 1); + pfile.write(buff); + execpriv(buff); + } + + clearstat(-1); +} + +function mainloop(ntn) +{ + var ch, r, c, i, n, city, army, force, obj; + var inbuf, buff; + + r = -1; + c = -1; + + army = -1; + + /* find the player's capitol city */ + + if(cities[nations[ntn].city].nation == ntn) { + i = nations[ntn].city; + r = cities[i].r; + c = cities[i].c; + setfocus(ntn, r, c); + } + + /* find the player's first city */ + + city = city_at(r, c); + + if(city != -1 && cities[city].nation != ntn) + city = -1; + + if(city == -1) + for(i = 0; i < citycnt; i++) + if(cities[i].nation == ntn) { + r = cities[i].r; + c = cities[i].c; + setfocus(ntn, r, c); + break; + } + + /* find the player's first army */ + + if(city == -1) + for(i = 0; i < armycnt; i++) + if(armies[i].nation == ntn) { + r = armies[i].r; + c = armies[i].c; + army = i; + setfocus(ntn, r, c); + break; + } + + if(army == -1 && city == -1) { + saystat("Nation is Destroyed. Press Any Key: "); + console.getkey(); + return; + } + + /* enter the loop */ + + saystat("Welcome to Solomoriah's WAR! Press ? for Help."); + + force = 0; + + for(;;) { + + showmap(r, c, force); + force = 0; + + showfocus(r, c, 1); + ch = console.getkey(); + showfocus(r, c, 0); + + clearstat(-1); + + switch(ch) { + + case 'a' : /* armies */ + city = city_at(r, c); + if(city != -1 && cities[city].nation == ntn) + produce(city); + else + saystat("Must View Your Own City First."); + break; + + case '\016' : /* next army */ + obj = nextarmy(ntn, r, c); + r = obj.r; + c = obj.c; + if(!obj.ret) + saystat("No Next Army with Movement Found"); + else + setfocus(ntn, r, c); + break; + + case 'n' : /* next group */ + obj = nextgroup(ntn, r, c); + r = obj.r; + c = obj.c; + if(!obj.ret) { + saystat("No More Groups Remain."); + } else + setfocus(ntn, r, c); + break; + + case 'N' : /* last group */ + while((obj = nextgroup(ntn, r, c)).ret) { + r = obj.r; + c = obj.c; + } + r = obj.r; + c = obj.c; + setfocus(ntn, r, c); + break; + + case '\020' : /* prev army */ + obj = prevarmy(ntn, r, c); + r = obj.r; + c = obj.c; + if(!obj.ret) + saystat("No Previous Army with Movement Found"); + else + setfocus(ntn, r, c); + break; + + case 'p' : /* previous group */ + obj = prevgroup(ntn, r, c); + r = obj.r; + c = obj.c; + if(!obj.ret) { + saystat("No Previous Groups Remain."); + } else + setfocus(ntn, r, c); + break; + + case 'P' : /* first group */ + while((obj = prevgroup(ntn, r, c)).ret) { + r = obj.r; + c = obj.c; + } + r = obj.r; + c = obj.c; + setfocus(ntn, r, c); + break; + + case 'r' : /* rename hero */ + if(avcnt > 0 && armies[armyview[avpnt].id].name.length == 0) { + saystat("Enter Hero's Name: "); + inbuf = console.getstr(16); + + buff = format("name-army %d '%s'\n", armyview[avpnt].id, inbuf); + pfile.write(buff); + execpriv(buff); + + setfocus(ntn, r, c); + clearstat(-1); + } else + saystat("Can Only Rename Heros."); + break; + + case 'j' : /* next army */ + case 'd' : + case KEY_DOWN: + if(avcnt > 0) { + avpnt++; + avpnt += avcnt; + avpnt %= avcnt; + } else + saystat("No Armies!"); + break; + + case 'k' : /* previous army */ + case 'u' : + case KEY_UP: + if(avcnt > 0) { + avpnt--; + avpnt += avcnt; + avpnt %= avcnt; + } else + saystat("No Armies!"); + break; + + case ' ' : /* mark */ + if(avcnt > 0) + armyview[avpnt].mark = + armyview[avpnt].mark ? 0 : 1; + break; + + case 'I' : /* army information */ + if(avcnt > 0) { + var id = armyview[avpnt].id; + buff = format("%s: Combat %d / Hero %d %s", + armyname(id), armies[id].combat, armies[id].hero, + ((armies[id].hero > 0 && armies[id].eparm1) ? "(Loyal)" : "")); + saystat(buff); + } else + saystat("No Armies!"); + break; + + case '*' : /* mark all */ + case 'g' : /* mark all and move */ + for(i = 0; i < avcnt; i++) + if(armies[armyview[i].id].move_left > 0) + armyview[i].mark = 1; + if(ch == '*') + break; + /* fall through */ + + case 'm' : /* move */ + obj = move_mode(ntn, r, c); + r = obj.r; + c = obj.c; + setfocus(ntn, r, c); + break; + + case '/' : /* unmark all */ + for(i = 0; i < avcnt; i++) + armyview[i].mark = 0; + break; + + case 'i' : /* information */ + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + obj = info_mode(r, c, ntn, ch); + r = obj.r; + c = obj.c; + setfocus(ntn, r, c); + break; + + case 'R' : /* read... */ + reader(NEWSFL, 0); + force = 1; + break; + + case 'M' : /* mail... */ + inbuf = format(MAILFL, ntn); + reader(inbuf, 1); + force = 1; + break; + + case 'S' : /* send mail */ + saystat("Send Mail -- Enter Ruler's Name, or All to Post News: "); + inbuf = console.getstr(16); + + n = -1; + for(i = 0; i < nationcnt; i++) + if(nations[i].name.toUpperCase() == inbuf.toUpperCase()) + n = i; + + if(n == -1 && "all" == inbuf.toLowerCase()) + n = 0; + + if(n == -1) { + saystat("No Such Ruler."); + break; + } + + mailer(ntn, n); + + force = 1; + clearstat(-1); + break; + + case 's' : /* status */ + status(); + force = 1; + break; + + case 'h' : /* help */ + case '?' : + help(); + break; + + case '\f' : + force = 1; + break; + + case 'q' : /* quit */ + saystat("Quit? (Y/N) "); + if(console.getkey().toLowerCase() == 'y') + return; + clearstat(-1); + break; + } + } +} + +function writemap(fp, ntn) { + var r, c, i, j, m; + var pmap=[]; + + function markup(r, c) + { + var r_origin, c_origin, i, j, fixed_r, fixed_c; + + r_origin = parseInt(r / gran) * gran - 7; + c_origin = parseInt(c / gran) * gran - 7; + + for(i = 0; i < 16; i++) + for(j = 0; j < 16; j++) { + fixed_r = fixrow(r_origin+i); + fixed_c = fixcol(c_origin+j); + if(pmap[fixed_r][fixed_c] == 0) + pmap[fixed_r][fixed_c] = 3; + } + } + + /* clear the player map */ + + for(r = 0; r < map_height; r++) { + pmap[r]=[]; + for(c = 0; c < map_width; c++) { + pmap[r][c] = 0; + } + } + + /* find the nation's groups */ + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == ntn) { + r = armies[i].r; + c = armies[i].c; + pmap[r][c] = 1; + } + + for(i = 0; i < citycnt; i++) + if(cities[i].nation == ntn) { + r = cities[i].r; + c = cities[i].c; + pmap[r][c] = 1; + } + + /* mark up the overlay */ + + for(c = 0; c < map_width; c++) + for(r = 0; r < map_height; r++) + if(pmap[r][c] == 1) + markup(r, c); + + /* write map */ + + fp.printf("%c %d %d\n\n", + marks[0][nations[ntn].mark], map_height, map_width); + + for(r = 0; r < map_height; r++) { + for(c = 0; c < map_width; c++) + fp.printf("%s%s%u", + map[r][c], mapovl[r][c], pmap[r][c]); + fp.write('\n'); + } +} + +function titlescreen() +{ + var i; + var title = [ + " S O L O M O R I A H ' S", + "", + " # # ## ##### ###", + " # # # # # # ###", + " # # # # # # ###", + " # # ###### ##### # ", + " # ## # # # # # ", + " ## ## # # # # ###", + " # # # # # # ###", + ]; + + console.clear(7); + + for(i=0; i<title.length; i++) { + console.gotoxy(11, i+3); + console.print(title[i]); + } + + console.gotoxy(11, i+3); + console.print('JSWAR Version '+(major_ver)+'.'+(minor_ver)+' "Code by Solomoriah"'); + + console.gotoxy(11, i+5); + console.print("Original Copyright 1993, 1994, 2001, 2013, Chris Gonnerman"); + + console.gotoxy(11, i+6); + console.print("JavaScript Version Copyright 2013, Stephen Hurd"); + + console.gotoxy(11, i+7); + console.print("All Rights Reserved."); +} + +function newcity() +{ + var i; + var clusters = []; + var cc; + var c; + var cl; + + for(i = 0; i<MAXCITIES; i++) + clusters[i] = -1; + + for(i=0; i<citycnt; i++) { + if(cities[i].nation > 0) + clusters[cities[i].cluster % MAXCITIES] = 1; + else if(clusters[cities[i].cluster % MAXCITIES] == -1) + clusters[cities[i].cluster % MAXCITIES] = 0; + } + + cc = 0; + + for(i = 0; i < MAXCITIES; i++) + if(clusters[i] == 0) + cc++; + + if(cc == 0) { /* any city will do... */ + cc = 0; + + for(i = 0; i < citycnt; i++) + if(cities[i].nation == 0) + cc++; + + if(cc == 0) + return -1; + + c = random(cc); + + for(i = 0; i < citycnt; i++) + if(cities[i].nation == 0) + if(c == 0) + return i; + else + c--; + + /* should not get here... */ + + return -1; + + } else { /* find an empty cluster... */ + + c = random(cc); + + for(i = 0; i < MAXCITIES; i++) + if(clusters[i] == 0) + if(c == 0) + break; + else + c--; + + if(i < MAXCITIES) { + cl = i; + cc = 0; + for(i = 0; i < citycnt; i++) + if(cities[i].cluster == cl) + cc++; + c = random(cc); + for(i = 0; i < citycnt; i++) + if(cities[i].cluster == cl) + if(c == 0) + return i; + else + c--; + } + + /* should not get here. */ + + return -1; + } +} + +function main(argc, argv) +{ + var rc; + var uid; + var n; + var c; + var ch; + var t; + var trys; + var mtbl; + var line; + var offset; + var confirmed; + var fp=new File(); + var pp=new File(); + var filename=''; + var inbuf=''; + var name=''; + var p; + var u; + var pass=''; + var cmd=''; + var gamedir=''; + var st_buf; + var i; + + titlescreen(); + + /* load map file */ + + if((rc = loadmap()) != 0) { + console.gotoxy(11,21); + console.print("Error Loading Map ("+rc+")\r\n"); + console.getkey(); + exit(1); + } + if((rc = loadsave()) != 0) { + console.gotoxy(11,21); + console.print("Error Loading Game Save ("+rc+")\r\n"); + console.getkey(); + exit(2); + } + + console.gotoxy(11,17); + if(world.length > 0) + console.print("World: "+world+" "); + console.print("Turn: "+gen); + + uid = user.number; + + if(uid == undefined || uid == 0) { + console.gotoxy(11, 21); + console.print("UID Not Available; Aborting."); + console.getkey(); + exit(3); + } + + console.gotoxy(11, 21); + console.print("Reading Master Commands... "); + + fp = new File(game_dir+'/master.cmd'); + if(fp.open('rb')) { + for(i=0; (inbuf = fp.readln())!=null; i++) { + if((rc=execpriv(inbuf)==0)) { + console.gotoxy(49,21); + console.print(format("%3d lines")); + } + else { + console.gotoxy(11,21); + console.print("Master Cmd Failed, Line "+(i+1)+", Code "+rc+" "); + console.getkey(); + exit(4); + } + } + fp.close(); + } + + /* check if nation is entered. */ + + n = -1; + + for(i = 0; i < nationcnt; i++) { + if(nations[i].uid == uid) { + /* TODO: Check for the canary file! */ + n = i; + break; + } + } + + if(n == -1) { /* nation not entered yet... */ + c = newcity(); + + if(c >= 0) { + fp = new File(game_dir+'/master.cmd'); + if(!fp.open('ab')) { + console.gotoxy(11,21); + console.print("Can't Write Master Cmd's "); + console.cleartoeol(); + console.getkey(); + exit(5); + } + + n = nationcnt; + confirmed = 0; + + while(!confirmed) { + console.gotoxy(11,19); + console.print("Your City is "+ cities[c].name); + console.cleartoeol(); + + inbuf=''; + while(inbuf.length==0) { + console.gotoxy(11, 21); + console.print("(Enter ! to Retry)"); + console.cleartoeol(); + console.gotoxy(11, 20); + console.print("Enter your name: "); + console.cleartoeol(); + inbuf = console.getstr(NATIONNMLEN); + } + if(inbuf == '!') + c = newcity(); + else + confirmed = 1; + } + + name=inbuf; + console.gotoxy(11,22); + console.print("Available: "); + + inbuf = marks[0]; + for(i=0; i<nationcnt; i++) + inbuf = inbuf.replace(nations[i].mark, ''); + inbuf = inbuf.replace(' ',''); + console.print(inbuf); + console.gotoxy(11, 21); + console.print("Select Nation Mark: "); + console.cleartoeol(); + ch = console.getkeys(inbuf); + console.gotoxy(11,22); + console.cleartoeol(); + inbuf = "new-nation '"+name+"' "+uid+' '+c+' '+ch; + fp.writeln(inbuf); + execpriv(inbuf); + + /* ... and the hero... */ + t = cities[c].types[0]; + mtbl = ttypes[t].move_tbl; + inbuf = "make-army '"+name+"' "+n+' '+cities[c].r+' '+cities[c].c+' '+(random(3)+4)+' '+(random(2)+1)+' 8 '+(mtbl)+' 0 1'; + fp.writeln(inbuf); + execpriv(inbuf); + + /* ...and take the city. */ + inbuf = 'control-city '+(n)+' '+(c); + fp.writeln(inbuf); + execpriv(inbuf); + fp.close(); + } + else { + console.gotoxy(11, 21); + console.print("No Cities Available. "); + console.cleartoeol(); + console.getkey(); + exit(6); + } + } + + /* execute player commands */ + + console.gotoxy(11, 21); + console.print("Reading Player Commands... "); + console.cleartoeol(); + fp = new File(format("%s/%04d.cmd", game_dir, uid)); + if(fp.open('rb')) { + for(i=0; (inbuf = fp.readln()) != null; i++) { + if((rc = execpriv(inbuf))==0) { + if((i+1) % 10 == 0) { + console.gotoxy(49, 21); + console.print(format("%3u lines", i)); + } + } + else { + console.gotoxy(11, 21); + console.print("Player Cmd Failed, Line "+(i+1)+", Code "+(rc)+" "); + console.getkey(); + exit(7); + } + } + fp.close(); + } + + /* append to player file... */ + + pfile = new File(format("%s/%04d.cmd", game_dir, uid)); + if(!pfile.open('ab', 0 /* Not buffered */)) { + console.gotoxy(11, 21); + console.print("Can't Create or Append Player Cmd's "); + console.cleartoeol(); + console.getkey(); + exit(8); + } + + /* main loop */ + + for(i=0; i<nationcnt; i++) + if(nations[i].uid == uid) + n = i; + + console.gotoxy(11, 20); + console.print("Welcome, "+nations[n].name+" of "+nationcity(n)+"!"); + console.cleartoeol(); + console.gotoxy(11, 21); + console.print("Press Any Key to Begin... "); + console.cleartoeol(); + console.getkey(); + mainscreen(); + mainloop(n); + + /* clean up */ + + pfile.close(); + + pfile = new File(format("%s/%04d.map", game_dir, uid)); + pfile.open('wb'); + writemap(pfile, n); + pfile.close(); + exit(0); +} + +main(argc, argv); + +/* end of file. */ diff --git a/xtrn/war/warcommon.js b/xtrn/war/warcommon.js new file mode 100644 index 0000000000000000000000000000000000000000..87ebc22c615d53ba4a1367b261e492828d4b75e0 --- /dev/null +++ b/xtrn/war/warcommon.js @@ -0,0 +1,589 @@ +// From stdver +const major_ver = 1; +const minor_ver = 0; + +// defines +const NATIONNMLEN = 14; +const MAXCITIES = 150; +const MAXMAPSZ = 160; +const TIME_TO_DESERT = 7; +const MAXARMIES = 2000; +const ARMYNAMLEN = 14; + +const TRANS_SELF = 0; +const TRANS_HERO = 1; +const TRANS_ONE = 2; +const TRANS_ALL = 3; + +const MAILFL = "mail.%03d"; +const NEWSFL = "news"; +const HEADERMARK = " \b"; +const MAILLOG = "mail.log"; +const GAMEBAK = "game.%03d"; +const MASTERFL = "master.cmd"; +const MASTERBAK = "master.%03d"; +const GAMESAVE = "game.save.json"; +const PLAYERFL = "%04d.cmd"; + +// defined by loadmap() +var map_width; +var map_height; +var map=[]; +var mapovl=[]; + +function loadmap() +{ + var fp; + var inbuf=''; + var rows, cols, i, j, m; + + /* initialize map arrays */ + + fp = new File(game_dir+'/map'); + if(!fp.open('rb')) + return 'Open Error'; + if((inbuf = fp.readln())==null) { + fp.close(); + return 'Read Error'; + } + if(inbuf.substr(0, 2) != 'M ') { + fp.close(); + return 'Invalid Header'; + } + + if((m=inbuf.match(/^M ([0-9]+) ([0-9]+)$/))==null || m[1] < 1 || m[2] < 1 || m[1] > MAXMAPSZ || m[2] > MAXMAPSZ) { + fp.close(); + return 'Invalid Header'; + } + map_height=rows=parseInt(m[1], 10); + map_width=cols=parseInt(m[2], 10); + + fp.readln(); + + for(i = 0; i < rows; i++) { + map[i]=[]; + mapovl[i]=[]; + for(j = 0; j < cols; j++) { + map[i][j] = '~'; + mapovl[i][j] = ' '; + } + } + + for(i = 0; i < rows; i++) { + if((inbuf = fp.readln())==null) { + fp.close(); + return 'Unexpected EOF'; + } + for(j = 0; j<cols && j<inbuf.length; j++) + map[i][j] = inbuf.substr(j, 1) == ' ' ? '~' : inbuf.substr(j, 1); + } + fp.close(); + + return 0; +} + +// defined by loadsave() +var cities; +var citycnt = 0; +var ttypes; +var ttypecnt = 0; +var armies; +var armycnt = 0; +var move_table; +var mvtcnt = 0; +var world=''; +var nations; +var nationcnt=0; +var gen=0; + +const marks = [ + "*ABCDEFGHIJKLMNOPQRSTUVWXYZ?", + "@abcdefghijklmnopqrstuvwxyz " +]; + +function loadsave() { + var game; + var i; + var fp=new File(game_dir+'/game.save.json'); + if(!file_exists(fp.name)) + fp=new File(game_dir+'/game.orig.json'); + + if(!fp.open('rb')) + return 'Open Error'; + + game=JSON.parse(fp.readAll().join('\n')); + fp.close(); + + /* add cities to map overlay */ + + for(i = 0; i < game.cities.length; i++) { + if(mapovl[game.cities[i].r][game.cities[i].c] == ' ' + || marks[1].indexOf(mapovl[game.cities[i].r][game.cities[i].c]) != -1) + mapovl[game.cities[i].r][game.cities[i].c] = game.nations[game.cities[i].nation].mark; + else + mapovl[game.cities[i].r][game.cities[i].c] = '!'; + } + + /* clean up */ + + cities=game.cities; + ttypes=game.ttypes; + nations=game.nations; + armies=game.armies; + move_table=game.move_table; + world=game.world; + + citycnt = game.cities.length; + ttypecnt = game.ttypes.length; + nationcnt = game.ncnt; + armycnt = game.armies.length; + mvtcnt = game.move_table.length; + gen = game.gen; + + fp.close(); + + return 0; +} + +var maint_in_progress = false; +var news = new File(game_dir+'/news'); +function nation_news(name, city) { + if(maint_in_progress && news.is_open) + news.write(name+' becomes the ruler of '+cities[city].name+'!\r\n\r\n'); +} + +function instance(n) +{ + var buff; + + if(n > 10 && n < 20) { + buff = format("%dth", n); + return buff; + } + + switch(n % 10) { + case 1 : + buff = format("%dst", n); + break; + + case 2 : + buff = format("%dnd", n); + break; + + case 3 : + buff = format("%drd", n); + break; + + default : + buff = format("%dth", n); + break; + } + + return buff; +} + +var privtable = { + "global-update":function(argc, argv) { + var i, k, n, t, cnt, xch, max; + + /* pack army list */ + + do { + xch = 0; + + for(k = 0; k < armycnt; k++) + if(armies[k].nation == -1) + break; + + if(k < armycnt) { + for(i = armycnt - 1; i >= k; i--) + if(armies[i].nation != -1) + break; + else + armycnt--; + + if(i > k) { + armies[k].name = armies[i].name; + armies[k].nation = armies[i].nation; + armies[k].r = armies[i].r; + armies[k].c = armies[i].c; + armies[k].combat = armies[i].combat; + armies[k].hero = armies[i].hero; + armies[k].move_rate = armies[i].move_rate; + armies[k].move_tbl = armies[i].move_tbl; + armies[k].special_mv = armies[i].special_mv; + armies[k].eparm1 = armies[i].eparm1; + + armycnt--; + + xch = 1; + } + } + } while(xch); + + /* create new armies */ + + for(i = 0; i < citycnt; i++) { + + cnt = 0; + + for(k = 0; k < armycnt; k++) + if(armies[k].nation == cities[i].nation + && armies[k].r == cities[i].r + && armies[k].c == cities[i].c) + cnt++; + + max = cities[i].defense * 2; + + if(max > 10) + max = 10; + + if(cities[i].nation != 0) { + max = 12; + k = cities[i].nation; + if(nations[k].idle_turns >= TIME_TO_DESERT) + max = 0; + } + + if(cnt < max) { + + n = cities[i].prod_type; + + if(n >= 0 && n < 4) { + cities[i].turns_left--; + if(cities[i].turns_left < 1) { + if(armycnt < MAXARMIES - 1) { + t = cities[i].types[n]; + + armies[armycnt] = {}; + armies[armycnt].name = format(".%03d/%03d/%03d" + , i, t, ++cities[i].instance[n]); + + armies[armycnt].nation = cities[i].nation; + armies[armycnt].r = cities[i].r; + armies[armycnt].c = cities[i].c; + + armies[armycnt].combat = ttypes[t].combat; + armies[armycnt].hero = 0; + + armies[armycnt].move_rate = ttypes[t].move_rate; + armies[armycnt].move_tbl = ttypes[t].move_tbl; + armies[armycnt].special_mv = + ttypes[t].special_mv; + armies[armycnt].eparm1 = 0; + + armycnt++; + + cities[i].turns_left = cities[i].times[n]; + + } else + cities[i].turns_left = 0; + } + } + } + } + + /* update all armies' movement. */ + + for(i = 0; i < armycnt; i++) + armies[i].move_left = armies[i].move_rate; + + gen++; + + return 0; + }, + "new-nation":function(argc, argv) { + var i, r, c; + + /* if in war update, add news entry */ + + nation_news(argv[1], parseInt(argv[3],10)); + + /* create nation entry */ + + nations[nationcnt].name = argv[1]; + nations[nationcnt].uid = parseInt(argv[2], 10); + nations[nationcnt].city = parseInt(argv[3], 10); + nations[nationcnt].mark = argv[4].substr(0, 1); + + /* transfer armies */ + + r = cities[nations[nationcnt].city].r; + c = cities[nations[nationcnt].city].c; + + for(i = 0; i < armycnt; i++) + if(armies[i].r == r + && armies[i].c == c + && armies[i].nation == 0) + armies[i].nation = nationcnt; + + /* clean up */ + + nationcnt++; + + return 0; + }, + "control-city":function(argc, argv) { + var c; + + cities[c = parseInt(argv[2], 10)].nation = parseInt(argv[1], 10); + + if(argv[3] != undefined && parseInt(argv[3], 10) > 0) + cities[c].turns_left = cities[c].times[cities[c].prod_type] + 1; + + return 0; + }, + "kill-army":function(argc, argv) { + var a, i, n; + + a = parseInt(argv[1], 10); + + if(a == -2) { + i = parseInt(argv[2], 10); + n = parseInt(argv[3], 10); + if(n > 0) { + armies[i].nation = n; + if(armies[i].hero > 1) + armies[i].hero--; + return 0; + } + a = i; + } + + if(a == -1) { + n = parseInt(argv[2], 10); + if(n < 1 || n > nationcnt) + return 0; + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n) { + armies[i].nation = -1; + armies[i].r = -1; + armies[i].c = -1; + } + return 0; + } + + armies[a].nation = -1; + armies[a].r = -1; + armies[a].c = -1; + + return 0; + }, + "move-army":function(argc, argv) { + var a, b; + + a = parseInt(argv[1], 10); + + if(armies[a].nation == -1) + return 0; + + b = armies[a].move_left; + b -= parseInt(argv[2], 10); + if(b < 0) + b = 0; + armies[a].move_left = b; + armies[a].r = parseInt(argv[3], 10); + armies[a].c = parseInt(argv[4], 10); + + return 0; + }, + "make-army":function(argc, argv) { + /* no error, just don't do it. */ + + if(armycnt >= MAXARMIES) + return 0; + + armies[armycnt] = { + name:argv[1].substr(0, ARMYNAMLEN), + nation:parseInt(argv[2], 10), + r:parseInt(argv[3], 10), + c:parseInt(argv[4], 10), + combat:parseInt(argv[5], 10), + hero:parseInt(argv[6], 10), + move_rate:parseInt(argv[7], 10), + move_left:parseInt(argv[7], 10), + move_tbl:parseInt(argv[8], 10), + special_mv:parseInt(argv[9], 10), + eparm1:parseInt(argv[10], 10) + }; + + armycnt++; + + return 0; + }, + "name-army":function(argc, argv) { + var a; + + a = parseInt(argv[1], 10); + + if(armies[a].nation == -1) + return 0; + + armies[a].name = argv[2].substr(0, ARMYNAMLEN); + + return 0; + }, + "change-army":function(argc, argv) { + var a, c, h; + + a = parseInt(argv[1], 10); + c = parseInt(argv[2], 10); + h = parseInt(argv[3], 10); + + if(armies[a].nation == -1) + return 0; + + if(c >= 0) armies[a].combat = c; + if(h >= 0) armies[a].hero = h; + + return 0; + }, + "set-eparm":function(argc, argv) { + var a; + + a = parseInt(argv[1], 10); + + if(armies[a].nation == -1) + return 0; + + armies[a].eparm1 = parseInt(argv[2], 10); + + return 0; + }, + "set-produce":function(argc, argv) { + var c; + + c = parseInt(argv[1], 10); + + cities[c].prod_type = parseInt(argv[2], 10); + cities[c].turns_left = cities[c].times[cities[c].prod_type]; + + return 0; + } +}; + +function parseline(line) { + var i; + var s; + var args=[]; + + i = 0; + + while(line.length > 0 && i++ < 20) { + line=line.replace(/^\s*((?:'.*?')|(?:[^'\s][^\s]*))\s*/, function(m, str) { + str=str.replace(/^'(.*)'$/,"$1"); + args.push(str); + return ''; + }); + } + + return args; +} + +function execpriv(line) +{ + var args=[]; + var n; + + args = parseline(line); + + if(args.length == 0) + return 'No Text on Line'; + + if(privtable[args[0]] == undefined) + return 'No Such Command'; + + return privtable[args[0]](args.length, args); +} + +function my_city_at(r, c, n) +{ + var i; + + for(i = 0; i < citycnt; i++) + if((n < 0 || cities[i].nation == n) + && cities[i].r == r + && cities[i].c == c) + return i; + + return -1; +} + +function city_at(r, c) +{ + return my_city_at(r, c, -1); +} + +function nationcity(n) +{ + if(n == 0) return "Militia"; + if(n == 27) return "Rogue"; + + return cities[nations[n].city].name; +} + +function armyname(a) +{ + var c, t, i, m; + var buff; + + if(armies[a].name.substr(0, 1) != '.') + return armies[a].name; + + c = 0; + t = 0; + i = -1; + + m=armies[a].name.match(/([0-9]+)\/([0-9]+)\/([0-9]+)/); + if(m==null) + return "????"; + c=parseInt(m[1], 10); + t=parseInt(m[2], 10); + i=parseInt(m[3], 10); + + buff = cities[c].name+' '+instance(i)+' '+ttypes[t].name; + return buff; +} + +function isgreater(a1, a2) +{ + var c1, c2, t1, t2, i1, i2; + var buf1=''; + var buf2=''; + var m; + + if(armies[a1].hero > armies[a2].hero) return 1; + if(armies[a1].hero < armies[a2].hero) return 0; + + if(armies[a1].special_mv > armies[a2].special_mv) return 1; + if(armies[a1].special_mv < armies[a2].special_mv) return 0; + + if(armies[a1].combat > armies[a2].combat) return 1; + if(armies[a1].combat < armies[a2].combat) return 0; + + if(armies[a1].move_rate > armies[a2].move_rate) return 1; + if(armies[a1].move_rate < armies[a2].move_rate) return 0; + + if(armies[a1].name.substr(0,1) != '.' && armies[a2].name.substr(0,1) == '.') + return 1; + + if(armies[a1].name.substr(0,1) == '.' && armies[a2].name.substr(0,1) != '.') + return 0; + + if(armies[a1].name.substr(0,1) != '.' && armies[a2].name.substr(0,1) != '.') + if(armies[a1].name > armies[a2].name) + return 1; + else + return 0; + + if((m=armies[a1].name.match(/^\.([0-9]+)\/([0-9]+)\/([0-9]+)$/))!=null) + buf1=format("%03d%03d%03d", parseInt(m[1], 10),parseInt(m[2], 10),parseInt(m[3], 10)); + if((m=armies[a2].name.match(/^\.([0-9]+)\/([0-9]+)\/([0-9]+)$/))!=null) + buf2=format("%03d%03d%03d", parseInt(m[1], 10),parseInt(m[2], 10),parseInt(m[3], 10)); + + if(buf1 > buf2) + return 1; + + return 0; +} + diff --git a/xtrn/war/warupd.js b/xtrn/war/warupd.js new file mode 100644 index 0000000000000000000000000000000000000000..4486e3411e32abc597000cf4253f12a97751c318 --- /dev/null +++ b/xtrn/war/warupd.js @@ -0,0 +1,942 @@ +var game_dir = js.exec_dir; +/* + Solomoriah's WAR! + + warupd.c -- main procedure file for war update + + Copyright 2013 Stephen Hurd + All rights reserved. + + 3 Clause BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, self list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, self list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the author nor the names of any contributors + may be used to endorse or promote products derived from self software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +// Based on: +/* + Solomoriah's WAR! + + warupd.c -- main procedure file for war update + + Copyright 1993, 1994, 2001, 2013 Chris Gonnerman + All rights reserved. + + 3 Clause BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, self list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, self list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the author nor the names of any contributors + may be used to endorse or promote products derived from self software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +load(game_dir+'/warcommon.js'); + +var mfile; + +var nlist=[]; +var nlcnt; +function shuffle() +{ + var i, n1, n2, tmp; + + nlcnt = 0; + + for(i = 1; i < nationcnt; i++) + nlist[nlcnt++] = i; + + for(i = 0; i < nlcnt * nlcnt; i++) { + n1 = random(nlcnt); + n2 = random(nlcnt); + if(n1 != n2) { + tmp = nlist[n1]; + nlist[n1] = nlist[n2]; + nlist[n2] = tmp; + } + } +} + +var usertable = { + "move-army":function(argc, argv) { + var a, b; + + a = parseInt(argv[1], 10); + + if(armies[a].nation == -1) + return 0; + + if(argc > 5) { + b = parseInt(argv[5], 10); + + if(a != b && armies[b].nation == -1) + return 0; + } + + b = armies[a].move_left; + b -= parseInt(argv[2], 10); + if(b < 0) + b = 0; + armies[a].move_left = b; + armies[a].r = parseInt(argv[3], 10); + armies[a].c = parseInt(argv[4], 10); + + if(argc > 5) + mfile.printf("move-army %s %s %s %s %s\n", + argv[1], argv[2], argv[3], argv[4], argv[5]); + else + mfile.printf("move-army %s %s %s %s\n", + argv[1], argv[2], argv[3], argv[4]); + + return 0; + }, + "make-army":function(argc, argv) { + /* no error, just don't do it. */ + + if(armycnt >= MAXARMIES) + return 0; + + armies[armycnt].name = argv[1].substr(0, ARMYNAMLEN); + armies[armycnt].nation = parseInt(argv[2], 10); + armies[armycnt].r = parseInt(argv[3], 10); + armies[armycnt].c = parseInt(argv[4], 10); + armies[armycnt].combat = parseInt(argv[5], 10); + armies[armycnt].hero = parseInt(argv[6], 10); + armies[armycnt].move_rate = parseInt(argv[7], 10); + armies[armycnt].move_left = parseInt(argv[7], 10); + armies[armycnt].move_tbl = parseInt(argv[8], 10); + armies[armycnt].special_mv = parseInt(argv[9], 10); + armies[armycnt].eparm1 = 0; + + armycnt++; + + mfile.printf("make-army '%s' %s %s %s %s %s %s %s %s\n", + argv[1], argv[2], argv[3], + argv[4], argv[5], argv[6], + argv[7], argv[8], argv[9]); + + return 0; + }, + "name-army":function(argc, argv) { + var a; + + a = parseInt(argv[1], 10); + + if(armies[a].nation == -1) + return 0; + + armies[a].name = argv[2].substr(0, ARMYNAMLEN); + + mfile.printf("name-army %s '%s'\n", argv[1], argv[2]); + + return 0; + }, + "set-produce":function(argc, argv) { + var c; + + c = parseInt(argv[1], 10); + + cities[c].prod_type = parseInt(argv[2], 10); + cities[c].turns_left = cities[c].times[cities[c].prod_type]; + + mfile.printf("set-produce %s %s\n", argv[1], argv[2]); + + return 0; + } +}; + +function execuser(line) +{ + var args; + var n; + + args = parseline(line); + + if(args.length == 0) + return 5; + + if(usertable[args[0]] != undefined) + return usertable[args[0]](args.length, args); + return 6; +} + +var mail_gen = 0; +function mail_line(text, ntn) +{ + var i, pos; + var fname; + var mailfiles = [ + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null}, + {ntn:-1, age:0, fp:null} + ]; + + if(ntn == -1) { /* close all */ + for(i = 0; i < 8; i++) { + if(mailfiles[i].fp != null) + mailfiles[i].fp.close(); + + mailfiles[i].ntn = -1; + mailfiles[i].age = 0; + mailfiles[i].fp = null; + } + return; + } + + if(ntn == 0 || ntn == 27) /* ignore god and rogue */ + return; + + /* find the nation's mail file if already open... */ + + for(i = 0; i < 8; i++) + if(mailfiles[i].ntn == ntn) { + mailfiles[i].age = mail_gen++; + break; + } + + if(i >= 8) { /* not open. */ + pos = 0; + + for(i = 1; i < 8; i++) + if(mailfiles[i].age < mailfiles[pos].age) + pos = i; + + if(mailfiles[pos].fp != null) + mailfiles[pos].fp.close(); + + mailfiles[pos].ntn = -1; + + fname = game_dir+'/'+format(MAILFL, ntn); + mailfiles[pos].fp = new File(fname); + + if(!mailfiles[pos].fp.open('ab')) /* error, can't stop now... */ + return; + + mailfiles[pos].ntn = ntn; + mailfiles[pos].age = mail_gen++; + + } else + pos = i; + + mailfiles[pos].fp.write(text); +} + +function message_out(text, n1, n2, do_news) +{ + if(n1) + mail_line(text, n1); + + if(n2) + mail_line(text, n2); + + if(do_news) + news.write(text); + + print(text); +} + +function capture(n, c) +{ + var buff; + var n2; + + n2 = cities[c].nation; + + buff = nationcity(n)+" captures "+cities[c].name; + message_out(buff, n, n2, 1); + + if(cities[c].nation > 0) { + buff = " from "+nationcity(n2)+"\n"; + message_out(buff, n, n2, 1); + } else + message_out("\n", n, n2, 1); + + buff = "control-city "+n+" "+c+" 1\n"; + mfile.write(buff); + execpriv(buff); +} + +/* + make_stack forms the stack of armies which includes army a. +*/ + +function make_stack(stack, a) +{ + var i, n, r, c, h; + + n = armies[a].nation; + r = armies[a].r; + c = armies[a].c; + + stack.count = 0; + stack.ctot = 0; + stack.hero = -1; + h = 0; + + for(i = 0; stack.count < 12 && i < armycnt; i++) + if(armies[i].nation == n + && armies[i].r == r + && armies[i].c == c) { + stack.index[stack.count] = i; + if(armies[i].hero > h) { + stack.hero = stack.count; + h = armies[i].hero; + } + stack.ctot += armies[i].combat; + stack.count++; + } + + stack.ctot += stack.count * h; + + stack.city = city_at(r, c); + + if(cities[stack.city].nation != n) + stack.city = -1; + + if(stack.city != -1) + stack.ctot += stack.count * cities[stack.city].defense; +} + +function least(stack) +{ + var i, n; + + n = 0; + + for(i = 0; i < stack.count; i++) + if(isgreater(stack.index[n], stack.index[i])) + n = i; + + return n; +} + +function stack_remove(stack, idx) +{ + var i, h; + + if(stack.count < 1) + return; + + stack.count--; + + if(idx < stack.count) + stack.index[idx] = stack.index[stack.count]; + + stack.ctot = 0; + stack.hero = -1; + h = 0; + + for(i = 0; i < stack.count; i++) { + stack.ctot += armies[stack.index[i]].combat; + if(armies[stack.index[i]].hero > h) { + stack.hero = i; + h = armies[stack.index[i]].hero; + } + } + + stack.ctot += stack.count * h; + + if(stack.city != -1) + stack.ctot += stack.count * cities[stack.city].defense; +} + +function advance(hero) +{ + var res; + var buff; + + print("advance "+hero+"\n"); + + res = random(9) + 1; + + if(res <= (armies[hero].hero + armies[hero].combat)) + return; + + if(armies[hero].combat < 7 + && random(8) >= armies[hero].combat) { + print("advance "+hero+" combat\n"); + buff = "change-army "+hero+" "+armies[hero].combat + 1+" "+armies[hero].hero+"\n"; + mfile.write(buff); + execpriv(buff); + return; + } + + if(armies[hero].hero < 3 + && random(4) >= armies[hero].hero) { + print("advance "+hero+" hero\n"); + buff = "change-army "+hero+" "+armies[hero].combat+" "+armies[hero].hero + 1+"\n"; + mfile.write(buff); + execpriv(buff); + } +} + +function battle(a, b) +{ + var stacks = [ + {ctot:0, hero:0, count:0, city:0, index:[0,0,0,0,0,0,0,0,0,0,0,0]}, + {ctot:0, hero:0, count:0, city:0, index:[0,0,0,0,0,0,0,0,0,0,0,0]} + ]; + var ntns=[0,0]; + var r, c, city, hi, total, rlose, rwin, l, i, d, dn; + var names, buff; + + ntns[0] = armies[a].nation; + ntns[1] = armies[b].nation; + + names[0] = nationcity(ntns[0]); + names[1] = nationcity(ntns[1]); + + r = armies[a].r; + c = armies[a].c; + city = city_at(r, c); + + buff = "Battle between "+names[0]+" and "+names[1]; + message_out(buff, ntns[0], ntns[1], 1); + + if(city != -1) { + buff = " in "+cities[city].name; + message_out(buff, ntns[0], ntns[1], 1); + } + + buff = " (Turn "+gen+")"; + message_out(buff, ntns[0], ntns[1], 0); + + message_out("\n", ntns[0], ntns[1], 1); + + make_stack(stacks[0], a); + make_stack(stacks[1], b); + + buff = "(Odds: "+stacks[0].ctot+" to "+stacks[1].ctot+")\n"; + message_out(buff, ntns[0], ntns[1], 0); + + for(i = 0; i < 2; i++) { + + buff = names[i]+" has "+stacks[i].count+" armies"; + message_out(buff, ntns[0], ntns[1], 1); + + if((hi = stacks[i].hero) != -1) { + buff = " led by " + + armies[stacks[i].index[hi]].name[0] == '\0' + ? "a nameless hero" + : armies[stacks[i].index[hi]].name; + buff += '\n'; + message_out(buff, ntns[0], ntns[1], 1); + } else + message_out("\n", ntns[0], ntns[1], 1); + } + + while(stacks[0].count > 0 && stacks[1].count > 0) { + + total = stacks[0].ctot + stacks[1].ctot; + + /* roll dem bones */ + + if(random(total) < stacks[0].ctot) + rlose = 1; + else + rlose = 0; + + rwin = (rlose + 1) % 2; + + /* check for hero desertion */ + + d = -1; + + if(stacks[rlose].ctot < parseInt(stacks[rwin].ctot / 2) + && (hi = stacks[rlose].hero) != -1 + && armies[stacks[rlose].index[hi]].eparm1 != 1) { + if(random(10) < 5) { + dn = -1; + if(stacks[rwin].count < 12 && random(10) < 5) + dn = ntns[rwin]; + d = hi; + } else { + buff = "set-eparm "+stacks[d].index[hi]+" 1\n"; + mfile.write(buff); + execpriv(buff); + } + } + + /* find the victim */ + + if(d == -1) { + l = least(stacks[rlose]); + + buff = armyname(stacks[rlose].index[l])+" ("+names[rlose]+") is destroyed.\n"; + message_out(buff, ntns[0], ntns[1], 0); + + if(armies[stacks[rlose].index[l]].hero > 0) + news.write(buff); + + /* kill an army */ + + buff = "kill-army "+stacks[rlose].index[l]+"\n"; + mfile.write(buff); + execpriv(buff); + + } else { + l = d; + + buff = armyname(stacks[rlose].index[l])+" ("+names[rlose]+") deserts"; + message_out(buff, ntns[0], ntns[1], 1); + + if(dn != -1) { + buff = " and joins "+nationcity(dn)+"\n"; + message_out(buff, ntns[0], ntns[1], 1); + } else + message_out("\n", ntns[0], ntns[1], 1); + + /* hero deserts */ + + buff = "kill-army -2 "+stacks[rlose].index[d]+" "+dn+"\n"; + mfile.write(buff); + execpriv(buff); + + /* rebuild other stack around the deserter */ + + if(dn != -1) + make_stack(stacks[rwin], d); + } + + /* remove army from stack */ + + stack_remove(stacks[rlose], l); + } + + if(stacks[0].count < 1) + rwin = 1; + else + rwin = 0; + + buff = names[rwin]+" wins!\n"; + message_out(buff, ntns[0], ntns[1], 1); + + if(city != -1 + && cities[city].nation != ntns[rwin]) + capture(ntns[rwin], city); + + if((hi = stacks[rwin].hero) != -1) + advance(stacks[rwin].index[hi]); +} + +function combat(n) +{ + var i, j, c; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n) + for(j = 0; j < armycnt; j++) + if(armies[j].nation != n + && armies[j].r == armies[i].r + && armies[j].c == armies[i].c) { + + mail_line(HEADERMARK, armies[i].nation); + mail_line(HEADERMARK, armies[j].nation); + + battle(i, j); + print('\n'); + news.write('\n'); + break; + } + + /* all battles are now over. */ + /* rescan the armies table for armies attacking undefended cities */ + /* must scan separately since armies may have died in battle */ + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n) + if((c = city_at(armies[i].r, armies[i].c)) != -1 + && cities[c].nation != n) { + + mail_line(HEADERMARK, armies[i].nation); + mail_line(HEADERMARK, cities[c].nation); + + capture(armies[i].nation, c); + print('\n'); + news.write('\n'); + } +} + +/* + deserter() causes a randomly-selected non-hero army to desert the + given nation. +*/ + +function deserter(n) +{ + var narmies, i, die; + var buff; + + narmies = 0; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n + && armies[i].hero < 1) + narmies++; + + if(narmies < 1) + return; + + die = random(narmies); + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n + && armies[i].hero < 1) + if(die == 0) + break; + else + die--; + + + /* found one, kill it. */ + + mail_line(" \b", n); + buff = armyname(i)+" deserts "+nations[n].name+" of "+nationcity(n)+"."; + message_out(buff, n, 0, 1); + + buff = " (Turn "+gen+")"; + message_out(buff, n, 0, 0); + + message_out("\n\n", n, 0, 1); + + /* so kill it. */ + + buff = "kill-army "+i+"\n"; + mfile.write(buff); + execpriv(buff); +} + +/* + creator() constructs a hero for the given nation, *if* the nation + needs one and if a roll indicates one is to be created. + + a nation "needs" a hero when it has more cities than heros. + + a roll is then made using (number of cities) - (number of heros) + as a percent chance EXCEPT if the nation has NO heros; then the + odds are 10 times normal. Maximum odds are 90% in either case. +*/ + +function creator(n) +{ + var nheros, ncities, odds, counter, i, c, r, t, mtbl; + var buff; + + ncities = 0; + + for(i = 0; i < citycnt; i++) + if(cities[i].nation == n) + ncities++; + + nheros = 0; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n + && armies[i].hero > 0) + nheros++; + + odds = ncities - nheros; + + if(nheros == 0) + odds *= 10; + + if(odds > 90) + odds = 90; + + if(nheros >= ncities + || random(100) >= odds) + return; + + r = random(ncities); + + for(i = 0; i < citycnt; i++) + if(cities[i].nation == n) + if(r-- < 1) + break; + + c = i; + + /* too many armies there? */ + + counter = 0; + + for(i = 0; i < armycnt; i++) + if(armies[i].nation == n + && armies[i].r == cities[c].r + && armies[i].c == cities[c].c) + counter++; + + if(counter >= 12) + return; + + /* it's OK, do it. */ + + mail_line(" \b", n); + buff = "A hero arises in "+cities[c].name+" and joins "+nations[n].name+" of "+nationcity(n)+"!"; + message_out(buff, n, 0, 1); + + buff = " (Turn "+gen+")"; + message_out(buff, n, 0, 0); + + message_out("\n\n", n, 0, 1); + + t = cities[c].types[0]; + mtbl = ttypes[t].move_tbl; + + buff = format("make-army '' %d %d %d %d %d %d %d %d %d\n", + n, cities[c].r, cities[c].c, + random(4)+2, random(2)+1, 8, mtbl, 0, 0); + + mfile.write(buff); + execpriv(buff); +} + +function savegame(fp) +{ + var game={}; + + game.cities=cities; + game.ttypes=ttypes; + game.nations=nations; + game.armies=armies; + game.move_table=move_table; + game.world=world; + game.cities.length=citycnt; + game.ttypes.length=ttypecnt; + game.ncnt=nationcnt; + game.armies.length=armycnt; + game.move_table.length=mvtcnt; + game.gen=gen; + fp.write(JSON.stringify(game, null, '\t')); +} + +function main(argc, argv) +{ + var rc, i, j, k, n, u; + var fp; + var filename, inbuf, p; + + print(format("\nJSWARUPD Version %d.%d \"Code by Solomoriah\"\n", + major_ver, minor_ver)); + print("Original Copyright 1993, 1994, 2001, 2013, Chris Gonnerman\n"); + print("JavaScript Version Copyright 2013, Stephen Hurd\n"); + print("All Rights Reserved.\n\n"); + + + /* load map file */ + + rc = loadmap(); + + if(rc != 0) { + print("Error Loading Map ("+rc+")\n"); + exit(1); + } + + /* load game save */ + + rc = loadsave(); + + if(rc != 0) { + print("Error Loading Game Save ("+rc+")\n"); + exit(1); + } + + if(world.length != 0) + print("World: "+world+"\n"); + + /* open news output */ + + if(!news.open('ab')) { + print("Error Writing News File <"+news.name+">\n"); + exit(10); + } + maint_in_progress = true; + + print("Turn Update "+gen+"\n\n"); + + if(world.length != 0) { + news.write(" \b"); + news.write(world); + } else + news.write(" \bSolomoriah's WAR!"); + + news.write(" News Report Turn "+gen+"\n\n"); + + /* execute master file */ + + print("Reading Master Commands...\r\n"); + + fp = new File(game_dir+'/'+MASTERFL); + + if(fp.open('rb')) { + for(i = 0; (inbuf = fp.readln()) != null; i++) { + rc = execpriv(inbuf); + if(rc != 0) { + print("Master Cmd Failed, Line "+(i+1)+", Code "+rc+"\n"); + exit(2); + } + } + + fp.close(); + } + + /* open master for writing. */ + + mfile = new File(game_dir+'/'+MASTERFL); + + if(!mfile.open('ab')) { + print("Can't Append to Master File"); + exit(5); + } + + /* execute player commands */ + + print("Reading Player Commands...\r\n"); + + shuffle(); + + for(k = 0; k < nlcnt; k++) { + + n = nlist[k]; + u = nations[n].uid; + + filename = format(PLAYERFL, u); + + fp = new File(game_dir+'/'+filename); + + if(fp.open("rb")) { + + print("\n"+nations[n].name+" of "+nationcity(n)+" moves...\n"); + + nations[n].idle_turns = 0; + + for(i = 0; (inbuf = fp.readln()) != null; i++) { + rc = execuser(inbuf); + if(rc != 0) { + printf("Player Cmd Failed, Line "+(i+1)+", Code "+rc+" "); + exit(2); + } + } + + fp.close(); + + file_remove(fp.name); + } else { + print("\n"+nations[n].name+" of "+nationcity(n)+" is idle.\n"); +print("FILE: "+fp.name); + nations[n].idle_turns++; + } + + combat(n); + + if(nations[n].idle_turns >= TIME_TO_DESERT) + deserter(n); + else + creator(n); + } + + /* do the update */ + + print("Global Update...\n"); + + execpriv("global-update"); + mfile.write("global-update\n"); + + /* close up */ + + news.close(); + mfile.close(); + + mail_line(null, -1); + + /* consolidate */ + + filename = format(MASTERBAK, gen); + + if(!file_rename(game_dir+'/'+MASTERFL, game_dir+'/'+filename)) { + print("Can't Rename Master Cmd File\n"); + exit(9); + } + + filename = format(filename, GAMEBAK, gen); + + if(file_exists(game_dir+'/'+GAMESAVE) && !file_rename(game_dir+'/'+GAMESAVE, game_dir+'/'+filename)) { + print("Can't Rename Game Save\n"); + exit(9); + } + + fp = new File(game_dir+'/'+GAMESAVE); + + if(!fp.open('wb')) { + print("Can't Create New Save File\n"); + exit(9); + } + + /* clean up outdated files. */ + + if(gen - 4 > 0) { + filename = game_dir+'/'+format(MASTERBAK, gen - 4); + file_remove(filename); + + filename = game_dir+'/'+format(GAMEBAK, gen - 4); + file_remove(filename); + } + + savegame(fp); + + fp.close(); + + exit(0); +} + +main(argc, argv); diff --git a/xtrn/war/worlds/alderon/game.orig.json b/xtrn/war/worlds/alderon/game.orig.json new file mode 100644 index 0000000000000000000000000000000000000000..58253337eb2af2e9a9019b5abcc6c8793d4cee94 --- /dev/null +++ b/xtrn/war/worlds/alderon/game.orig.json @@ -0,0 +1,2047 @@ +{ + "ncnt": 1, + "nations": [ + { + "name": "Overlord", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "Rogue", + "uid": -1, + "city": 0, + "mark": "?", + "idle_turns": 0 + } + ], + "cities": [ + { + "name": "Indigo", + "cluster": 1, + "nation": 0, + "r": 62, + "c": 61, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lavender", + "cluster": 1, + "nation": 0, + "r": 58, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Crimson", + "cluster": 1, + "nation": 0, + "r": 57, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Saffron", + "cluster": 1, + "nation": 0, + "r": 62, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Verdant", + "cluster": 1, + "nation": 0, + "r": 1, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Metropolis", + "cluster": 2, + "nation": 0, + "r": 15, + "c": 11, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gotham", + "cluster": 2, + "nation": 0, + "r": 14, + "c": 6, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Keystone City", + "cluster": 2, + "nation": 0, + "r": 20, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Central City", + "cluster": 2, + "nation": 0, + "r": 18, + "c": 6, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Heliochrysum", + "cluster": 3, + "nation": 0, + "r": 32, + "c": 32, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Portulaca", + "cluster": 3, + "nation": 0, + "r": 28, + "c": 32, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gaillardia", + "cluster": 3, + "nation": 0, + "r": 35, + "c": 33, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Coreopsis", + "cluster": 3, + "nation": 0, + "r": 34, + "c": 36, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Delphineum", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 40, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ruby", + "cluster": 4, + "nation": 0, + "r": 21, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Amber", + "cluster": 4, + "nation": 0, + "r": 28, + "c": 23, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Emerald", + "cluster": 4, + "nation": 0, + "r": 26, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Diamond", + "cluster": 4, + "nation": 0, + "r": 22, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sapphire", + "cluster": 4, + "nation": 0, + "r": 25, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Zhentil Keep", + "cluster": 5, + "nation": 0, + "r": 39, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Shadowdale", + "cluster": 5, + "nation": 0, + "r": 36, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silverdale", + "cluster": 5, + "nation": 0, + "r": 44, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Battledale", + "cluster": 5, + "nation": 0, + "r": 41, + "c": 23, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Dread", + "cluster": 6, + "nation": 0, + "r": 44, + "c": 6, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 4, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Doom", + "cluster": 6, + "nation": 0, + "r": 50, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 7, + 15, + -1 + ], + "times": [ + 1, + 4, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Despair", + "cluster": 6, + "nation": 0, + "r": 52, + "c": 7, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Death", + "cluster": 6, + "nation": 0, + "r": 49, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Agony", + "cluster": 6, + "nation": 0, + "r": 52, + "c": 12, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 13, + 15, + -1 + ], + "times": [ + 1, + 3, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gloom", + "cluster": 6, + "nation": 0, + "r": 49, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Iron", + "cluster": 7, + "nation": 0, + "r": 51, + "c": 41, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gold", + "cluster": 7, + "nation": 0, + "r": 57, + "c": 36, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 20 + ], + "times": [ + 1, + 2, + 3, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silver", + "cluster": 7, + "nation": 0, + "r": 51, + "c": 36, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Tin", + "cluster": 7, + "nation": 0, + "r": 49, + "c": 34, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lead", + "cluster": 7, + "nation": 0, + "r": 54, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Nyarlathotep", + "cluster": 8, + "nation": 0, + "r": 2, + "c": 17, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Yogsothoth", + "cluster": 8, + "nation": 0, + "r": 8, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Cthulhu", + "cluster": 8, + "nation": 0, + "r": 1, + "c": 11, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Hastor", + "cluster": 8, + "nation": 0, + "r": 4, + "c": 12, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Olan", + "cluster": 9, + "nation": 0, + "r": 44, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Kaxandar", + "cluster": 9, + "nation": 0, + "r": 42, + "c": 39, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Torgar", + "cluster": 9, + "nation": 0, + "r": 40, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Arras Charka", + "cluster": 10, + "nation": 0, + "r": 11, + "c": 53, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 21, + -1 + ], + "times": [ + 1, + 2, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Derzon", + "cluster": 10, + "nation": 0, + "r": 11, + "c": 49, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ekosiak", + "cluster": 10, + "nation": 0, + "r": 14, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ish-Tako", + "cluster": 10, + "nation": 0, + "r": 13, + "c": 44, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Chishata", + "cluster": 10, + "nation": 0, + "r": 15, + "c": 49, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Qualinesti", + "cluster": 11, + "nation": 0, + "r": 0, + "c": 39, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 20 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sylvanesti", + "cluster": 11, + "nation": 0, + "r": 6, + "c": 38, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Rathwynn", + "cluster": 11, + "nation": 0, + "r": 5, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 17, + 5, + 11, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Caledon", + "cluster": 11, + "nation": 0, + "r": 1, + "c": 43, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Alfheim", + "cluster": 11, + "nation": 0, + "r": 62, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Atlantis", + "cluster": 12, + "nation": 0, + "r": 43, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Mu", + "cluster": 12, + "nation": 0, + "r": 45, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Poseidon", + "cluster": 12, + "nation": 0, + "r": 42, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Neptune", + "cluster": 12, + "nation": 0, + "r": 47, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + } + ], + "ttypes": [ + { + "name": "Lt. Infantry", + "combat": 2, + "move_rate": 6, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Hv. Infantry", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Lt. Cavalry", + "combat": 2, + "move_rate": 12, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Hv. Cavalry", + "combat": 3, + "move_rate": 8, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Dwarf Legion", + "combat": 3, + "move_rate": 4, + "move_tbl": 2, + "special_mv": 0 + }, + { + "name": "Elven Archers", + "combat": 3, + "move_rate": 6, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Zombie Legion", + "combat": 3, + "move_rate": 3, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Wraith Horde", + "combat": 4, + "move_rate": 6, + "move_tbl": 4, + "special_mv": 0 + }, + { + "name": "Elite Troopers", + "combat": 4, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Gug", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Dwarf Miners", + "combat": 4, + "move_rate": 4, + "move_tbl": 5, + "special_mv": 0 + }, + { + "name": "Scout", + "combat": 1, + "move_rate": 8, + "move_tbl": 6, + "special_mv": 0 + }, + { + "name": "Byakhee", + "combat": 2, + "move_rate": 7, + "move_tbl": 4, + "special_mv": 2 + }, + { + "name": "Ghouls", + "combat": 3, + "move_rate": 5, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Navy", + "combat": 2, + "move_rate": 10, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Undead Navy", + "combat": 3, + "move_rate": 8, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Clipper", + "combat": 2, + "move_rate": 12, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Infantry", + "combat": 2, + "move_rate": 8, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Mermen", + "combat": 2, + "move_rate": 6, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Tritons", + "combat": 3, + "move_rate": 4, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Pegasus", + "combat": 2, + "move_rate": 10, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Hippogryff", + "combat": 3, + "move_rate": 8, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Leviathan", + "combat": 5, + "move_rate": 4, + "move_tbl": 8, + "special_mv": 1 + } + ], + "armies": [], + "move_table": [ + { + "cost": [ + 0, + 1, + 2, + 2, + 4 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 3, + 0 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 2, + 4 + ] + }, + { + "cost": [ + 1, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 2, + 3 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 1, + 0, + 0, + 0, + 0 + ] + }, + { + "cost": [ + 1, + 1, + 2, + 3, + 4 + ] + } + ], + "world": "Alderon's World", + "gen": 0 +} \ No newline at end of file diff --git a/xtrn/war/worlds/alderon/map b/xtrn/war/worlds/alderon/map new file mode 100644 index 0000000000000000000000000000000000000000..47270ef31595b49484d59f498f4be4381fb0becf --- /dev/null +++ b/xtrn/war/worlds/alderon/map @@ -0,0 +1,66 @@ +M 64 64 + +...~%%%~~~^^#~~~%%%~~#%.%%%%..^^~~~####%%%%%#~.~~~~~~~~~~~~~~%%% +...~~~~~~~^##~~~%%%%###%....^^^^~~%#####%%%%~#.~~~~~~~~~~~~~~~~~ +..~~~~~~~~^##~~%%%%%###......^^~~~%%####%%%%~~.~~~~~~~~~~~~~~~~~ +~~~~~~~~~^^##%%%%%%%~##.......~~~~%%#~~###%~~~~~~~~~~~~~~~~~~~~~ +~~~~####^^##%%%~~~~~~~~~.~~..~~~%%%%^~~~%%%%~~~~~~~~~~~~~~~~~~~~ +~~~~###~~~~~.~~~~~~~~~~~~~~##~~%%%%%^~%%%%%%~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~..~~~~~~~~~~~##%%%%%%%.~~%%%%%.~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~..~~~~~~~~~~~###%%%%~~~.~~~~%%..%%~~~~~~^~~~~~~~~~~~ +~~~~~~~~~~~%%%%~~~....~~~~~%%%%~~~~~~~~~....~%%~~~^^^#~~~~~~~~~~ +~~~~~~~~~~~%%%%%~~.....~~~~%%%~~~~~~~~~^....~~%~~##^##~~~~~~~~~~ +~~~~~~~~~~##%%%%~......~~...%~~~~~~~~~~^~..~~#%~%#####%~~~~~~~~~ +~~~~~...##~#%%%%....^^~~~...~~~~~~~~~~~~~~~~##%.%###~%%%~~~~~~~~ +~~~~~~^^..~~~~%%....^^~~~~~~~~~~~~~~~~~~~~~#^^..####..%%~~~~~~~~ +~~~~~~^^^^%%~~~%...####~~~~~~~~~~~~~~~~~~~~##....###....~^^...~~ +~~~~~~^^^%%%~~~~~~#####.~~~~~~~~~~~~~~~~~~~~#....###%%..###..~~~ +~~~~...#%%%%%%%~~~####...~~~~~~~~~~~~~~~~~~~...~###%%%%.###..~~~ +##....~~%%%%%%%~~~......~~~~~~~~~~~~~~~~~~~~~..~~##%%%%~##..%... +......~~####%%~~~~.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%~~~~..%%.. +...%..#######~~~~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%. +..%%%#########~~~~~##%~~~~~~..#%~~~~~~~~~~~~~~~~~~~~~~~~~~~##%%. +~~~~~~~########~~%%%###~~~~~####~~~~~~~~~~~~~~~~~~~~~~~~~~~~##~~ +~~~~~~~~###.##~~~%%%##^~~~~~####~~~~~~~~~~~~~~~~....~~~~~~~~~~~~ +~~~~~~~~~##^^~~~%%%%..^^~~~~####~~~~~~~~~~~~~~~#....#~~~~~~~~~~~ +~~..~~~~~~~~~~~~%%%%....~~~~%###~~~~~~~~~~~~~~~%...~~~~~~~~~~~~~ +~~~~..~~~~~~~~~~~~%%.....#%%%%%%^^%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~%%...##%%%%%%^^%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~^%..~~~.^^^..^^%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~^~~~~~~~^^^..^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~%.%.%.....^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~%%.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~....%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~....%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%%%%%~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%..~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~%^^%%~~~~~~%%%%......~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~%%%^%%~~~~~~%%%%.....~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~####~~~~~~~~......~~~~~~~~..~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~######~~~~~~~~~~~~..%~~~~~~~...~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~%%%%%#######~~~~~~~~~~~~~%%~~~~~~..~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~%%%###^####~~~~~~~~~~~~^^^.%%~~.~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~####%###~~~~####~~~~^^^^%%%%..~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~####%%%%%%~~###~~~~~^^^^%%%%.~~~~~~~~~~~~~~~~~~~ +~~~~~~~~^^^~~~~.####%%%%%%%..#~~~~~^^^^^^%%%~~~~~~~~~~~~~~~~~~~~ +~~~~....^^^~~~..####...%%%%...~~~~~^.^^^^%%~~~~~~~~~~~~~~~~~~~~~ +~~~~.....~~~~~...####...##.....~~~~~^^^.#~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~...~~~~^##...##%%%%##.....~~~~~^^..~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~..~~~~^^##..~~%%%%##...###~~~~~^..~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~..~~~~^^##.~~~%%%%~~..#####~~~~...~~~~#~~~~~~~~~~~~~~~~~~~ +~~~~###.~~~####%%%~~~~~~~~~~%###%%..#~~.....#~~~~~~~~~~~~~~~~~~~ +~~~~####~~~####%%%%~~~~~~~~~%###%^^^#~~~#...~~~~~~~~~~~~~~~~~~~~ +~~~~####^^..###~%%~~~~~~....%###~%^^#~~~##..~~~~~~~~~~~~~~~~~~~~ +~~~~~###^^..^^^~~~~~##~.....%%#~~~^^^^~###%%~~~~~~~~~~~~~~~~~~~~ +~~~~~~^^^~~..^~~~~%%~##.~~~.%%%~~~~^^..#~~~.###~~~~~~~~~~~~~~~~~ +~~~~~~^^~~~..~~~~~~%~~~~~~~..%~~~~~^^...~~~.###~~~~~~~~~~~~~~~~~ +~~~~~~~^~~~~.~~~~~~%%~~~~~~~.~~~~~~^^^.~~~~~##~~~~~~~~~~~~~~~~~~ +~#~~~~~~~~~~##~~~~~~~~~~~~~~~.~.~~%%^^^~~~~~##~~~~~~~~~~~~~~~~~~ +###~~~~~~~~~~~^~.~~~~~~~~~~^.....%%%^^^~~~~~~~~~~~~~~~~~~~~~~%%% +%#.....%~~~~~~~...~~~~~~~~~~~~..^^%%^^^~~~~~~~~~~~~~~~~~~~~~~~%% +....%%%%~~~~~~~~...%~~~~~~~~^~.^^^^%^^~~~~~~~~~~~~~~~~~~~~~~~~~% +~~~~~~~%###~~~~~...%%~~~~~~~###^^^~~%~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~.###..~~~~...%%%~~~~#####~~~~~#.~##~~~~~~~~~~~~~~~~~~~~.~ +~~~~..........~~~~~~%%%~~~%~###~~~~~##..###~~~~~~~~~~~~~~~~~%... +%%............~~~~~~%%%%~%%%~~~~~~~~##..##..~~~~~~~~~~~~~~~%%%%% +%%..%%..~~...~~~~~~~~%%%%%%%~~~~~~~~###.#...~~~~~~~~~~~~~~~%%%%% diff --git a/xtrn/war/worlds/earth/game.orig.json b/xtrn/war/worlds/earth/game.orig.json new file mode 100644 index 0000000000000000000000000000000000000000..aaf8360c13a3c1cc1039e23726051b58fa9313ce --- /dev/null +++ b/xtrn/war/worlds/earth/game.orig.json @@ -0,0 +1,2047 @@ +{ + "ncnt": 1, + "nations": [ + { + "name": "Overlord", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "Rogue", + "uid": -1, + "city": 0, + "mark": "?", + "idle_turns": 0 + } + ], + "cities": [ + { + "name": "Indigo", + "cluster": 1, + "nation": 0, + "r": 5, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lavender", + "cluster": 1, + "nation": 0, + "r": 7, + "c": 2, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Crimson", + "cluster": 1, + "nation": 0, + "r": 3, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Saffron", + "cluster": 1, + "nation": 0, + "r": 9, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 7, + 0, + 0, + -1 + ] + }, + { + "name": "Verdant", + "cluster": 1, + "nation": 0, + "r": 6, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Metropolis", + "cluster": 2, + "nation": 0, + "r": 28, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gotham", + "cluster": 2, + "nation": 0, + "r": 29, + "c": 5, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 10, + 9, + 0, + -1 + ] + }, + { + "name": "Keystone City", + "cluster": 2, + "nation": 0, + "r": 31, + "c": 8, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Central City", + "cluster": 2, + "nation": 0, + "r": 35, + "c": 9, + "prod_type": 0, + "turns_left": 5, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Heliochrysum", + "cluster": 3, + "nation": 0, + "r": 32, + "c": 24, + "prod_type": 0, + "turns_left": 3, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Portulaca", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 29, + "prod_type": 0, + "turns_left": 3, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gaillardia", + "cluster": 3, + "nation": 0, + "r": 38, + "c": 24, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Coreopsis", + "cluster": 3, + "nation": 0, + "r": 36, + "c": 21, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Delphineum", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 19, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ruby", + "cluster": 4, + "nation": 0, + "r": 14, + "c": 23, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Amber", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 7, + 0, + 0, + -1 + ] + }, + { + "name": "Emerald", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 28, + "prod_type": 0, + "turns_left": 5, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Diamond", + "cluster": 4, + "nation": 0, + "r": 18, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sapphire", + "cluster": 4, + "nation": 0, + "r": 19, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Zhentil Keep", + "cluster": 5, + "nation": 0, + "r": 40, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Shadowdale", + "cluster": 5, + "nation": 0, + "r": 42, + "c": 20, + "prod_type": 0, + "turns_left": 5, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silverdale", + "cluster": 5, + "nation": 0, + "r": 45, + "c": 22, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Battledale", + "cluster": 5, + "nation": 0, + "r": 48, + "c": 24, + "prod_type": 0, + "turns_left": 3, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Dread", + "cluster": 6, + "nation": 0, + "r": 38, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 4, + -1, + -1 + ], + "instance": [ + 9, + 7, + -1, + -1 + ] + }, + { + "name": "Doom", + "cluster": 6, + "nation": 0, + "r": 39, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 7, + 15, + -1 + ], + "times": [ + 1, + 4, + 6, + -1 + ], + "instance": [ + 17, + 8, + 0, + -1 + ] + }, + { + "name": "Despair", + "cluster": 6, + "nation": 0, + "r": 42, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 9, + 9, + -1, + -1 + ] + }, + { + "name": "Death", + "cluster": 6, + "nation": 0, + "r": 43, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 31, + 0, + -1, + -1 + ] + }, + { + "name": "Agony", + "cluster": 6, + "nation": 0, + "r": 45, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 13, + 15, + -1 + ], + "times": [ + 1, + 3, + 6, + -1 + ], + "instance": [ + 30, + 0, + 0, + -1 + ] + }, + { + "name": "Gloom", + "cluster": 6, + "nation": 0, + "r": 49, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 12, + 0, + -1, + -1 + ] + }, + { + "name": "Iron", + "cluster": 7, + "nation": 0, + "r": 55, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gold", + "cluster": 7, + "nation": 0, + "r": 54, + "c": 14, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 20 + ], + "times": [ + 1, + 2, + 3, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silver", + "cluster": 7, + "nation": 0, + "r": 58, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Tin", + "cluster": 7, + "nation": 0, + "r": 57, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 9, + 0, + 0, + -1 + ] + }, + { + "name": "Lead", + "cluster": 7, + "nation": 0, + "r": 51, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 9, + 0, + 0, + -1 + ] + }, + { + "name": "Nyarlathotep", + "cluster": 8, + "nation": 0, + "r": 34, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 7, + 0, + -1, + -1 + ] + }, + { + "name": "Yogsothoth", + "cluster": 8, + "nation": 0, + "r": 30, + "c": 52, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 7, + 0, + -1, + -1 + ] + }, + { + "name": "Cthulhu", + "cluster": 8, + "nation": 0, + "r": 31, + "c": 57, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 7, + 0, + -1, + -1 + ] + }, + { + "name": "Hastor", + "cluster": 8, + "nation": 0, + "r": 28, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 7, + 0, + -1, + -1 + ] + }, + { + "name": "Olan", + "cluster": 9, + "nation": 0, + "r": 42, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 10, + 0, + -1, + -1 + ] + }, + { + "name": "Kaxandar", + "cluster": 9, + "nation": 0, + "r": 40, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 11, + 0, + -1, + -1 + ] + }, + { + "name": "Torgar", + "cluster": 9, + "nation": 0, + "r": 46, + "c": 60, + "prod_type": 0, + "turns_left": 2, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 14, + 1, + -1, + -1 + ] + }, + { + "name": "Arras Charka", + "cluster": 10, + "nation": 0, + "r": 18, + "c": 43, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 21, + -1 + ], + "times": [ + 1, + 2, + 6, + -1 + ], + "instance": [ + 7, + 0, + 0, + -1 + ] + }, + { + "name": "Derzon", + "cluster": 10, + "nation": 0, + "r": 17, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 9, + 0, + 0, + -1 + ] + }, + { + "name": "Ekosiak", + "cluster": 10, + "nation": 0, + "r": 20, + "c": 47, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ish-Tako", + "cluster": 10, + "nation": 0, + "r": 16, + "c": 46, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Chishata", + "cluster": 10, + "nation": 0, + "r": 23, + "c": 50, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Qualinesti", + "cluster": 11, + "nation": 0, + "r": 53, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 20 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sylvanesti", + "cluster": 11, + "nation": 0, + "r": 56, + "c": 55, + "prod_type": 0, + "turns_left": 3, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Rathwynn", + "cluster": 11, + "nation": 0, + "r": 62, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 17, + 5, + 11, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 20, + 0, + 0, + -1 + ] + }, + { + "name": "Caledon", + "cluster": 11, + "nation": 0, + "r": 60, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Alfheim", + "cluster": 11, + "nation": 0, + "r": 58, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Atlantis", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 41, + "prod_type": 0, + "turns_left": 2, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 6, + 0, + 3, + -1 + ] + }, + { + "name": "Mu", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 37, + "prod_type": 0, + "turns_left": 3, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 7, + 0, + 3, + -1 + ] + }, + { + "name": "Poseidon", + "cluster": 12, + "nation": 0, + "r": 46, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 7, + 0, + 3, + -1 + ] + }, + { + "name": "Neptune", + "cluster": 12, + "nation": 0, + "r": 44, + "c": 38, + "prod_type": 0, + "turns_left": 8, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 7, + 0, + 4, + -1 + ] + } + ], + "ttypes": [ + { + "name": "Lt. Infantry", + "combat": 2, + "move_rate": 6, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Hv. Infantry", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Lt. Cavalry", + "combat": 2, + "move_rate": 12, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Hv. Cavalry", + "combat": 3, + "move_rate": 8, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Dwarf Legion", + "combat": 3, + "move_rate": 4, + "move_tbl": 2, + "special_mv": 0 + }, + { + "name": "Elven Archers", + "combat": 3, + "move_rate": 6, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Zombie Legion", + "combat": 3, + "move_rate": 3, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Wraith Horde", + "combat": 4, + "move_rate": 6, + "move_tbl": 4, + "special_mv": 0 + }, + { + "name": "Elite Troopers", + "combat": 4, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Gug", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Dwarf Miners", + "combat": 4, + "move_rate": 4, + "move_tbl": 5, + "special_mv": 0 + }, + { + "name": "Scout", + "combat": 1, + "move_rate": 8, + "move_tbl": 6, + "special_mv": 0 + }, + { + "name": "Byakhee", + "combat": 2, + "move_rate": 7, + "move_tbl": 4, + "special_mv": 2 + }, + { + "name": "Ghouls", + "combat": 3, + "move_rate": 5, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Navy", + "combat": 2, + "move_rate": 10, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Undead Navy", + "combat": 3, + "move_rate": 8, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Clipper", + "combat": 2, + "move_rate": 12, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Infantry", + "combat": 2, + "move_rate": 8, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Mermen", + "combat": 2, + "move_rate": 6, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Tritons", + "combat": 3, + "move_rate": 4, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Pegasus", + "combat": 2, + "move_rate": 10, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Hippogryff", + "combat": 3, + "move_rate": 8, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Leviathan", + "combat": 5, + "move_rate": 4, + "move_tbl": 8, + "special_mv": 1 + } + ], + "armies": [], + "move_table": [ + { + "cost": [ + 0, + 1, + 2, + 2, + 4 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 3, + 0 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 2, + 4 + ] + }, + { + "cost": [ + 1, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 2, + 3 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 1, + 0, + 0, + 0, + 0 + ] + }, + { + "cost": [ + 1, + 1, + 2, + 3, + 4 + ] + } + ], + "world": "Solomoriah's World", + "gen": 0 +} diff --git a/xtrn/war/worlds/earth/map b/xtrn/war/worlds/earth/map new file mode 100644 index 0000000000000000000000000000000000000000..4cf7706ebde5168af702c1b69d5f50df950bc720 --- /dev/null +++ b/xtrn/war/worlds/earth/map @@ -0,0 +1,66 @@ +M 64 64 + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~%%....%~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~~~^...~~~~.~~~~~~~~ +~~~~~~~~~~.^~%^~~~~~~~~~~~~~~~~~~~~~~~~~%.~~~~^.^^^~~~~^%~~~~~~~ +~~~~~~~~^.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.^.^^.~~~~~~~~~~~~~ +~~~~~~~~.^.~~~~.~~~~~~~~~~~~~~~~~~~~~~~~~~~.~^^^^^^^..~~~~~~~~~~ +~~~~~~~~~~##~.~^^%~~~~~~~~~~~~~~~~~%~~~~~~.^^..^^..^^^^^^^.~~~%~ +~~.^~~~~~~...%~^#.~~~~~~~~~~~~~~~~%%%~~~~~.^^..^^.^.^^^^^^^~~~~~ +~.....^^....~.%%~^%~~~~~~~~~~~~~~^^^#^%.^^^#^^^.....^.^^^^^^^^#~ +~~.....^......^%~..~~~~~~~~~~~~~~^^^^#^^^^^.^^^....^^^^.^^^^^.^. +~#^^^.......^^.^~%.~~~~~~~~~~~~~%^.^^.^^^^^^^^^^....^^..^^..^^.^ +~~^.....^^..^^%%~..~~~~~~~~~~~~%##.##^^^^#^^^^..^..^^^^.^^.^^^~~ +~^^.....^....^~~~^~~~~~~~~~~~%~##^##.^^^^^^^^^^......^^.^^..^~~~ +~.^.%.....^...~~~^~~~~~~~~~~~%~%##^.^#^^.^^^^^^.....^.^.^^~~.~~~ +~~.%~~.......#~~~.^.~~~~~~~~~~~..%^#^##^.^^^^^^^.^..^...~~~^~~~~ +~~~~~~~#.....^^.....~~~~~~~~~~..#.####^^.^#^^^........^~~~^.~~~~ +~~~~~~~~.......^^...%~~~~~~~~.%######^^^^.^.^^........^#~~.~~~~~ +~~~~~~~~.......^^.^..~~~~~~~~^####^^^##^.^...^.......^^^~~~~~~~~ +~~~~~~~~^^.....^.^^.~~~~~~~~~~######.#^.^^^..^.......^^~~~~~~~~~ +~~~~~~~~.^.......##~~~~~~~~~~~######~~~...^..........^%~~~~~~~~~ +~~~~~~~~.^....^.^%~~~~~~~~~~~^%~~~##~~#.##.^.........%~~~~~~~~~~ +~~~~~~~~^^....^^^~~~~~~~~~~~~~~~~~~~.^..##^^...#...^.~~#~~~~~~~~ +~~~~~~~~~%^..^^^~~~~~~~~~~~~~^^#~~~~~.#..^.#.####..^~~##~~~~~~~~ +~~~~~~~~~~...^^^~~~~~~~~~~~~~#.#^%~~~.^^.^^^^###...^.~#~~~~~~~~~ +~~~~~~~~~~~^^~~~~~~~~~~~~~~~#^^^^.^^^^~^#~~.^###..^.~~~~~~~~~~~~ +~~~~~~~~~~~^.~~~~~~~~~~~~~~~#^^^^^^^^^~~##~..#^^..^.~~~~~~~~~~~~ +~~~~~~~~~~~~.~~~~~~~~~~~~~~%#^^^^^^.^^.~##~^^^~#^^^#~~~~~~~~~~~~ +~~~~~~~~~~~~~%#~~~~~~~~~~~~##^^^^^..^#^~~~~~.~~~#####~~~~~~~~~~~ +~~~~~~~~~~~~~~~%~~%~~~~~~~~~#^#^^...^^^~~~~~%~~%.#%~#~~~~~~~~~~~ +~~~~~~~~~~~~~~~~%^^#~~~~~~~~####^^^^..^~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~^.^#^~%~~~~~~~~~##^.^^%~~~~~~~~~~.^#~~~~~~~~~~~~ +~~~~~~~~~~~~~~~#^^^^##.~~~~~~~~~###..#~~~~~~~~~~%.~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~#^##^^##.%~~~~~~~~%##^.#~~~~~~~~~~~~~.~~~~~~~~~~~~ +~~~~~~~~~~~~~~##..^#.^^^~~~~~~~~~^^^.^~~~~~~~~~~~~%~%~~.~~~~~~~~ +~~~~~~~~~~~~~~..###^##^~~~~~~~~~~^.^^%~~#~~~~~~~~~~~~~#~~~~~~~~~ +~~~~~~~~~~~~~~~#%%#^#^#~~~~~~~~~~.^^^%~##~~~~~~~~~~~.^^.~~~~~~~~ +~~~~~~~~~~~~~~~%%%^^^#%~~~~~~~~~~^.^#~~#~~~~~~~~~~~.^^^#.~~~~~~~ +~~~~~~~~~~~~~~~%%%###%~~~~~~~~~~%#^##~~~~~~~~~~~~~~#######~~~~~~ +~~~~~~~~~~~~~~~%%%###~~~~~~~~~~~~%^.#~~~~~~~~~~~~~~^####^#~~~~~~ +~~~~~~~~~~~~~~~%#####~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~%%#%###~~~~~~ +~~~~~~~~~~~~~~~%%%^#~~~~~~~~~~~~~~%~~~~~~~~~~~~~~~~%~#~#%%~~~~~~ +~~~~~~~~~~~~~~~%%#^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~~~#~~ +~~~~~~~~~~~~~~~~%##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~ +~~~~~~~~~~~~~~~~~#^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/xtrn/war/worlds/solomoriah/game.orig.json b/xtrn/war/worlds/solomoriah/game.orig.json new file mode 100644 index 0000000000000000000000000000000000000000..5ea6525e0b91f82be3883ca04522e6299a97c9e8 --- /dev/null +++ b/xtrn/war/worlds/solomoriah/game.orig.json @@ -0,0 +1,2047 @@ +{ + "ncnt": 1, + "nations": [ + { + "name": "Overlord", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "Rogue", + "uid": -1, + "city": 0, + "mark": "?", + "idle_turns": 0 + } + ], + "cities": [ + { + "name": "Indigo", + "cluster": 1, + "nation": 0, + "r": 5, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lavender", + "cluster": 1, + "nation": 0, + "r": 7, + "c": 2, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Crimson", + "cluster": 1, + "nation": 0, + "r": 3, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Saffron", + "cluster": 1, + "nation": 0, + "r": 9, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Verdant", + "cluster": 1, + "nation": 0, + "r": 6, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Metropolis", + "cluster": 2, + "nation": 0, + "r": 28, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gotham", + "cluster": 2, + "nation": 0, + "r": 29, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Keystone City", + "cluster": 2, + "nation": 0, + "r": 31, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Central City", + "cluster": 2, + "nation": 0, + "r": 35, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Heliochrysum", + "cluster": 3, + "nation": 0, + "r": 32, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Portulaca", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 29, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gaillardia", + "cluster": 3, + "nation": 0, + "r": 38, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Coreopsis", + "cluster": 3, + "nation": 0, + "r": 36, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Delphineum", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 19, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ruby", + "cluster": 4, + "nation": 0, + "r": 14, + "c": 23, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Amber", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Emerald", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 28, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Diamond", + "cluster": 4, + "nation": 0, + "r": 18, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sapphire", + "cluster": 4, + "nation": 0, + "r": 19, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Zhentil Keep", + "cluster": 5, + "nation": 0, + "r": 40, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Shadowdale", + "cluster": 5, + "nation": 0, + "r": 42, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silverdale", + "cluster": 5, + "nation": 0, + "r": 45, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Battledale", + "cluster": 5, + "nation": 0, + "r": 48, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Dread", + "cluster": 6, + "nation": 0, + "r": 38, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 4, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Doom", + "cluster": 6, + "nation": 0, + "r": 39, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 7, + 15, + -1 + ], + "times": [ + 1, + 4, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Despair", + "cluster": 6, + "nation": 0, + "r": 42, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Death", + "cluster": 6, + "nation": 0, + "r": 43, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Agony", + "cluster": 6, + "nation": 0, + "r": 45, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 13, + 15, + -1 + ], + "times": [ + 1, + 3, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Gloom", + "cluster": 6, + "nation": 0, + "r": 49, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Iron", + "cluster": 7, + "nation": 0, + "r": 55, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gold", + "cluster": 7, + "nation": 0, + "r": 54, + "c": 14, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 20 + ], + "times": [ + 1, + 2, + 3, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silver", + "cluster": 7, + "nation": 0, + "r": 58, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Tin", + "cluster": 7, + "nation": 0, + "r": 57, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Lead", + "cluster": 7, + "nation": 0, + "r": 51, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Nyarlathotep", + "cluster": 8, + "nation": 0, + "r": 34, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Yogsothoth", + "cluster": 8, + "nation": 0, + "r": 30, + "c": 52, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Cthulhu", + "cluster": 8, + "nation": 0, + "r": 31, + "c": 57, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Hastor", + "cluster": 8, + "nation": 0, + "r": 28, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Olan", + "cluster": 9, + "nation": 0, + "r": 42, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Kaxandar", + "cluster": 9, + "nation": 0, + "r": 40, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Torgar", + "cluster": 9, + "nation": 0, + "r": 46, + "c": 60, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + -1, + -1 + ] + }, + { + "name": "Arras Charka", + "cluster": 10, + "nation": 0, + "r": 18, + "c": 43, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 21, + -1 + ], + "times": [ + 1, + 2, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Derzon", + "cluster": 10, + "nation": 0, + "r": 17, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Ekosiak", + "cluster": 10, + "nation": 0, + "r": 20, + "c": 47, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ish-Tako", + "cluster": 10, + "nation": 0, + "r": 16, + "c": 46, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Chishata", + "cluster": 10, + "nation": 0, + "r": 23, + "c": 50, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Qualinesti", + "cluster": 11, + "nation": 0, + "r": 53, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 20 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sylvanesti", + "cluster": 11, + "nation": 0, + "r": 56, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Rathwynn", + "cluster": 11, + "nation": 0, + "r": 62, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 17, + 5, + 11, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Caledon", + "cluster": 11, + "nation": 0, + "r": 60, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Alfheim", + "cluster": 11, + "nation": 0, + "r": 58, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Atlantis", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 41, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Mu", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Poseidon", + "cluster": 12, + "nation": 0, + "r": 46, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + }, + { + "name": "Neptune", + "cluster": 12, + "nation": 0, + "r": 44, + "c": 38, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + -1 + ] + } + ], + "ttypes": [ + { + "name": "Lt. Infantry", + "combat": 2, + "move_rate": 6, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Hv. Infantry", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Lt. Cavalry", + "combat": 2, + "move_rate": 12, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Hv. Cavalry", + "combat": 3, + "move_rate": 8, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Dwarf Legion", + "combat": 3, + "move_rate": 4, + "move_tbl": 2, + "special_mv": 0 + }, + { + "name": "Elven Archers", + "combat": 3, + "move_rate": 6, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Zombie Legion", + "combat": 3, + "move_rate": 3, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Wraith Horde", + "combat": 4, + "move_rate": 6, + "move_tbl": 4, + "special_mv": 0 + }, + { + "name": "Elite Troopers", + "combat": 4, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Gug", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Dwarf Miners", + "combat": 4, + "move_rate": 4, + "move_tbl": 5, + "special_mv": 0 + }, + { + "name": "Scout", + "combat": 1, + "move_rate": 8, + "move_tbl": 6, + "special_mv": 0 + }, + { + "name": "Byakhee", + "combat": 2, + "move_rate": 7, + "move_tbl": 4, + "special_mv": 2 + }, + { + "name": "Ghouls", + "combat": 3, + "move_rate": 5, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Navy", + "combat": 2, + "move_rate": 10, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Undead Navy", + "combat": 3, + "move_rate": 8, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Clipper", + "combat": 2, + "move_rate": 12, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Infantry", + "combat": 2, + "move_rate": 8, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Mermen", + "combat": 2, + "move_rate": 6, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Tritons", + "combat": 3, + "move_rate": 4, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Pegasus", + "combat": 2, + "move_rate": 10, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Hippogryff", + "combat": 3, + "move_rate": 8, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Leviathan", + "combat": 5, + "move_rate": 4, + "move_tbl": 8, + "special_mv": 1 + } + ], + "armies": [], + "move_table": [ + { + "cost": [ + 0, + 1, + 2, + 2, + 4 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 3, + 0 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 2, + 4 + ] + }, + { + "cost": [ + 1, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 2, + 3 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 1, + 0, + 0, + 0, + 0 + ] + }, + { + "cost": [ + 1, + 1, + 2, + 3, + 4 + ] + } + ], + "world": "Solomoriah's World", + "gen": 0 +} \ No newline at end of file diff --git a/xtrn/war/worlds/solomoriah/map b/xtrn/war/worlds/solomoriah/map new file mode 100644 index 0000000000000000000000000000000000000000..c90877c521388a22c357fe91db72e85a5862cd23 --- /dev/null +++ b/xtrn/war/worlds/solomoriah/map @@ -0,0 +1,66 @@ +M 64 64 + +....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%% +....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% +....%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~. +....%.%.%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^. +..^^^~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^ +..^^^.~~~..%^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%^^ +%%%%%%##...%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%^^ +%%%%%%#.....%%~~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%^^ +###%~~~~....%%%%~~~~~~~~~~~~..~~~~~~~~~~~~~~~...%~~~~~~~~~~~~~~~ +####~~~~^^..%%%%~~~^^##~~~~~~~~~~~~~~~~~~~~#....#~~~~~~~~~~~~~~~ +####~~~~~^##%%%~~~##.###~~~~~~~~~~~~~~~~~~~~....~~~~~~~~~~~~~~~~ +####~~~~~###%%%~~########~~~~~~~~~##~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%#..~~~~~~%##~~~~~#########%%%...%%##~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~...~~~~~~#######..%....%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~.....~~~~%%####~~........%%..~~~~%%~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~......~~~%%%%%%%~~....##...%..##~%%%%##~~..~~~~~~~~~~~~~ +~~~~~~~...####~~~%%%%%%%#...~~~~~~~..###.%%%%###~...~~~~~~~~~~~~ +~~~~~~~~.#####~~~~~~%%%^^^~~~~~~~~~..###..%%###....#~~~~~~~~~~~~ +~~~~~~~~~####...%~~~%%^^^^~~~~~~~~...^^~....###....##~~~~~~~~~~~ +~~~~~~~~~~^^....%%~~~~..^^~~~~~~~~~~~~~~%%..####..^^#~~~~~~~~~~~ +~~~~...~~~^^....%%%%#~##...~~~~~~~~~~~~~%%%~###%.%##~~~~~~~~~~~~ +~~~%...~~......~%%%%##~~~~~~~~~~~~~~~~~~~%#####%~%#~~..~^~~~~~~~ +~~%%%~~~~.....~~%%%%%~~~~~~~~~~~~~~~~~~~~~##^##~~%~~....^~~~~~~~ +~%%%%~~~~~....~~~%%%%~~~~~~~~~~~~~~~~~~~~~#^^^~~~%%~....~~~~~~~~ +%%%%###~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~%%..%%~~~~.~~~ +%%%%##~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%%%~~.%%% +%~~##~~~~~~~~~~~~~~.~~~~~###~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%~^%%%% +~~~..~~.~~~~~~~~~%%%##^^####~~~~~~~~~~~~~~~~~~~~~~~~%%%%~~~^%%%% +~~.......##~%%%%%%%##^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%###~~#%%~~ +~^^......###%%%%%~~##^~~~~~~~~..~~~~~~~~~~~~~~~~~.~~%%%%####%%~~ +^^^^....%###%%%%~~~##^~~~~~~~...~~~~~~~~~~~~~~~~~.#~%%%%#####%~~ +^^..%%%%.%#~~%%%~~~#^^~~~%%%~...%%%~~~~~~~~~~~~~~.~#%%%%%####~~~ +~~~~%%%%%%%~~~~~~~~...~~..%%..%%%%%%%~~~~~~~~~~~~~~~...#.###~~~~ +~~~~%%%~%%%%~~~~~~............%%%%%%%~~~~~~~~~~~~~~~..##..##~~~~ +~###~%~~~%%%~~~~~~..........~~~~...%~~~~~~~~~~~~~~~~~###..##~~~~ +#####~~~~%%%...~~~~..###.~~~~~~~~.~~~~~~~~~~~~~~~~~~~~##~.#~~~~~ +^###~~~~~~~%%...~~~~~###%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~^^ +^.~^~~~~~~~~%...~~~~~~~~%%%%....%~~~~~~~~~~~~~~~~~~~~~~~~~^^%^^^ +..~~~~~~~~~~~~...~~~~~~~%.....#%%%~~~~~~~~~~~~~~~~~~~~~~~^^^%%^^ +....^~~~~~~~~~~.~^~~~~~~~~~~~###%%%~~~~~~~~~~~~~~~~~~~~~~^^^%%%. +.~.~~~~~~~~~~~~~~~##~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~##~~~~~^^^%%~~ +~~~.~~~~~~~%%~~~~~~.~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~##~~~~~.^^^~~~ +~~%..~~~~~~~%~~~~~~..~~~^^~~~~~~~~~~~~~~~~~~~~~~~###.~~~...^^~~~ +~%%%.~~~.##~%%~~~~^..~~^^^~~~~~~~~~~~~~~~~~~~~~~~###.~~~#..^^~~~ +~#%%.....~##~~~~~^^^..^^###~~~~~~~~~~~~~~~~~~~~~~~~~%%###~^^^^~~ +###%....~~~~~~%%~###..^^####~~~~~~~~~~~~~~~~~~~~~~~~..##~~~#^^%~ +###%~~~~~~~~~%%%%####~~~####~~~~~~~~~~~~~~~~~~~~~~~~...#~~~#^^^% +###%~~~~~~~~~~%%%####~~~.###~~~~~~~~~~~~~~~~~~~~~~~#.....~~#..%% +####..~~%%%%~~~.##^^~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~...~~~~# +###...##%%%%~~..##^^~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...~~~~~ +~.....##%%%%##...##^~~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~~....~~~~ +~.....##...####...~~~~~.....~~~~~~~~~~~~~~~~~~~~~~~~~~~#....~~~~ +~~...%%%%...####..~~~^^^....~~~~~~~~~~~~~~~~~~~~~~~~~%%%#^^.~~~~ +~~#..%%%%%%%####.~~~~^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%^^^~~~~ +~###~~%%%%%%####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%%%^^^~~~~ +####~~~~###%####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..%%%%.^^^~~~~ +~~~~~~~~####^###%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~%%..^^~~~~ +~~~~~~~~~#######%%%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~%%~~~~ +~~~~~~~~~~######~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...~~~~~~~%..~~ +..~~~~~~~~####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~~~.... +~~~~~~%%^%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.....%%%% +~~~~~~%%^^%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~......%%%% +%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..%%%%%%% +%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%%% diff --git a/xtrn/war/worlds/solomoriah/map.png b/xtrn/war/worlds/solomoriah/map.png new file mode 100644 index 0000000000000000000000000000000000000000..97d8148bd56a8e62ae23d7d697b284dfd9d26d40 Binary files /dev/null and b/xtrn/war/worlds/solomoriah/map.png differ diff --git a/xtrn/war/worlds/spacewar/game.orig.json b/xtrn/war/worlds/spacewar/game.orig.json new file mode 100644 index 0000000000000000000000000000000000000000..71dbc29eba88287b29c282f38a29b42bc1d843a1 --- /dev/null +++ b/xtrn/war/worlds/spacewar/game.orig.json @@ -0,0 +1,1612 @@ +{ + "ncnt": 1, + "nations": [ + { + "name": "Overlord", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "Rogue", + "uid": -1, + "city": 0, + "mark": "?", + "idle_turns": 0 + } + ], + "cities": [ + { + "name": "Mercury", + "cluster": 1, + "nation": 0, + "r": 4, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Venus", + "cluster": 1, + "nation": 0, + "r": 4, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Earth", + "cluster": 1, + "nation": 0, + "r": 5, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Mars", + "cluster": 1, + "nation": 0, + "r": 9, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Jupiter", + "cluster": 1, + "nation": 0, + "r": 0, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Jinx", + "cluster": 2, + "nation": 0, + "r": 4, + "c": 56, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Wemadeit", + "cluster": 2, + "nation": 0, + "r": 9, + "c": 50, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Wunderland", + "cluster": 2, + "nation": 0, + "r": 8, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Shaster", + "cluster": 2, + "nation": 0, + "r": 5, + "c": 47, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Crashland", + "cluster": 2, + "nation": 0, + "r": 2, + "c": 52, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Vulcan", + "cluster": 3, + "nation": 0, + "r": 13, + "c": 15, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Qo'noS", + "cluster": 3, + "nation": 0, + "r": 9, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Andoria", + "cluster": 3, + "nation": 0, + "r": 14, + "c": 19, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Trill", + "cluster": 3, + "nation": 0, + "r": 13, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Bajor", + "cluster": 3, + "nation": 0, + "r": 7, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Romulus", + "cluster": 4, + "nation": 0, + "r": 61, + "c": 17, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Remus", + "cluster": 4, + "nation": 0, + "r": 59, + "c": 19, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Cardassia", + "cluster": 4, + "nation": 0, + "r": 63, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Tholia", + "cluster": 4, + "nation": 0, + "r": 59, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Ceti Alpha V", + "cluster": 4, + "nation": 0, + "r": 55, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Unimatrix 01", + "cluster": 5, + "nation": 0, + "r": 44, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Unimatrix 02", + "cluster": 5, + "nation": 0, + "r": 40, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Unimatrix 03", + "cluster": 5, + "nation": 0, + "r": 45, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Unimatrix 04", + "cluster": 5, + "nation": 0, + "r": 43, + "c": 16, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Unimatrix 05", + "cluster": 5, + "nation": 0, + "r": 48, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Centauri", + "cluster": 6, + "nation": 0, + "r": 56, + "c": 61, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Narn", + "cluster": 6, + "nation": 0, + "r": 52, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Minbar", + "cluster": 6, + "nation": 0, + "r": 57, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Epsilon 3", + "cluster": 6, + "nation": 0, + "r": 60, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Vorlon", + "cluster": 6, + "nation": 0, + "r": 53, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Coruscant", + "cluster": 7, + "nation": 0, + "r": 20, + "c": 44, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Naboo", + "cluster": 7, + "nation": 0, + "r": 25, + "c": 38, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Kamino", + "cluster": 7, + "nation": 0, + "r": 21, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Geonosis", + "cluster": 7, + "nation": 0, + "r": 24, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Alderaan", + "cluster": 7, + "nation": 0, + "r": 18, + "c": 41, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Tattooine", + "cluster": 8, + "nation": 0, + "r": 27, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Dagobah", + "cluster": 8, + "nation": 0, + "r": 23, + "c": 53, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Hoth", + "cluster": 8, + "nation": 0, + "r": 22, + "c": 56, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Yavin", + "cluster": 8, + "nation": 0, + "r": 19, + "c": 52, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + }, + { + "name": "Endor", + "cluster": 8, + "nation": 0, + "r": 18, + "c": 56, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 12, + 0, + 0, + 0 + ] + } + ], + "ttypes": [ + { + "name": "Lt. Infantry", + "combat": 2, + "move_rate": 6, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Hv. Infantry", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Lt. Cavalry", + "combat": 2, + "move_rate": 12, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Hv. Cavalry", + "combat": 3, + "move_rate": 8, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Dwarf Legion", + "combat": 3, + "move_rate": 4, + "move_tbl": 2, + "special_mv": 0 + }, + { + "name": "Elven Archers", + "combat": 3, + "move_rate": 6, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Zombie Legion", + "combat": 3, + "move_rate": 3, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Wraith Horde", + "combat": 4, + "move_rate": 6, + "move_tbl": 4, + "special_mv": 0 + }, + { + "name": "Elite Troopers", + "combat": 4, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Gug", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Dwarf Miners", + "combat": 4, + "move_rate": 4, + "move_tbl": 5, + "special_mv": 0 + }, + { + "name": "Scout", + "combat": 1, + "move_rate": 8, + "move_tbl": 6, + "special_mv": 0 + }, + { + "name": "Byakhee", + "combat": 2, + "move_rate": 7, + "move_tbl": 4, + "special_mv": 2 + }, + { + "name": "Ghouls", + "combat": 3, + "move_rate": 5, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Navy", + "combat": 2, + "move_rate": 10, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Undead Navy", + "combat": 3, + "move_rate": 8, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Clipper", + "combat": 2, + "move_rate": 12, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Infantry", + "combat": 2, + "move_rate": 8, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Mermen", + "combat": 2, + "move_rate": 6, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Tritons", + "combat": 3, + "move_rate": 4, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Pegasus", + "combat": 2, + "move_rate": 10, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Hippogryff", + "combat": 3, + "move_rate": 8, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Leviathan", + "combat": 5, + "move_rate": 4, + "move_tbl": 8, + "special_mv": 1 + } + ], + "armies": [], + "move_table": [ + { + "cost": [ + 0, + 1, + 2, + 2, + 4 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 3, + 0 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 2, + 4 + ] + }, + { + "cost": [ + 1, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 2, + 3 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 1, + 0, + 0, + 0, + 0 + ] + }, + { + "cost": [ + 1, + 1, + 2, + 3, + 4 + ] + } + ], + "world": "Space War", + "gen": 54 +} \ No newline at end of file diff --git a/xtrn/war/worlds/spacewar/map b/xtrn/war/worlds/spacewar/map new file mode 100644 index 0000000000000000000000000000000000000000..973ae1675cc7d331f05d982ea7ca3db5c9804824 --- /dev/null +++ b/xtrn/war/worlds/spacewar/map @@ -0,0 +1,66 @@ +M 64 64 + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/xtrn/war/worlds/spacewar/map.png b/xtrn/war/worlds/spacewar/map.png new file mode 100644 index 0000000000000000000000000000000000000000..f4791ba0ce52037665b7bea775e06fe90447b5f0 Binary files /dev/null and b/xtrn/war/worlds/spacewar/map.png differ diff --git a/xtrn/war/worlds/tolivar/game.orig.json b/xtrn/war/worlds/tolivar/game.orig.json new file mode 100644 index 0000000000000000000000000000000000000000..69585d0acbfe2cc8c76f1ca6fdf472de6367de26 --- /dev/null +++ b/xtrn/war/worlds/tolivar/game.orig.json @@ -0,0 +1,2047 @@ +{ + "ncnt": 1, + "nations": [ + { + "name": "Overlord", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "", + "uid": 0, + "city": 0, + "mark": "*", + "idle_turns": 0 + }, + { + "name": "Rogue", + "uid": -1, + "city": 0, + "mark": "?", + "idle_turns": 0 + } + ], + "cities": [ + { + "name": "Indigo", + "cluster": 1, + "nation": 0, + "r": 5, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lavender", + "cluster": 1, + "nation": 0, + "r": 7, + "c": 2, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Crimson", + "cluster": 1, + "nation": 0, + "r": 3, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Saffron", + "cluster": 1, + "nation": 0, + "r": 9, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Verdant", + "cluster": 1, + "nation": 0, + "r": 6, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Metropolis", + "cluster": 2, + "nation": 0, + "r": 28, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gotham", + "cluster": 2, + "nation": 0, + "r": 29, + "c": 5, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Keystone City", + "cluster": 2, + "nation": 0, + "r": 31, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Central City", + "cluster": 2, + "nation": 0, + "r": 35, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Heliochrysum", + "cluster": 3, + "nation": 0, + "r": 32, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Portulaca", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 29, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gaillardia", + "cluster": 3, + "nation": 0, + "r": 38, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Coreopsis", + "cluster": 3, + "nation": 0, + "r": 36, + "c": 21, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 21 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Delphineum", + "cluster": 3, + "nation": 0, + "r": 33, + "c": 19, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ruby", + "cluster": 4, + "nation": 0, + "r": 14, + "c": 23, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Amber", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Emerald", + "cluster": 4, + "nation": 0, + "r": 16, + "c": 28, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Diamond", + "cluster": 4, + "nation": 0, + "r": 18, + "c": 25, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sapphire", + "cluster": 4, + "nation": 0, + "r": 19, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Zhentil Keep", + "cluster": 5, + "nation": 0, + "r": 40, + "c": 18, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Shadowdale", + "cluster": 5, + "nation": 0, + "r": 42, + "c": 20, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silverdale", + "cluster": 5, + "nation": 0, + "r": 45, + "c": 22, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 20 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Battledale", + "cluster": 5, + "nation": 0, + "r": 48, + "c": 24, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 14 + ], + "times": [ + 1, + 2, + 2, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Dread", + "cluster": 6, + "nation": 0, + "r": 38, + "c": 0, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 4, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Doom", + "cluster": 6, + "nation": 0, + "r": 39, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 7, + 15, + -1 + ], + "times": [ + 1, + 4, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Despair", + "cluster": 6, + "nation": 0, + "r": 42, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Death", + "cluster": 6, + "nation": 0, + "r": 43, + "c": 9, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Agony", + "cluster": 6, + "nation": 0, + "r": 45, + "c": 4, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 6, + 13, + 15, + -1 + ], + "times": [ + 1, + 3, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gloom", + "cluster": 6, + "nation": 0, + "r": 49, + "c": 3, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 6, + 7, + -1, + -1 + ], + "times": [ + 1, + 5, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Iron", + "cluster": 7, + "nation": 0, + "r": 55, + "c": 8, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Gold", + "cluster": 7, + "nation": 0, + "r": 54, + "c": 14, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 20 + ], + "times": [ + 1, + 2, + 3, + 5 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Silver", + "cluster": 7, + "nation": 0, + "r": 58, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Tin", + "cluster": 7, + "nation": 0, + "r": 57, + "c": 10, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Lead", + "cluster": 7, + "nation": 0, + "r": 51, + "c": 13, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 3, + "types": [ + 0, + 1, + 8, + -1 + ], + "times": [ + 1, + 2, + 3, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Nyarlathotep", + "cluster": 8, + "nation": 0, + "r": 34, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Yogsothoth", + "cluster": 8, + "nation": 0, + "r": 30, + "c": 52, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 12, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Cthulhu", + "cluster": 8, + "nation": 0, + "r": 31, + "c": 57, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Hastor", + "cluster": 8, + "nation": 0, + "r": 28, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 2, + "types": [ + 9, + 13, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Olan", + "cluster": 9, + "nation": 0, + "r": 42, + "c": 59, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Kaxandar", + "cluster": 9, + "nation": 0, + "r": 40, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Torgar", + "cluster": 9, + "nation": 0, + "r": 46, + "c": 60, + "prod_type": 0, + "turns_left": 1, + "defense": 3, + "ntypes": 2, + "types": [ + 4, + 10, + -1, + -1 + ], + "times": [ + 1, + 3, + -1, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Arras Charka", + "cluster": 10, + "nation": 0, + "r": 18, + "c": 43, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 21, + -1 + ], + "times": [ + 1, + 2, + 6, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Derzon", + "cluster": 10, + "nation": 0, + "r": 17, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 0, + 1, + 2, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ekosiak", + "cluster": 10, + "nation": 0, + "r": 20, + "c": 47, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 2, + 3 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Ish-Tako", + "cluster": 10, + "nation": 0, + "r": 16, + "c": 46, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Chishata", + "cluster": 10, + "nation": 0, + "r": 23, + "c": 50, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 0, + 1, + 8, + 14 + ], + "times": [ + 1, + 2, + 3, + 6 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Qualinesti", + "cluster": 11, + "nation": 0, + "r": 53, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 20 + ], + "times": [ + 1, + 2, + 2, + 4 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Sylvanesti", + "cluster": 11, + "nation": 0, + "r": 56, + "c": 55, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Rathwynn", + "cluster": 11, + "nation": 0, + "r": 62, + "c": 58, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 17, + 5, + 11, + -1 + ], + "times": [ + 1, + 2, + 2, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Caledon", + "cluster": 11, + "nation": 0, + "r": 60, + "c": 54, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Alfheim", + "cluster": 11, + "nation": 0, + "r": 58, + "c": 51, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 4, + "types": [ + 17, + 5, + 11, + 16 + ], + "times": [ + 1, + 2, + 2, + 7 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Atlantis", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 41, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Mu", + "cluster": 12, + "nation": 0, + "r": 49, + "c": 37, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Poseidon", + "cluster": 12, + "nation": 0, + "r": 46, + "c": 42, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + }, + { + "name": "Neptune", + "cluster": 12, + "nation": 0, + "r": 44, + "c": 38, + "prod_type": 0, + "turns_left": 1, + "defense": 2, + "ntypes": 3, + "types": [ + 18, + 19, + 22, + -1 + ], + "times": [ + 1, + 2, + 8, + -1 + ], + "instance": [ + 0, + 0, + 0, + 0 + ] + } + ], + "ttypes": [ + { + "name": "Lt. Infantry", + "combat": 2, + "move_rate": 6, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Hv. Infantry", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Lt. Cavalry", + "combat": 2, + "move_rate": 12, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Hv. Cavalry", + "combat": 3, + "move_rate": 8, + "move_tbl": 1, + "special_mv": 0 + }, + { + "name": "Dwarf Legion", + "combat": 3, + "move_rate": 4, + "move_tbl": 2, + "special_mv": 0 + }, + { + "name": "Elven Archers", + "combat": 3, + "move_rate": 6, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Zombie Legion", + "combat": 3, + "move_rate": 3, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Wraith Horde", + "combat": 4, + "move_rate": 6, + "move_tbl": 4, + "special_mv": 0 + }, + { + "name": "Elite Troopers", + "combat": 4, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Gug", + "combat": 3, + "move_rate": 4, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Dwarf Miners", + "combat": 4, + "move_rate": 4, + "move_tbl": 5, + "special_mv": 0 + }, + { + "name": "Scout", + "combat": 1, + "move_rate": 8, + "move_tbl": 6, + "special_mv": 0 + }, + { + "name": "Byakhee", + "combat": 2, + "move_rate": 7, + "move_tbl": 4, + "special_mv": 2 + }, + { + "name": "Ghouls", + "combat": 3, + "move_rate": 5, + "move_tbl": 0, + "special_mv": 0 + }, + { + "name": "Navy", + "combat": 2, + "move_rate": 10, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Undead Navy", + "combat": 3, + "move_rate": 8, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Clipper", + "combat": 2, + "move_rate": 12, + "move_tbl": 7, + "special_mv": 3 + }, + { + "name": "Elf Infantry", + "combat": 2, + "move_rate": 8, + "move_tbl": 3, + "special_mv": 0 + }, + { + "name": "Mermen", + "combat": 2, + "move_rate": 6, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Tritons", + "combat": 3, + "move_rate": 4, + "move_tbl": 7, + "special_mv": 0 + }, + { + "name": "Pegasus", + "combat": 2, + "move_rate": 10, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Hippogryff", + "combat": 3, + "move_rate": 8, + "move_tbl": 4, + "special_mv": 1 + }, + { + "name": "Leviathan", + "combat": 5, + "move_rate": 4, + "move_tbl": 8, + "special_mv": 1 + } + ], + "armies": [], + "move_table": [ + { + "cost": [ + 0, + 1, + 2, + 2, + 4 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 3, + 0 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 2, + 4 + ] + }, + { + "cost": [ + 1, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 0, + 1, + 2, + 2, + 3 + ] + }, + { + "cost": [ + 0, + 1, + 1, + 1, + 2 + ] + }, + { + "cost": [ + 1, + 0, + 0, + 0, + 0 + ] + }, + { + "cost": [ + 1, + 1, + 2, + 3, + 4 + ] + } + ], + "world": "Solomoriah's World", + "gen": 0 +} \ No newline at end of file diff --git a/xtrn/war/worlds/tolivar/map b/xtrn/war/worlds/tolivar/map new file mode 100644 index 0000000000000000000000000000000000000000..417f7641ccada1b60607548ff9f3b98f12fd36df --- /dev/null +++ b/xtrn/war/worlds/tolivar/map @@ -0,0 +1,66 @@ +M 64 64 + +~~##~~~~~~~~~~~~%%%%~~~~~~~~~~~~~~~~~.....~~~~~~~~~~~###~~~~~~~~ +~~~~~~~~~~~~~~~%%%..~~~~~~~~~~~~~~~~~~....~~~~~~%%~~~.##~~~~~~~~ +~~~~~~~~~~~~~~~%%%..~~~~~~~~~~~%%%~~~....~~~~~~%%%%~....~~~~~~~~ +~~~~~~~~~~~~~~%%%%..~~~~~~~~~~~%%%......~~~~~~%%%%%~....~~~~~~~~ +~~~~~~~~~~~~~%%%%%..~~~~~~~~~~~~%........~~^^^%%%%%~....~~~~~~~~ +~~~~~~~~~~~~%%%%~~~~..~~~~~~~~~~~.........^^^^..%%~~~..~~~~~~~~~ +##~~~~~~~...%%%~~~~....~~~~~~~~~~~........^^^^...~~~~~~~~~~~~~~~ +###..~~~....###~~~~....~~~##~~~~~~~~.......^^....~~~~~~~~~~~~~~# +###...^^^...###~~~~~....~####~~~~~~~###~~~~~....~~~~~~~~~~~~~~~# +%%~~..^^^^^^##~~~~~~......##..~~~~~####~~~%%...~~~~~~~~~~~~~~~~% +%%%%..^^^^^^^^^~~~~~~.........~~~~~#####%%%%%~~~~~~~~~~~~~~~~~~% +%%%%%..^^^^^^^^^~~~~~~........~~~~#~###%%%%%~~~~~~~~~~~~~~~~~~~~ +%%%%~~~.^^^...^^^~~~~~~~~~~~~~~~~#####%%%%%~~~~~~~~~~~~~~~~~~~~~ +%%%~~~~~~......^^~~~~~~~~~~~~~~~~####^%%%%%~~~~~~.~~~~~~~~~~~~~~ +%%~~~~~~~~....%%%~~~~~~~~~~~~~~~~~##^^^%%%~~~~~~...~~~~~~~~~~~~~ +%%%~~~~~~~~...%%%~~~~~~~~~~~~~~~~~^^^^^^~%%~~~~~~.~~~~~~~~~~~##% +%%%~~~~^^^....%%~~~~~~~~~~~~~~~~~~^^^^^^~~##~~~~~~~~~~~~~~~~###% +%%%~~~^^^^....~~~~~~~~~~~~~~~~~~~~.^^^^~~~###~~~~~~~~~~~~~~..##% +%%~~~~^^^.....~~~~~~~~~~~~~~~~~~~...~~~~~####~~.~~~~~~~~~~~..... +.~~~...~~.....~~~~~~~~~~~~~~~~~~~~.~~~~~~###~~...~~~~~~~~~~..... +..~....~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~###~~~..~~~~~~~~~~..... +.......~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##~~~~##~~~^^%~~~~~~~~~..... +.....%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~####~~~##~~~^^^~~~~~~~~~..... +~~~~%%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~####~~###~~~^^~~~~~~~^^~~..~~ +~~~~%%%...~~~~~~~~~~~~~~~~~~~~~~~~~~#######~~~~~~~~~~~~^^^^~~~~~ +~~~~%%%....~~~~~~~~~~~~~~~~~~~~~~~~#######~~~~~~~~~~~~~^^^^~~~~~ +~~~~~~~~~.~~~~~~~~~~~~~~~~~~~~~~~~~~#####~%%%~~~~~~~~%%%^^~~~~~~ +^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%.~~~~~~%%%%%~~~~~~~ +^^^~~~~~~~~~~~~~~~~...%%~~~~~~~~~~~~~~~~~~%%...~~~~~%%%%%~~~~~~. +^^^~~~~~~~~~~~~~~......%~~~~~~~~~~~~~~~~~~~%......%%%~%%~~~~~~~~ +~^%%~~~~~~~~~~~~~.....~~~~~~~~~~~~~~~~~%~~%%......%%%~~~~~~~~~~~ +~~%%~~~~~~~~~~~~~~...~~~~~~~~~~~~~~~~~%%%%%%.......%%~~~~~~~~~~~ +~....~~~~~~~~~~~~~...~~~~~~~~~~~~~~~~~~%~~%%%.......~~~~~~~~~~~~ +.......~~~~~~~~~~~~......~~~~~~~~~~~~~~~~~~%~~~~....~~~~~~~~~~~~ +........%%%~~~~~~~~.......~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~~~~~... +.~.....%%%%%~~~~~~~~......~~~~~~~~~~~~~~~~~~~~~~~##~~~~~~~~~~... +~~%....%%%%%~~~~~~~~~~~....~~~~~##~~~~~~~~~~~~~~~##~~~~~~...~~.. +^%%%%%%~~~%%#~~~~~~~~~~~.....#####.~~~~~~~~~~~~~.##~~~~~....~~~^ +^%%%%%%~~~~^^^~~~~~~~~~~~....###~...^^~~~~~~~~~~^##~~~~~....~~~^ +^^%%%%~~~~~^^^^~~~~~~~~~~~..~~~~...^^^^~~~~..~~^^^.~~~~##.~^~~~~ +~~~%%~~~~~~~^^~~~~~~~~~~~~~~~~~%...^^^..~~....^^^...~~###~^^^~~~ +~~~~~~~~~~~~##~~~~~~~~~~~~~~~~%%%.~~..........^^^......#~~^^~~~~ +~~~~~~~~~~~~###~~~~~~~~~..~~~%%%%%~~......~~...^~~.....~~~..~~~~ +~~~~~~...~~~~###%%%%~~~.......%%%#~~~..........~~~~...~~~~.~~~~~ +~~~~~.....~~~~~#%%%%%~~........####~~~.........~~~~~~~~~~~~~~~~~ +~~~~......~~~~~##%%%%%~~...~...####.~~~..%%.....~~~~~~~~~~~~~~~~ +~~~......~~~~~~###%%%%~~~..~...###...~~%%%%%....~~~~~~~~~~~~~~~~ +~~##.~..%%~~~~~~#^^^^.......%%~~~^....%%%%%%....~~~~~~~~~~~~~~~~ +.###~~~%%%%~~~~~~^^^^.....%%%%%^^^^..~%%%%%%~..~~~~~~~~~~~~~~~~. +#####~~%%%%%~~~~~^^^^....~%%%%^^^^%%%%%%%..~~~~~~~~~~~~~~~~~~~.. +####^^..%%%%~~~~^^^^^^..~~~~~~^^^%%%%%%%...~~~~~~~~~~~~~~~~~~..# +###^^^...%%~~~~~^^^^^^%%~~~~~~~^^%%%%%%%...~~~~~~~~~~~~~~~~~~~.# +###^^^....~~~~~~~^^^^^%%~~~~~~~~~%%%%%~~~.~~~~~~~~~~~~~~~~~~~~.# +#~~^^^....%~~~~~~.^^^%%%~~~~~~~~~%%%%%~~~~~~~~~~~~~~~~.~..~~~... +~~~~^^.%%%%%~~~....^%%%%~~~~~~~~~~%%%%~~~~~~~~~~~~~~~~....%%.... +~~~~~~%%%%%%%......%%%%%~~~~~~~~~~~%%%%~~~#~~~~~~~~~.~.~.%%%...~ +~~~~~~%%%%%%%.....~~%%%~~~~~~~~~~~~~%%%~~###~~~~~~~...%%%%%%%.~~ +~~~~~~%%%%%%~~.%%~~~~~~~~~~~~~~~~~~~~%%%~~#..~~~~~...%%%%%%%%~~~ +~~~~~~%%%%..~~%%%%~~~~~~~~~~~~~~~~~~~%%%~~~..........%%%^^^%%~~~ +~~~~~~~%%...~~%%%%~~~~~~~~~~~~~~~~~~~~~~~~~.........#^%..^^~~~~~ +~~~~~~~~....~~~%%%~~~~~~~~~~~~~~~~~~~~~~~~~~.....~~~^^^....~~~~~ +~~~~~~~~~.##~~~~%%%%~~~~~~~~~~~~~~~~~~~~~~~~~....~~~^^^^....~~~~ +~~~~~~~~~###~~~~~%%%%~~~~~~~~~~~~~~~..~~~~~~~~..~~~~~^^^^...~~~~ +~~~~~~~~~~~~~~~~~%%%~~~~~~~~~~~~~~~~.....~~~~~~~~~~~~##^^..~~~~~