// Steam-tunnel hack, by Bryce Schroeder (2006) // package th; import java.util.Vector; import java.awt.*; import javax.swing.*; class InventoryCellRenderer extends JLabel implements ListCellRenderer { public Component getListCellRendererComponent( JList list, Object value, // value to display int index, // cell index boolean isSelected, // is the cell selected boolean cellHasFocus) { String s = ((Itm)value).describe(); setText(s); return this; } } class MonsterCellRenderer extends JLabel implements ListCellRenderer { public Component getListCellRendererComponent( JList list, Object value, // value to display int index, // cell index boolean isSelected, // is the cell selected boolean cellHasFocus) { String s; if (value != g.player) s = ((Mon)value).describe(); else s = "You"; setText(s); return this; } } public class Tunnels { // configuration public static int VT100 = 0, DOS = 1, GUI = 2; public static int gmode = VT100; //public static boolean VT100 = true; // use vt100 graphics // good for *nix. otherwise use dos graphics. public static boolean DEBUG = true; public static boolean PUBLIC = false; // server mode public static double DIFFICULTY = 1.6; private static boolean used_debug = false; public static int PATCH = 5; public static String[] ARTIFACTS = { "Zaurus of Perspicacity", "Pen of the Propagandists", "Dread Sword of Nerfing" }; public static String[] CANIBAL = { "question your sanity.", "feel guilty.", "wonder how things came to this so quickly.", "think this is really weird.", "question your sanity." }; public static String[] pet_names = { "Zappy", "Mr. Dangerous", "Greased Lightning", "Plato", "Aristotle", "Fuzzy", "Mutt","Rufus","Hunter", "Copper" }; public static String[] default_names = { "Seijik", "Habnabit", "Foo Thark", "Ironspam von Schweinhund II", "Gluon McGee", "Gordon Tazmania", "Preston Q Lackwit", "Dubai Dan", "Zemdar Hemmingway", "Orcrist L'Pointy", "Dash Riprock", "Waldo Sporkler", "Klingon Warrior Bob", "Neko Ichiban" }; public static String[] GENDERS = { "genderless", "male", "female", "male or female" }; // GUI CODE public static JFrame iwindow; public static JPanel ipanel; public static JScrollPane iinventory_scrollpane; public static JScrollPane iitems_scrollpane; public static JScrollPane imons_scrollpane; public static JList iinventory; public static JList iitems; public static JPanel istatpanel; public static JLabel istatpanel_name; public static JList imons; public static void init_gui() { iwindow = new JFrame("TunnelHack"); iwindow.setSize(640,480); iwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ipanel = new JPanel(); ipanel.setLayout(new BorderLayout()); istatpanel = new JPanel(); istatpanel.setLayout(new BorderLayout()); iwindow.add(ipanel); iwindow.setVisible(true); } // Run after the player and map exist. public static void config_gui() { iinventory = new JList();//g.player.inventory); iinventory_scrollpane = new JScrollPane(iinventory); iinventory.setCellRenderer(new InventoryCellRenderer()); //iinventory_scrollpane.setMinimumSize(new Dimension(160,200)); ipanel.add(iinventory_scrollpane, BorderLayout.WEST); iitems = new JList();//g.here.items); iitems_scrollpane = new JScrollPane(iitems); iitems.setCellRenderer(new InventoryCellRenderer()); //iitems_scrollpane.setMinimumSize(new Dimension(160,200)); ipanel.add(iitems_scrollpane, BorderLayout.CENTER); imons = new JList();//g.here.mons); imons_scrollpane = new JScrollPane(imons); imons.setCellRenderer(new MonsterCellRenderer()); //imons_scrollpane.setMinimumSize(new Dimension(160,200)); ipanel.add(imons_scrollpane, BorderLayout.EAST); iwindow.setVisible(true); } public static void update_gui() { iinventory.setListData(g.player.inventory); iitems.setListData(g.here.items); imons.setListData(g.here.mons); } public static void main (String[] args) { if (PUBLIC) g.from = Ifc.gstring("?"); else g.from = "Local Game"; if (gmode == GUI) init_gui(); Ifc.msg("Bryce Schroeder's Steam Tunnel Hack, v1.3 r" + PATCH); String name = Ifc.gstring("What is your name?", Utl.rn(default_names)); int major = Ifc.choice("What is your major?", "Science|Liberal Arts|Physical Education"); Spe[] majors = {Species.nerd, Species.artsie, Species.jock}; Spe[] pets = {Species.pikachu, Species.cat, Species.dog}; /*if (Utl.rn(3) == 0) g.pet = Species.zergling.make(); else*/ // no more random zerglings g.pet = pets[major].make(); g.player = majors[major].make(); g.major = major; g.player.name = name; g.player.ai = g.player.WANDERING; g.pet.rabid = false; g.pet.ai = g.pet.PET; int gender = 1+Ifc.choice("Which gender are you?", "Male|Female"); g.player.gender = gender; Ifc.msg(("\n\t\t\t--------\n"+Ifc.INTRO+"\n\n").replaceAll( "\\|artifact\\|", ARTIFACTS[g.major])); g.pet.name = Ifc.gstring("What is your pet "+g.pet.species.name+"'s name?", Utl.rn(pet_names)); System.out.printf("Welcome to the tunnels, %s the %s!\n", name, majors[major].name ); if (PUBLIC) Ifc.msg("You are playing from " + g.from); Ifc.msg("You have a pet " + g.pet.species.name + " named " + g.pet.name + "."); Ifc.msg("Type ? then return/enter for a command listing."); Ifc.pk(); Node entrance; Node center = new Boiler_Room(); MoleParameterSet mps = new MoleParameterSet(); // MoleParameterSet for northern branch (where player starts) MoleParameterSet rps = new MoleParameterSet(); rps.inital_difficulty = 30; rps.difficulty_slope = -1; rps.special_chance = 10; entrance = Map.make_map(center, mps, rps); entrance.add(g.player); entrance.add(g.pet); ++g.phase; g.center = center; if (gmode == GUI) config_gui(); //Map.fix(); while (main_loop()) { if (g.player.hp <= 0 || g.player.dead) { Ifc.msg("You are dead."); System.out.printf( "Goodbye %s the %s, killed by %s in %s %s.\n", g.player.name, g.player.species.name, g.player.last_damage, (g.here.unique? "the" : "a"), g.here.name ); Ifc.pk(); if (g.player.murders == 0) Ifc.msg("You never murdered anyone."); else { System.out.printf("You killed %d people.\n", g.player.murders); if (g.player.murders <= g.allow_murder) Ifc.msg("But you would have gotten away with it."); else System.out.printf("You would have been convicted of %d murders.\n", g.player.murders - g.allow_murder); } if (g.player.canibal == 0) Ifc.msg("You never resorted to canibalism."); else System.out.printf("You ate %d members of your own species.\n", g.player.canibal); if (g.player.peacefuls == 0) Ifc.msg("You never attacked a peaceful creature."); else System.out.printf("You attacked peaceful creatures %d times.\n", g.player.peacefuls); System.out.printf("You vanquished %d enemies. You had %d XP. \n", g.player.vanquished, g.player.xp); System.out.printf("You visited %2.1f%% of the maze's rooms.\n", ((float)g.visited / g.nodes.size()) * 100); if (!used_debug) try { Ifc.msg("Trying to write to the high scores..."); Hsn.writeout(g.player); } catch (java.io.IOException e) { Ifc.msg("Sadly, your score could not be recorded in scores.txt."); } Ifc.pk(); if (Ifc.yn("Would you like to see a census of the tunnels?")) for (Spe x : Species.one_of_everything) { System.out.printf("%s: %d created; ~%d alive.\n", x.name, x.created, x.created-x.dead); } break; } } } public static void win () { g.player.xp += 100000-g.player.vanquished*50; // Win bonus if (g.player.xp < 0 ) g.player.xp = 0; Ifc.msg("Congratulations, " + g.player.name + "! You've beaten Tunnel Hack!"); Ifc.msg("You have survivied..."); System.out.printf( "Goodbye %s the great level %d %s, destroyer of Suzie, finder of the legendary %s.\n", g.player.name, g.player.level, g.player.species.name, g.artifact.kind.name); g.player.last_damage = "emerged from the tunnels victorious"; if (g.player.murders == 0) Ifc.msg("You never murdered anyone."); else { System.out.printf("You killed %d people.\n", g.player.murders); if (g.player.murders <= g.allow_murder) Ifc.msg("But you got away with it."); else { System.out.printf("You were convicted and sentenced to %d years in prison.\n", Utl.d(50)*(g.player.canibal+1)); g.player.last_damage = "won the game, but was arrested for murder"; } } if (g.player.canibal == 0) Ifc.msg("You never resorted to canibalism."); else System.out.printf("You ate %d members of your own species.\n", g.player.canibal); if (g.player.peacefuls == 0) Ifc.msg("You never attacked a peaceful creature."); else System.out.printf("You attacked peaceful creatures %d times.\n", g.player.peacefuls); System.out.printf("You vanquished %d enemies. You had %d XP. \n", g.player.vanquished, g.player.xp); System.out.printf("You visited %2.1f%% of the maze's rooms.\n", ((float)g.visited / g.nodes.size()) * 100); try { Ifc.msg("Trying to write to the high scores..."); Hsn.writeout(g.player); } catch (java.io.IOException e) { Ifc.msg("Sadly, your score could not be recorded in scores.txt."); } Ifc.pk(); System.exit(0); } private static void update ( Vector monsters ) { Mon current; for (int i = 0; i < monsters.size(); ++i) { current = (Mon)g.monsters.elementAt(i); if (current == g.player) continue; if (current.hp <= 0) { current.die(null); continue; } if (current.ai != 0 || g.player.here.mons.contains(current)) current.update(); } } public static boolean main_loop() { // Update world Mon current; for (int apcache = g.highest_ap; apcache > 0; --apcache) { for (int i = 0; i < g.monsters.size(); ++i) { current = (Mon)g.monsters.elementAt(i); if (current.hp <= 0) current.die(null); if (current.ap < apcache) continue; if (current.xap > 0) { current.xap--; continue; } if (current == g.player) { Map.show(g.here, 30, 7, false, 6); if (g.player.hp < g.player.mhp && g.turns % g.player.species.regeneration == 1) ++g.player.hp; // Eventually, this will be in an if-else with the console code below. if (gmode == GUI) update_gui(); System.out.printf("\n\nT:%d AP %d/%d HP:%s%d/%d%s -- %s the %s (%d/%d) -- %s%s%s\n", g.turns, apcache, g.player.ap, Ifc.hpcolor(g.player), g.player.hp, g.player.mhp, Ifc.color(), g.player.name, g.player.species.name, g.player.level, g.player.xp, Ifc.color(g.here.color), g.here.name, Ifc.color() ); Ifc.msg(g.here.describe()); if (g.player.stunned != 0) { Ifc.you("are stunned by " + g.player.stunner + " and are unable to move!"); Ifc.pk(); --g.player.stunned; } else while(!player_turn()); Ifc.msg(" ---- "); continue; } if (current.ai != 0 || g.player.here.mons.contains(current)) current.update(); } } g.doUpdate(); for (int i = 0; i < g.nodes.size(); ++i) ((Node)g.nodes.elementAt(i)).update(); ++g.turns; return true; } public static void look(Node where) { Mon who = null; if (where.mons.isEmpty() || Utl.rn(4) == 0) Ifc.you("don't see anything there."); else { who = (Mon)Utl.rn(where.mons); Ifc.you("catch a glimpse of a " + who.species.name + "."); if (Utl.rn()) Ifc.you("Think "+Ifc.he(who)+" is " + Mon.string_status[who.ai] + "."); } } public static boolean do_glide() { if (g.glidetrigger) g.glide = null; if (g.glide != null) { int dir = -1; if (g.here.north == g.glide) { Ifc.you("proceed north."); dir = 0; } else if (g.here.south == g.glide) { Ifc.you("proceed south."); dir = 1; } else if (g.here.east == g.glide) { Ifc.you("proceed east."); dir = 2; } else if (g.here.west == g.glide) { Ifc.you("proceed west."); dir = 3; } else Ifc.you("teleport."); g.glidetrigger = false; g.here.mons.remove(g.player); g.here = g.glide; g.here.add(g.player); if (g.here.mons.size() > 1 || g.here.items.size() > 0 || Map.countlinks(g.here) != 2) g.glide = null; else { if (g.here.north != null && dir != 1) if (g.here.north.special_symbol != " ") g.glide = null; else g.glide = g.here.north; else if (g.here.south != null && dir != 0) if (g.here.south.special_symbol != " ") g.glide = null; else g.glide = g.here.south; else if (g.here.east != null && dir != 3) if (g.here.east.special_symbol != " ") g.glide = null; else g.glide = g.here.east; else if (g.here.west != null && dir != 2) if (g.here.west.special_symbol != " ") g.glide = null; else g.glide = g.here.west; } return true; } return false; } public static boolean player_turn() { if (g.player.hp <= 0) return true; if (do_glide()) return true; System.out.print("> "); //while (!g.in.hasNextByte()) String cmnd = ""; while (cmnd.length() == 0) cmnd = g.in.nextLine(); Mon who; Itm what; Node where; switch (cmnd.charAt(0)) { case 'x': if (!used_debug && !Ifc.yn("Enter debug mode? (NO SCORE)")) break; if (DEBUG) { if (!used_debug) g.player.inventory.add(Items.zaurus.make()); used_debug = true; g.debug = true; System.out.printf("Stats of %s the %s level %d/%d %s:\n", g.player.name, GENDERS[g.player.gender], g.player.level, g.player.xp, g.player.species.name ); System.out.printf("You are %s aligned. (%d)\n", (g.player.species.alignment < 0? "jock" : (g.player.species.alignment > 0? "nerd" : "neutrally")), g.player.species.alignment); System.out.printf("ST: %d/%d IN: %d/%d DX: %d/%d HP: %d/%d Rg: 1/%d Ar: %d\n", g.player.st, g.player.mst, g.player.in, g.player.min, g.player.dx, g.player.mdx, g.player.hp, g.player.mhp, g.player.species.regeneration, g.player.armor); System.out.printf("Sins: Murder: %d/%d, Canibalism: %d, Attack peacefuls: %d\n", g.player.murders, g.allow_murder, g.player.canibal, g.player.peacefuls); if (g.player.resist_chemical) Ifc.msg("You are chemical resistant."); if (g.player.resist_gas) Ifc.msg("You are gas resistant."); if (g.player.resist_polymorph) Ifc.msg("You are polymorph resistant."); if (g.player.resist_bullets) Ifc.msg("You are bullet resistant."); if (Ifc.yn("Want a census?")) for (Spe x : Species.one_of_everything) { System.out.printf("%s: %d created; ~%d alive.\n", x.name, x.created, x.created-x.dead); } if (Ifc.yn("Create a creature?")) { Spe critter = Ifc.get_spe(Ifc.gstring("What kind of creature?")); Mon temp = critter.make(); temp.rabid = Ifc.yn("Do you want it rabid/insane?"); temp.ai = Ifc.choice("What is its AI state?", "Sleeping|Wandering|Attacking|Fleeing|Allied"); g.here.add(temp); Ifc.msg("A " + critter.name + " appears in a poof of binary!"); } if (Ifc.yn("Create an object?")) { Kind thingy = Ifc.get_kind(Ifc.gstring("What kind of thing?")); Itm temp = thingy.make(); temp.tainted = Ifc.yn("Do you want it tainted?"); g.here.add(temp); Ifc.msg("A " + thingy.name + " appears in a poof of binary!"); } if (Ifc.yn("Would you like to polymorph?")) { g.player.species = Ifc.get_spe(Ifc.gstring("Turn into what creature? ")); if (Ifc.yn("Reroll stats? ")) g.player.reroll_stats(); } if (Ifc.yn("Would you like a giant map?")) { for (int i = 0; i < g.nodes.size(); ++i) ((Node)g.nodes.elementAt(i)).trav = false; Map.show(g.here, 150, 150, true, 0); } /* if (Ifc.yn("Want to genocide something?")) String target = Ifc.gstring("Wipe out what creatures?"); for (Spe x : Species.one_of_everything) { if (x.name.compareTo(x) == 0) { Ifc.msg("Wiped out all "+x.name+"!"); }*/ } else Ifc.msg("That feature is for debug mode only."); return false; case 'l': Ifc.you("look around."); Ifc.msg(g.here.describe(true)); Ifc.pk(); return false; case 'n': if (g.here.north == null) { Ifc.you( "look for a northern passage, but find none."); Ifc.pk(); return false; } else { Ifc.you("proceed north."); g.here.mons.remove(g.player); g.here = g.here.north; g.here.add(g.player); } break; case 's': if (g.here.south == null) { Ifc.you( "look for a southern passage, but find none."); Ifc.pk(); return false; } else { Ifc.you("proceed south."); g.here.mons.remove(g.player); g.here = g.here.south; g.here.add(g.player); } break; case 'e': if (g.here.east == null) { Ifc.you( "look for an eastern passage, but find none."); Ifc.pk(); return false; } else { Ifc.you("proceed east."); g.here.mons.remove(g.player); g.here = g.here.east; g.here.add(g.player); } break; case 'w': if (g.here.west == null) { Ifc.you( "look for an western passage, but find none."); Ifc.pk(); return false; } else { Ifc.you("proceed west."); g.here.mons.remove(g.player); g.here = g.here.west; g.here.add(g.player); } break; case '?': Ifc.msg(Ifc.HELP); Ifc.pk(); return false; case 't': who = Ifc.choice_mon("Talk to whom?", g.here.mons); if (who == null) return false; Ifc.you(Utl.rn("chat|strike up a conversation|talk|chat")+ " with the " + who.species.name + "."); who.do_talk(true); break; case 'g': if (g.here.items.size() == 0) { Ifc.you("see no items here."); return false; } what = Ifc.choice_itm("Pick up what?", g.here.items); if (what == null) return false; if (g.player.pick_up(what)) Ifc.you("have a " + what.kind.name + "."); break; case 'r': if (g.player.inventory.size() == 0) { Ifc.you("haven't anything to ready."); return false; } what = Ifc.choice_itm("Wield what as a weapon?", g.player.inventory); if (what == null) return false; if (what.kind.damage == 0) { Ifc.you("don't think that is worth wielding."); return false; } else g.player.wield(what); break; case 'c': if (g.player.inventory.size() == 0) { Ifc.you("haven't anything to eat."); return false; } what = Ifc.choice_itm("What would you like to eat?", g.player.inventory); if (what == null) return false; if (what.kind.heal == 0) { Ifc.you("can't eat that!"); return false; } else g.player.eat(what); if (what.kind == g.player.species.corpse) { Ifc.you(Utl.rn(CANIBAL)); ++g.player.canibal; } break; case 'p': if (g.player.inventory.size() == 0) { Ifc.you("haven't anything to wear."); return false; } what = Ifc.choice_itm("What would you like to wear?", g.player.inventory); if (what == null) return false; if (what.kind.armor == 0) { Ifc.you("would feel rather silly wearing a "+what.kind.name+"."); return false; } else g.player.wear(what); break; case 'i': Ifc.show_items("You have these items:",g.player.inventory); return false; case 'd': if (g.player.inventory.size() == 0) { Ifc.you("haven't anything to drop."); return false; } what = Ifc.choice_itm("Drop what thing?", g.player.inventory); if (what == null) return false; g.player.drop(what); return false; case 'q': if (Ifc.yn("Are you sure you want to quit?")) { g.player.last_damage = "fleeing the tunnels like a coward"; g.player.hp = 0; } break; case 'z': if (g.player.inventory.size() == 0) { Ifc.you("are without material posessions.\n"); return false; } what = Ifc.choice_itm("Label what object?", g.player.inventory); if (what == null) return false; what.name = Ifc.gstring("Call this " + what.kind.name + " what? "); return false; case 'j': if (g.here.mons.size() == 0) { Ifc.you("are alone.\n"); return false; } int mode = Ifc.choice("Do what?", "Name a creature|Take an item |Give an item"); who = Ifc.choice_mon("Which creature?", g.here.mons); if (who == null) return false; if (mode == 0) { who.name = Ifc.gstring("Call this " + who.species.name + " what? "); if (who.ai == who.PET) Ifc.you("will now call your "+who.species.name+" \""+who.name+"\"."); else if (who == g.player) Ifc.you("will henceforth go by the name \""+who.name+"\"."); else Ifc.you("will henceforth call the "+who.species.name+" \""+who.name+"\"."); return false; } else if (mode == 1) { if (who == g.player) { Ifc.msg("what, are you _trying_ to break this?"); return false; } if (who.ai != who.PET) { Ifc.you("don't think "+Ifc.the_mon(who)+" would let you.\n"); return false; } if (who.inventory.isEmpty()) { Ifc.you("has nothing to take.", who); return false; } what = Ifc.choice_itm("Take what from " + Ifc.the_mon(who) + "?", who.inventory); if (what == null) return false; if (what.worn) { Ifc.you("|is| wearing that.\n", who); return false; } if (what.wielded) { Ifc.you("|is| holding that.\n", who); return false; } who.drop(what); g.player.pick_up(what); } else { if (who == g.player) { Ifc.msg("what, are you _trying_ to break this?"); return false; } if (who.ai != who.PET) { Ifc.msg("You can only give items to allies.\n"); return false; } if (g.player.inventory.isEmpty()) { Ifc.you("have nothing to give.", who); return false; } what = Ifc.choice_itm("Give what to " + Ifc.the_mon(who) + "?", g.player.inventory); if (what == null) return false; if (what.worn) { Ifc.you("|is| wearing that.\n"); return false; } if (what.wielded) { Ifc.you("|is| holding that.\n"); return false; } g.player.drop(what); who.pick_up(what); } break; case 'a': who = Ifc.choice_mon("Attack what creature? ", g.here.mons); if (who == null) return false; if (who == g.player) return false; if (who.ai == who.PET) { Ifc.you("wouldn't dare hurt your "+(who.species.smart? "friend" : "pet")+"!"); return false; } if (who.i_like(g.player) && who.ai != Mon.ATTACKING) if (Ifc.yn("Really? " + Ifc.the_mon(who) + " means you no harm.")) ++g.player.peacefuls; else return false; Ifc.you("attack the " + who.species.name + "!"); if (g.player.species.special != null && g.player.species.usable_special && g.player.species.special.usep(g.player,who)) { g.player.species.special.doSpecial(g.player, who); } if (!g.player.do_attack(who)) Ifc.you("miss " + Ifc.him(who) + "!"); if (who.hp <= 0 && who.species.human && g.player.species.human) Ifc.you("worry that someone might find out about this..."); break; case 'u': if (g.player.inventory.size() == 0) { Ifc.you("haven't anything to use."); return false; } what = Ifc.choice_itm("Use what thing?", g.player.inventory); if (what == null) return false; if (what.special == null) { Ifc.you("can't use that in this way."); return false; } else return g.player.use(what); case 'v': where = Ifc.gnsew("Look in which direction?", g.here); Ifc.you("see "+(where.unique? "the " : "a ")+where.name+"."); look(where); break; case 'm': Map.show(g.here, 79, 23, used_debug, 0); Ifc.pk(); return false; case '#': g.tall = !g.tall; Ifc.msg("Toggeled tall mode: " + g.tall); return false; case 'o': g.glide = Ifc.gnsew("Glide in which direction?", g.here); g.glidetrigger = false; return do_glide(); case '.': case ' ': Ifc.you("stand around uselessly."); break; default: Ifc.msg("Invalid command!"); return false; } return true; } }