Files
awlite/awlite.awk
T

712 lines
27 KiB
Awk

# awlite: POSIX AWK port of Text Elite
# Version 1.8
# Original high-level algorithms from Text Elite 1.5 by Ian Bell, 1999, 2015
# Porting, corrections, improvements and optimizations by Luxferre, 2024
#
# Tested on: nawk/one-true-awk, busybox awk, gawk --posix, mawk -W posix
# Should run on any current POSIX-compliant AWK implementation but
# must be run with LC_ALL=C environment variable to work correctly!
#
# Gameplay differences from the original C version of TE 1.5:
# - multiple typos corrected in text strings
# - galaxy jumps are no longer free and cost 5000 credits each (like in classic Elite and Oolite)
# - cargo hold expansion also is non-free and (since v1.8) multi-tiered
# - alien items are available by default, can be overridden with -v NO_ALIEN_ITEMS=1
# - economy names are no longer shortened
# - the "politically correct" goods names are turned on with -v CENSORED=1
# - the following goods have been renamed: "Robot Slaves" to "Robots", "Liquor/Wines" to "Liquors", "Gem-Strones" to "Gem-stones"
# - market and local info tables are better aligned
# - the "cash" and "sneak" commands are removed since v1.6 (use saves to cheat)
# - state saving functionality since v1.6 with "save" and "load" commands
# - since v1.6.1, the game gives you a hint if you might have found Raxxla
# - since v1.6.3, galaxy names are actually displayed (taken from ArcElite)
# - since v1.7, "stat" command and basic ranking was introduced
# - since v1.8, "hold" command was replaced with "upgrade" with several ships
# ... to be continued ...
# utility functions
# determine (ordered) array length
function alen(a, i, k) {
k = 0
for(i in a) k++
return k
}
# split a string with separator into an array but with 0-based indexes
function asplit(s, a, sep, len, i) {
split(s, a, sep) # get 1-based-index array in a
len = alen(a)
for(i=0;i<len;i++) a[i] = a[i+1] # move everything to the left
delete a[len] # delete the last element after moving
}
# serialize any associative array into a string
# sep must be a single char not occurring in any key or value
function assocser(aa, sep, outs, k) {
outs = "" # initialize an ordered array string
for(k in aa) # iterate over keys
outs = outs sep k sep aa[k]
return substr(outs, 2) # delete the first sep
}
# deserialize any associative array from a string
# sep must be a single char used when calling assocser() function
function assocdes(s, aa, sep, oa, i, len) {
split("", aa) # erase aa array
split(s, oa, sep) # get 1-based ordered array in oa
len = alen(oa) # ordered array length
for(i=1;i<=len;i+=2) # populate aa
aa[oa[i]] = oa[i+1]
}
# get the ASCII code of a character
# usage: ord(c) => integer
function ord(c, b) {
# init char-to-ASCII mapping if it's not there yet
if(!TGL_ORD["#"]) for(b=0;b<256;b++) TGL_ORD[sprintf("%c", b)] = b
return int(TGL_ORD[c])
}
# Required bitwise operations (as POSIX AWK doesn't support them)
function bw_and(a, b, v, r) {
v = 1; r = 0
while(a > 0 || b > 0) {
if((a%2) == 1 && (b%2) == 1) r += v
a = int(a/2)
b = int(b/2)
v *= 2
}
return int(r)
}
# ============================ #
# Game code itself starts here #
# ============================ #
# PRNG part
function mysrand(seed) { srand(seed); rng_lastrand = seed - 1 }
function myrand(r) {
if(game["use_native_rand"] > 0) return int(rand() * 65536)
else { # attempt to optimize McDonnell's generator
r = (rng_lastrand * 3677 + 3680) % 2147483648
rng_lastrand = r -1
return r
}
}
function randbyte() {return myrand()%256}
# other functions
function mymin(a,b) {return (a < b) ? a : b}
# distance between 2 planets
function distance(p1x, p1y, p2x, p2y, dx, dy) {
dx = p1x - p2x
dy = p1y - p2y
return int(0.5 + 4*sqrt(dx*dx + dy*dy/4))
}
function rotl(x) { # rotate left 1 bit mod 256
x = x % 256 # truncate to a byte first
return (x * 2 + ((x > 127) ? 1 : 0)) % 256
}
function twist(x) { # twister function
return (256 * rotl(int(x/256)) + rotl(x%256)) % 65536
}
function galswitch(seeds) { # galaxy switcher (accepts an array)
seeds[0] = twist(seeds[0])
seeds[1] = twist(seeds[1])
seeds[2] = twist(seeds[2])
}
function tweakseed(seeds, t) { # another seed tweaker
t = (seeds[0] + seeds[1] + seeds[2]) % 65536
seeds[0] = seeds[1]
seeds[1] = seeds[2]
seeds[2] = t
}
# Generate system info from seed
# populates the sinfo map
function makesystem(seeds, sinfo, p1, p2, p3, p4, lnf, ecof, sname) {
lnf = bw_and(seeds[0], 64)
sinfo["x"] = int(seeds[1] / 256)
sinfo["y"] = int(seeds[0] / 256)
sinfo["govtype"] = int(seeds[1] / 8) % 8
sinfo["economy"] = int(seeds[0] / 256) % 8
if(sinfo["govtype"] <= 1)
sinfo["economy"] = 2 + (sinfo["economy"]%2) + (sinfo["economy"]>3?4:0)
ecof = 7 - sinfo["economy"]
sinfo["techlev"] = (sinfo["x"] % 4) + ecof + int(sinfo["govtype"] / 2)
if((sinfo["govtype"] % 2) == 1) sinfo["techlev"]++
sinfo["population"] = 4 * (sinfo["techlev"]) + sinfo["economy"] + sinfo["govtype"] + 1
sinfo["productivity"] = ((ecof + 3) * (sinfo["govtype"] + 4)) * sinfo["population"] * 8
sinfo["radius"] = 256 * ((int(seeds[2] / 256) % 16) + 11) + sinfo["x"]
# goat soup seed parts
sinfo["gsseed_a"] = seeds[1] % 256
sinfo["gsseed_b"] = int(seeds[1] / 256) % 256
sinfo["gsseed_c"] = seeds[2] % 256
sinfo["gsseed_d"] = int(seeds[2] / 256) % 256
# name pair indexes
p1 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
p2 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
p3 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
p4 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
sname = pairs[p1] pairs[p1+1] pairs[p2] pairs[p2+1] pairs[p3] pairs[p3+1]
if(lnf) sname = sname pairs[p4] pairs[p4+1]
gsub(/\./, "", sname) # remove all dots from sname
sinfo["name"] = sname # write the final name variant
# return sinfo
}
# "Goat Soup" planetary description string code
function gs_rnd(sinfo, a, x) { # accepts system info to modify gsseed
x = (sinfo["gsseed_a"] * 2) % 256
a = x + sinfo["gsseed_c"]
if(sinfo["gsseed_a"] > 127) a++
sinfo["gsseed_a"] = a % 256
sinfo["gsseed_c"] = x
x = sinfo["gsseed_b"]
a = (int(a / 256) + x + sinfo["gsseed_d"]) % 256
sinfo["gsseed_b"] = a
sinfo["gsseed_d"] = x
return a
}
# main desc generator, recursive, modifies sinfo as well
function goat_soup(source, sinfo, l, c, i, j, k, v, rnd, dsel) {
l = length(source)
for(i=0;i<l;i++) {
c = ord(substr(source, i+1, 1))
if(c < 128) printf("%c", c)
else {
if(c <= 164) {
rnd = gs_rnd(sinfo)
asplit(desc_list[c - 129], dsel, ",") # select the string from list
j = ((rnd >= 51) ? 1 : 0) + ((rnd >= 102) ? 1 : 0)
j += ((rnd >= 153) ? 1 : 0) + ((rnd >= 204) ? 1 : 0)
goat_soup(dsel[j], sinfo)
} else {
if(c == 176) { # planet name
v = sinfo["name"]
v = substr(v, 1, 1) tolower(substr(v, 2))
printf("%s", v)
} else if(c == 177) { # planet name + ian
v = sinfo["name"]
v = substr(v, 1, 1) tolower(substr(v, 2))
# find last "e" or "i" occurrence in v
j = match(v, /[eia]+$/)
if(j == 0) j = length(v) + 1
printf("%sian", substr(v, 1, j - 1))
} else if(c == 178) { # random name
v = gs_rnd(sinfo) % 4
for(j = 0; j <= v; j++) {
k = bw_and(62, gs_rnd(sinfo))
printf("%c", (j > 0) ? tolower(pairs0[k]) : pairs0[k])
printf("%c", tolower(pairs0[k+1]))
}
} else { printf("<bad char in data [%X]>",c); return }
}
}
}
}
# Galaxy builder (populates seeds array and global galaxy arrays)
function buildgalaxy(gnum, seeds, si, i) {
asplit("23114 584 46931", seeds, " ")
for(i=1;i<gnum;i++) galswitch(seeds)
split("", galaxy) # global galaxy array
split("", plannames) # global galaxy planet names array
split("", economies) # economy mapping
for(i=0;i<galsize;i++) {
split("", si) # init a new system info array
makesystem(seeds, si) # populate it
galaxy[i] = assocser(si, "|") # serialize into the field
plannames[i] = si["name"] # populate the name
galcoords_x[i] = si["x"] # populate x coordinate
galcoords_y[i] = si["y"] # populate y coordinate
economies[i] = si["economy"] # populate economy type
}
}
# Market functions
# buy amount a of product i, return amount bought
function gamebuy(i, a, t) {
if(player["cash"] < 0) t = 0
else {
t = mymin(localmarket_quantity[i], a)
if(goods_units[i] == 0) t = mymin(player["holdspace"], t)
t = mymin(t, int(player["cash"] / localmarket_price[i]))
}
shipshold[i] = int(shipshold[i]) + t
localmarket_quantity[i] -= t
player["cash"] -= t * localmarket_price[i]
player["expense"] += t * localmarket_price[i]
if(goods_units[i] == 0) player["holdspace"] -= t
return t
}
# sell amount a of product i, return amount sold
function gamesell(i, a, t) {
t = mymin(shipshold[i], a)
shipshold[i] -= t
localmarket_quantity[i] += t
if(goods_units[i] == 0) player["holdspace"] += t
player["cash"] += t * localmarket_price[i]
return t
}
# generate market for a particular planetary system
# accepts fluctuation byte and economy type number
# recreates localmarket_quantity and localmarket_price arrays
function genmarket(fluct, econtype, i, q, product, changing) {
for(i=0;i<=IDX_ALIEN_ITEMS;i++) {
product = econtype * goods_grads[i]
changing = bw_and(fluct, goods_masks[i])
q = (goods_bquants[i] + changing - product + 256) % 256
if(q > 127) q = 0
localmarket_quantity[i] = q % 64
q = (goods_bprices[i] + changing + product) % 256
localmarket_price[i] = q * 4
}
if(NO_ALIEN_ITEMS) localmarket_quantity[IDX_ALIEN_ITEMS] = 0
}
# display local market from localmarket_quantity and localmarket_price
function displaymarket(i) {
for(i=0;i<=IDX_ALIEN_ITEMS;i++) {
printf("\n%-16s", goods_names[i])
printf("%-5s", sprintf("%.1f", localmarket_price[i]/10))
printf("\t%u%s", localmarket_quantity[i], unitnames[goods_units[i]])
printf("\t\t%u", shipshold[i])
}
}
# move to system i
function gamejump(i, si) {
player["currentplanet"] = i
player["jumps"]++
assocdes(galaxy[i], si, "|")
genmarket(randbyte(), int(si["economy"]))
}
# print data for given system
function prisys(sinfo, compressed) {
if(compressed) {
printf("%10s TL: %2i ", sinfo["name"], sinfo["techlev"] + 1)
printf("%-20s %-15s", econnames[sinfo["economy"]], govnames[sinfo["govtype"]])
} else {
printf("\nSystem: %s", sinfo["name"])
printf("\nPosition (%i, %i)", sinfo["x"], sinfo["y"])
printf("\nEconomy: (%i) %s", sinfo["economy"], econnames[sinfo["economy"]])
printf("\nGovernment: (%i) %s", sinfo["govtype"], govnames[sinfo["govtype"]])
printf("\nTech level: %2i", sinfo["techlev"] + 1)
printf("\nTurnover: %u", sinfo["productivity"])
printf("\nRadius: %u", sinfo["radius"])
printf("\nPopulation: %u billion\n", int(sinfo["population"]/8))
goat_soup("\217 is \227.", sinfo) # generate and print the description
if(match(sinfo["name"], /RA..LA/)) # found Raxxla?
printf("\n%s", "Wait a sec... Is this the legendary Raxxla?\nWe'll never know for sure...")
}
}
# return id of the planet whose name matches passed string
# closest to current planet - if none, return current planet
function matchsys(s, d, i, p, cd) {
p = player["currentplanet"]
d = 9999
s = toupper(s) # system names are stored in uppercase
for(i=0;i<galsize;i++) {
if(index(s, plannames[i]) == 1) { # found i-th system
cd = distance(galcoords_x[i], galcoords_y[i], galcoords_x[p], galcoords_y[p])
if(cd < d) {d = cd; p = i}
}
}
return p
}
# direct command implementations (may be further merged into the REPL directly)
# rand command implementation
function dotweakrand() { game["use_native_rand"] = 1 - game["use_native_rand"] }
# local command implementation
function dolocal(d, i, p, si) {
printf("\nGalaxy %i - %s\n", player["galaxynum"], galnames[player["galaxynum"]])
p = int(player["currentplanet"])
for(i=0;i<galsize;i++) {
d = distance(galcoords_x[i], galcoords_y[i], galcoords_x[p], galcoords_y[p])
if(d <= game["maxfuel"]) {
printf("\n %s ", (d <= player["fuel"]) ? "*" : "-")
assocdes(galaxy[i], si, "|") # deserialize current system
prisys(si, 1)
printf(" (%.1f LY)", d/10)
}
}
}
# jump to planet name s
function dojump(s, dest, d, p, si) {
dest = matchsys(s) # find the destination
p = int(player["currentplanet"])
if(dest == p) { printf("\nBad jump"); return 0}
d = distance(galcoords_x[dest], galcoords_y[dest], galcoords_x[p], galcoords_y[p])
if(d > player["fuel"]) {printf("\nJump too far"); return 0}
player["fuel"] -= d
gamejump(dest, si)
prisys(si, 0)
return 1
}
# jump to next galaxy (planet number is preserved)
function dogalhyp() {
if(player["cash"] > game["galhypcost"]) {
player["cash"] -= game["galhypcost"]
player["expense"] += game["galhypcost"]
player["galaxynum"]++
player["jumps"]++
if(player["galaxynum"] == 9) player["galaxynum"] = 1
buildgalaxy(player["galaxynum"], globalseeds) # build a new galaxy
}
else printf("Not enough credits for hyperspace jump!\nMust have at least %.1f CR", game["galhypcost"]/10)
}
# print planet info
function doinfo(s, dest, si) {
dest = matchsys(s) # find the system
assocdes(galaxy[dest], si, "|") # deserialize found system
prisys(si, 0) # print its info
}
# upgrade/up command implementation
function doup(a, t, i, ns) {
ns = 6 # number of upgrades, including the basic version
if(player["upglvl"] == ns - 1)
printf("\nYou already are on the maximum upgrade level, enjoy!")
else if(a == "") { # no parameter, list available ships
printf("\nAvailable upgrades:\n")
for(i=player["upglvl"]+1;i<ns;i++) {
printf("\n%u. %-13s %-5s %-10s", i, shipnames[i], sprintf("%ut", cargoholds[i]), sprintf("%.1f CR",shipprices[i]/10))
}
printf("\n\nType upgrade [number] to upgrade")
} else {
a = int(a)
if(a >= ns || a <= player["upglvl"])
printf("\nInvalid upgrade number!")
else if(player["cash"] < shipprices[a])
printf("\nYou need at least %.1f CR to upgrade to %s!", shipprices[a]/10, shipnames[a])
else { # perform the upgrade if cash allows
player["upglvl"] = a
a = int(cargoholds[a])
t = 0
for(i=0;i<=IDX_ALIEN_ITEMS;i++)
if(goods_units[i] == 0) t += shipshold[i]
if(t > a) {printf("\nHold too full"); return 0}
player["holdspace"] = a - t
player["cash"] -= shipprices[player["upglvl"]]
player["expense"] += shipprices[player["upglvl"]]
printf("\nBought %s", shipnames[player["upglvl"]])
printf("\nCargo bay expanded to %dt", cargoholds[player["upglvl"]])
}
}
}
# check string s against n options in array a
# if matches ith element return i+1 else return 0
function stringmatch(s, a, n, i) {
s = tolower(s)
for(i=0;i<n;i++)
if(index(tolower(a[i]), s) == 1) return i+1
return 0
}
# sell command implementation (accepts space-separated name and amount)
function dosell(s, sp, pname, pquant, i, t) {
split(s, sp, " ")
pname = sp[1]
pquant = int(sp[2])
if(pquant < 1) pquant = 1
i = stringmatch(pname, goods_names, IDX_ALIEN_ITEMS + 1)
if(i == 0) {printf("\nUnknown product"); return 0}
i -= 1 # switch to the real product index
t = gamesell(i, pquant)
pname = goods_names[i] # update real product name
if(t > 0) {
printf("\nSelling %i%s of %s", t, unitnames[goods_units[i]], pname)
} else printf("\nCannot sell any %s", pname)
return 1
}
# buy command implementation (accepts space-separated name and amount)
function dobuy(s, sp, pname, pquant, i, t) {
split(s, sp, " ")
pname = sp[1]
pquant = int(sp[2])
if(pquant < 1) pquant = 1
i = stringmatch(pname, goods_names, IDX_ALIEN_ITEMS + 1)
if(i == 0) {printf("\nUnknown product"); return 0}
i -= 1 # switch to the real product index
t = gamebuy(i, pquant)
pname = goods_names[i] # update real product name
if(t > 0) {
printf("\nBuying %i%s of %s", t, unitnames[goods_units[i]], pname)
} else printf("\nCannot buy any %s", pname)
return 1
}
# attempt to buy f tonnes of fuel
function gamefuel(f) {
if((f + player["fuel"]) > game["maxfuel"])
f = game["maxfuel"] - player["fuel"]
if(game["fuelcost"] > 0 && (f * game["fuelcost"] > player["cash"]))
f = int(player["cash"] / game["fuelcost"])
player["fuel"] += f
player["cash"] -= f * game["fuelcost"]
player["expense"] += f * game["fuelcost"]
return f
}
# fuel command implementation
function dofuel(f) {
f = gamefuel(int(10 * f))
if(f == 0) printf("\nCan't buy any fuel")
else printf("\nBuying %.1fLY fuel", f/10)
return 1
}
# show stock market
function domkt() {
displaymarket()
printf("\n\nFuel: %.1f\nFree cargo space: %it", player["fuel"]/10, player["holdspace"])
}
# display help
function dohelp() {
printf("\nCommands are:")
printf("\nBuy product amount")
printf("\nSell product amount")
printf("\nFuel amount (buy amount LY of fuel)")
printf("\nJump planetname (limited by fuel)")
printf("\nGalhyp (jump to next galaxy)")
printf("\nInfo planetname (print info on system)")
printf("\nMkt (show market prices)")
printf("\nLocal (list systems within 7 lightyears)")
printf("\nUpgrade (upgrade your ship)")
printf("\nStat (show player statistics)")
printf("\nSave playername (save game into current working directory)")
printf("\nLoad playername (load game from current working directory)")
printf("\nQuit or ^D (exit)")
printf("\nHelp (display this text)")
printf("\nRand (toggle RNG)")
printf("\n\nAbbreviations allowed eg. b fo 5 = Buy Food 5, m = Mkt")
}
# Save/load functionality
function dosave(savename, fs, fn) {
gsub(/[^[:alnum:]]/, "_", savename) # sanitize all non-alnum chars
player["cargo"] = assocser(shipshold, "@")
fs = assocser(player, "|")
delete player["cargo"]
fn = savename ".awlite"
printf("%s\n", fs) > fn # write the savefile
close(fn)
printf("\nGame saved in %s", fn)
}
function doload(savename, fn, fs) {
gsub(/[^[:alnum:]]/, "_", savename) # sanitize all non-alnum chars
fn = savename ".awlite"
if((getline fs < fn) > 0) { # read the savefile
split("", player) # clear the player array
split("", shipshold) # clear the shipshold array
assocdes(fs, player, "|")
assocdes(player["cargo"], shipshold, "@")
delete player["cargo"]
split("", globalseeds) # init galaxy seeds
buildgalaxy(player["galaxynum"], globalseeds) # build the current galaxy
genmarket(0, economies[player["currentplanet"]]) # build local market
printf("\nGame loaded from %s", fn)
} else printf("\nError reading the savefile!")
close(fn)
}
# player statistics and ranking display
# ranking formula might be subject to change in future versions
function dostat(profind, rank) {
profind = 0 # profit margin index
rank = 0
if(player["expense"] > 0) {
profind = (player["cash"]-1000) / player["expense"]
if(profind > 1) rank = int(log(profind) / log(2)) + 1 # log base 2
if(rank < 0) rank = 0
if(rank > 8) rank = 8
}
printf("\nRank: %s", ranknames[rank])
printf("\n\n========= Money =========")
printf("\nBalance %17s", sprintf("%.1f CR",player["cash"]/10))
printf("\nExpenses %16s", sprintf("%.1f CR", player["expense"]/10))
printf("\nProfit margin %11s", sprintf("%.2f%%", profind*100))
printf("\n\n======= Ship info =======")
printf("\nName %20s", shipnames[player["upglvl"]])
printf("\nFuel %20s", sprintf("%.1f LY", player["fuel"]/10))
printf("\nCargo space %13s", sprintf("%ut", cargoholds[player["upglvl"]]))
printf("\nFree space %14s", sprintf("%ut", player["holdspace"]))
printf("\nJumps %19s", sprintf("%u", player["jumps"]))
}
# Game init procedure: first thing to call in the BEGIN block
function gameinit() {
rng_lastrand = 0 # state for custom PRNG
mysrand(12345); # ensure repeatability
numForLave = 7 # Lave is the 7th planet in galaxy 1
split("",game) # overall game state is stored here
game["use_native_rand"] = 1
game["galhypcost"] = 50000 # 5000 CR
game["cargoexpcost"] = 4000 # 400 CR for one-time upgrade
game["cargoexpsize"] = 35 # 35t after the upgrade
game["fuelcost"] = 2 # 0.2 CR/lightyear
game["maxfuel"] = 70 # 7.0 LY tank
split("",player) # current (saveable) player state is stored here
player["currentplanet"] = numForLave # current planet (1 to 256)
player["galaxynum"] = 1 # current galaxy (1 to 8)
player["cash"] = 1000 # current cash (100 CR)
player["expense"] = 0 # for tracking overall expenses
player["jumps"] = 0 # for counting interplanetary jumps
player["fuel"] = game["maxfuel"] # current fuel amount
player["upglvl"] = 0 # player's upgrade level
split("",shipshold) # (saveable) contents of cargo bay, up to 16 items
# constants and tables
# unit names
asplit("t kg g", unitnames, " ")
# galaxy names (1-indexed)
split("Santaari Colesque Lara'tan Angiana Proximus Sol Jaftra Xrata", galnames, " ")
# government names
asplit("Anarchy,Feudal,Multi-gov,Dictatorship,Communist,Confederacy,Democracy,Corporate State", govnames, ",")
# economy names
asplit("Rich Industrial,Average Industrial,Poor Industrial,Mainly Industrial,Mainly Agricultural,Rich Agricultural,Average Agricultural,Poor Agricultural", econnames, ",")
# rank names
asplit("Penniless,Mostly Penniless,Peddler,Dealer,Merchant,Broker,Entrepreneur,Tycoon,Elite", ranknames, ",")
# ship names
asplit("Cobra Mk3,Cobra Mk3 Ext,Python,Boa,Boa 2,Anaconda", shipnames, ",")
# upgrade prices
asplit("0 4000 2000000 4500000 4950000 6500000", shipprices, " ")
# cargo hold values, t
asplit("20 35 100 125 175 750", cargoholds, " ")
player["holdspace"] = cargoholds[player["upglvl"]] # max cargo hold space
# Goods
# Data for DB's price/availability generation system:
# Base price, Gradient, Base quantity, Mask, Unit, Name
split("", commodities) # will split on demand
commodities[0] = "19,-2,6,1,0,Food"
commodities[1] = "20,-1,10,3,0,Textiles"
commodities[2] = "65,-3,2,7,0,Radioactives"
commodities[3] = "40,-5,226,31,0," (CENSORED ? "Robots" : "Slaves")
commodities[4] = "83,-5,251,15,0," (CENSORED ? "Beverages" : "Liquors")
commodities[5] = "196,8,54,3,0,Luxuries"
commodities[6] = "235,29,8,120,0," (CENSORED ? "Rare Species" : "Narcotics")
commodities[7] = "154,14,56,3,0,Computers"
commodities[8] = "117,6,40,7,0,Machinery"
commodities[9] = "78,1,17,31,0,Alloys"
commodities[10] = "124,13,29,7,0,Firearms"
commodities[11] = "176,-9,220,63,0,Furs"
commodities[12] = "32,-1,53,3,0,Minerals"
commodities[13] = "97,-1,66,7,1,Gold"
commodities[14] = "171,-2,55,31,1,Platinum"
commodities[15] = "45,-1,250,15,2,Gem-stones"
commodities[16] = "53,15,192,7,0,Alien Items"
IDX_ALIEN_ITEMS=16
split("", goods_bprices) # holds base prices
split("", goods_grads) # holds gradients
split("", goods_bquants) # holds base quantities
split("", goods_masks) # holds masks
split("", goods_units) # holds measurement units
split("", goods_names) # holds goods names
for(i in commodities) { # it's pre-ordered anyway
split(commodities[i], parts, ",") # we can use 1-based here
goods_bprices[i] = int(parts[1])
goods_grads[i] = int(parts[2])
goods_bquants[i] = int(parts[3])
goods_masks[i] = int(parts[4])
goods_units[i] = int(parts[5])
goods_names[i] = parts[6]
}
# localmarket assoc arrays
split("", localmarket_quantity)
split("", localmarket_price)
# digrams for planet names
asplit("ABOUSEITILETSTONLONUTHNOALLEXEGEZACEBISOUSESARMAINDIREA.ERATENBERALAVETIEDORQUANTEISRION", pairs0, "")
asplit("..LEXEGEZACEBISOUSESARMAINDIREA.ERATENBERALAVETIEDORQUANTEISRION", pairs, "")
# planet description string parts
desc_list_str = "fabled,notable,well known,famous,noted|very,mildly,most,reasonably,|ancient,\225,great,vast,pink|\236 \235 plantations,mountains,\234,\224 forests,oceans|shyness,silliness,mating traditions,loathing of \206,love for \206|food blenders,tourists,poetry,discos,\216|talking tree,crab,bat,lobst,\262|beset,plagued,ravaged,cursed,scourged|\226 civil war,\233 \230 \231s,a \233 disease,\226 earthquakes,\226 solar activity|its \203 \204,the \261 \230 \231,its inhabitants' \232 \205,\241,its \215 \216|juice,brandy,water,brew,gargle blasters|\262,\261 \231,\261 \262,\261 \233,\233 \262|fabulous,exotic,hoopy,unusual,exciting|cuisine,night life,casinos,sit coms, \241 |\260,The planet \260,The world \260,This planet,This world|n unremarkable, boring, dull, tedious, revolting|planet,world,place,little planet,dump|wasp,moth,grub,ant,\262|poet,arts graduate,yak,snail,slug|tropical,dense,rain,impenetrable,exuberant|funny,weird,unusual,strange,peculiar|frequent,occasional,unpredictable,dreadful,deadly|\202 \201 for \212,\202 \201 for \212 and \212,\210 by \211,\202 \201 for \212 but \210 by \211,a\220 \221|\233,mountain,edible,tree,spotted|\237,\240,\207oid,\223,\222|ancient,exceptional,eccentric,ingrained,\225|killer,deadly,evil,lethal,vicious|parking meters,dust clouds,ice bergs,rock formations,volcanoes|plant,tulip,banana,corn,\262weed|\262,\261 \262,\261 \233,inhabitant,\261 \262|shrew,beast,bison,snake,wolf|leopard,cat,monkey,goat,fish|\214 \213,\261 \237 \242,its \215 \240 \242,\243 \244,\214 \213|meat,cutlet,steak,burgers,soup|ice,mud,Zero-G,vacuum,\261 ultra|hockey,cricket,karate,polo,tennis"
asplit(desc_list_str, desc_list, "|")
galsize = 256 # number of systems in one galaxy
}
# main code block
BEGIN {
gameinit() # init everything
split("", globalseeds) # init galaxy seeds
buildgalaxy(player["galaxynum"], globalseeds) # build the current galaxy
genmarket(0, economies[player["currentplanet"]]) # build local market
printf("\nWelcome to awlite 1.8\n")
dohelp()
# start the REPL
printf("\n\nCash: %.1f> ", player["cash"]/10)
while((getline cmd) > 0) {
cmd = tolower(cmd) # accept both uppercase and lowercase
spi = index(cmd, " ") # first whitespace in cmd
action = (spi == 0) ? cmd : substr(cmd, 1, spi - 1)
paramstr = (spi == 0) ? "" : substr(cmd, spi+1)
if(cmd == "q" || cmd == "quit") break
else if(cmd == "h" || cmd == "help") dohelp()
else if(cmd == "r" || cmd == "rand") dotweakrand()
else if(cmd == "m" || cmd == "mkt") domkt()
else if(cmd == "l" || cmd == "local") dolocal()
else if(cmd == "g" || cmd == "galhyp") dogalhyp()
else if(cmd == "st" || cmd == "stat") dostat()
else if(action == "i" || action == "info") doinfo(paramstr)
else if(action == "b" || action == "buy") dobuy(paramstr)
else if(action == "s" || action == "sell") dosell(paramstr)
else if(action == "j" || action == "jump") dojump(paramstr)
else if(action == "f" || action == "fuel") dofuel(paramstr)
else if(action == "up" || action == "upgrade") doup(paramstr)
else if(action == "save") dosave(paramstr)
else if(action == "load") doload(paramstr)
else printf("Unknown command")
printf("\n\nCash: %.1f> ", player["cash"]/10)
}
print "\nBye!"
}