package th; import java.util.Vector; class Boiler_Room extends Node { public Boiler_Room() { super(); special_symbol = "%"; color = Ifc.BRIGHT_RED; int f, i; description = "This boiler room is the heart of the steam tunnels.\n" + "The maze extends outward from this fiery core."; name = "Boiler Room"; unique = true; tunnel = false; } } class Coffee_Shop extends Node { private static Kind[] coffee_items = { Items.mcookie, Items.cookie, Items.cookie, Items.novel, Items.novel, Items.coffee, Items.coffee, Items.chocolate, Items.chocolate, Items.textbook }; public Coffee_Shop () { super(); int f, i; special_symbol = "S"; color = Ifc.BRIGHT_YELLOW; tunnel = false; description = "It's simply a modern coffee house frequented by the more artsy students."; name = "Coffee House"; i = 0; f = Utl.d(5); while (i++ < f) { add(Species.artsie.make()); add(Utl.rn(coffee_items).make()); } add(Species.beatnik.make()); } } class Entrance extends Node { public Entrance() { super(); int f, i; special_symbol = "#"; description = "Above you, a single shaft of sunlight penetrates the abyss you\n" +"now stand in. Before you lie the steam tunnels. There is no turning back now.\n"; name = "Entrance Vault"; unique = true; tunnel = false; color = Ifc.BRIGHT_BLUE; } public void add(Mon m) { m.here = this; if (m == g.player) { visited = true; g.here = this; if (g.player.inventory.contains(g.artifact)) { Ifc.msg("At last, your victorious quest can now be completed."); if (Ifc.yn("Would you like to leave the tunnels and win?")) Tunnels.win(); else Ifc.msg("Re-enter with the " + g.artifact.kind.name + " when you are ready."); } } mons.add((Object)m); } } class Region_Bridge extends Node { public Region_Bridge(Node n) { super(); special_symbol = "&"; description = "You are at a staircase in the steam tunnels. One way leads \n" + "back out into the winding maze and one way leads deeper in."; name = "Stairs Down"; unique = true; tunnel = false; color = Ifc.BRIGHT_RED; bridge = true; north = n.north; south = n.south; east = n.east; west = n.west; if (north != null) north.south = this; if (south != null) south.north = this; if (east != null) east.west = this; if (west != null) west.east = this; mons = n.mons; items = n.items; x = n.x; y = n.y; } } class Zeius_MonSpecial extends MonSpecial { public void after_die(Mon self, Mon killer, Node location) { Ifc.msg("Suzie: 'What?'"); if (killer == g.player) { g.bonus += 100; g.special_merits.add(" Battled with Suzie"); } Mon ueberzeius = Species.enemesis.make(); Ifc.msg(Ifc.color(Ifc.MAJOR_RED) +"Suddenly, Suzie reappears, surrounded by a dark aura.\n" +"Suzie: `Ack! The artifact! You're more powerful that I thought," +"but no matter.\nBehold the true extent of my powers, including but by no\n" +"means limited to a much cooler title!'"+Ifc.color() ); Ifc.pk(); ueberzeius.special = new eZeius_MonSpecial(); ueberzeius.ai = ueberzeius.ATTACKING; location.add(ueberzeius); } } class eZeius_MonSpecial extends MonSpecial { public void die(Mon self, Mon killer, Node location) { Ifc.msg("Suzie: 'NOOOOOOOO!!'"); if (killer == g.player) { ++g.killed_zeius; g.special_merits.add(" You were the destroyer of Suzie"); } else if (killer != null) { Ifc.msg("Suzie was killed by "+killer.describe()+"!"); } } } class Evil_Lab extends Node { private Kind[] ARTIFACTS = { Items.zaurus, Items.pen, Items.nerf_sword }; public Evil_Lab() { super(); int f, i; color = Ifc.MAJOR_YELLOW; special_symbol = "X"; description = "This evil lab is filled with the remains of vile\n" + "experiments. There is an evil aura here."; name = "Mad Lab Tech's Lair"; unique = true; Mon nem = Species.nemesis.make(); g.artifact = ARTIFACTS[g.major].make(); locked = true; nem.inventory.add(g.artifact); nem.special = new Zeius_MonSpecial(); tunnel = false; add(nem); } } class Champion_Hall extends Node { public Champion_Hall() { super(); int f, i; special_symbol = "H"; color = Ifc.BRIGHT_YELLOW; description = "Statues of great warriors line the walls of this room."; name = "Hall of Champions"; unique = true; locked = true; tunnel = false; add(Species.champion.make()); } } class Programmer_Tower extends Node { public Programmer_Tower() { super(); int f, i; locked = true; color = Ifc.BRIGHT_CYAN; special_symbol = "T"; description = "This strange room contains all kinds of strange machines."; name = "Programmer's Tower"; tunnel = false; unique = true; add(Species.programmer.make()); } } class Cube_Lair extends Node { private static Kind[] items = Items.all_items; public Cube_Lair() { super(); int f, i; color = Ifc.CYAN; special_symbol = "C"; description = "This is the lair of several gelatinous cubes."; tunnel = false; name = "Ooze Lair"; i = 0; f = Utl.d(4); while (i++ < f) { add(Species.gelatinous_cube.make()); add(Utl.rn(items).make()); } } } class Pikachu_Nest extends Node { private static Kind[] items = Items.corpses; public Pikachu_Nest() { super(); int f, i; color = Ifc.YELLOW; special_symbol = "P"; description = "This filthy warren is a Pikachu spawning ground!"; tunnel = false; name = "Pikachu Nest"; i = 0; f = Utl.d(6); while (i++ < f) { add(Species.pikachu.make()); if (Utl.rn()) add(Utl.rn(items).make()); if (Utl.rn(3) == 0) add (Items.pikachu_egg.make()); } } } class Dank_Cesspool extends Node { private static Kind[] items = { Items.human_corpse, Items.pikachu_corpse, Items.gnome_corpse, Items.dwarf_corpse, Items.mcookie, Items.flask, Items.flask, Items.glass, Items.stick, Items.tattered_rags, Items.rock, Items.filth }; private static Spe[] critters = { Species.crocodile, Species.cat, Species.dog, Species.crocodile, Species.toad, Species.crocodile, Species.toad, Species.amorphous_blob, Species.amorphous_blob,Species.amorphous_blob, Species.amorphous_blob,Species.amorphous_blob }; public Dank_Cesspool() { super(); int f, i; color = Ifc.BLUE; special_symbol = "D"; description = "The smell of death is strong here."; tunnel = false; name = "Dank Cesspool"; i = 0; f = Utl.d(6); while (i++ < f) { add(Utl.rn(critters).make()); if (Utl.rn()) { Itm tmp = Utl.rn(items).make(); tmp.tainted = true; add(tmp); } } add(Items.filth.make()); if (Utl.rn()) add(Items.filth.make()); if (Utl.rn()) add(Items.filth.make()); } } class Internet_Cafe extends Node { private static Kind[] items = { Items.ethernet_cable, Items.ethernet_cable, Items.soda, Items.cookie, Items.chocolate, Items.screwdriver, Items.textbook, Items.coffee }; public Internet_Cafe() { super(); int f, i; special_symbol = "I"; color = Ifc.GREEN; tunnel = false; description = "There is a clandestine internet cafe hidden here!"; name = "Internet Cafe"; i = 0; f = Utl.d(2,4); while (i++ < f) { add(Species.nerd.make()); if (Utl.rn()) add(Species.code_monkey.make()); add(Utl.rn(items).make()); } } } class Hamster_Nest extends Node { private static Kind[] items = { Items.carrot, Items.peanut, Items.hamster_corpse, Items.tattered_rags, Items.fur_scrap }; public Hamster_Nest() { super(); int f, i; tunnel = false; special_symbol = "N"; color = Ifc.BLUE; description = "This is a hamster nest!"; name = "Hamster Nest"; i = 0; f = Utl.d(2,6); while (i++ < f) { add(Species.hamster.make()); add(Utl.rn(items).make()); } if (Utl.rn()) add(Species.pikachu.make()); add(Species.giant_hamster.make()); } } class Locker_Room extends Node { private static Kind[] items = { Items.steroid_pill, Items.steroid_pill, Items.soda, Items.jacket, Items.t_shirt, Items.t_shirt, Items.baseball_bat, Items.ball, Items.ball, Items.pocket_knife, Items.steroid_pill, Items.soda }; public Locker_Room() { super(); int f, i; special_symbol = "R"; description = "This locker room has many lockers, some benches, and showers."; tunnel = false; color = Ifc.RED; name = "Locker Room"; i = 0; f = Utl.d(6); while (i++ < f) { add(Species.jock.make()); add(Utl.rn(items).make()); } add(Species.coach.make()); } } class Gnome_Hive extends Node { private static Kind[] gnome_items = { Items.conical_hat, Items.conical_hat, Items.conical_hat, Items.conical_hat, Items.cloak, Items.stick, Items.flask, Items.sack, Items.mcookie, Items.cloak, Items.wand }; public Gnome_Hive () { super(); int f, i; color = Ifc.MAGENTA; i = 0; f = Utl.d(8); special_symbol = "G"; tunnel = false; description = "This is a gnome hive, filled with gnome nests and gnomish items."; name = "Gnome Hive"; while (i++ < f) { add(Species.gnome.make()); add(Utl.rn(gnome_items).make()); } } /* This is just an example of how a trivial trap might work. * Don't enable it or the game will be messed up by the * hostile gnomes. public boolean do_trap (Mon m, Node old) { Ifc.msg("Beat it, we're sleeping in here."); return false; } */ } class Laboratory extends Node { private static Kind[] lab_items = { Items.scalpel, Items.textbook, Items.textbook, Items.textbook, Items.lab_coat, Items.lab_coat, Items.flask, Items.flask, Items.pencil, Items.pencil, Items.flask, Items.textbook, Items.magnifying_glass }; public Laboratory() { super(); int f, i; color = Ifc.YELLOW; special_symbol = "L"; tunnel = false; if (Utl.rn()) { // normal lab description = "You are in a chemistry laboratory.\nThere are fume-hoods and arcane apparata of various sorts."; name = "Laboratory"; // a mad scientist Mon ms = Species.madsci.make(); ms.rabid = false; add(ms); ms = Species.madsci.make(); ms.rabid = false; if (Utl.rn()) // or two add(ms); f = Utl.d(2,4); // nerds i = 0; while (i++ < f) { add(Species.nerd.make()); } } else { // elf lab name = "Laboratory"; description = "This chemistry laboratory has been trashed by pyrex elves!"; i = 0; f = Utl.d(2,4); // 2d4 pyrex elves while (i++ < f) { add(Species.pyrex_elf.make()); } f = Utl.d(4); // items i = 0; while (i++ < f) { add(Items.human_corpse.make()); add(Items.glass.make()); } } f = Utl.d(6); // items i = 0; while (i++ < f) { add(Utl.rn(lab_items).make()); } } } public class Node { public void finalize () { for (int i = 0; i < mons.size(); ++i) { ((Mon)mons.elementAt(i)).die(null); } } public static Class[] non_unique_special_nodes = { Utl.gclass("Laboratory"), Utl.gclass("Gnome_Hive"), Utl.gclass("Locker_Room"), Utl.gclass("Hamster_Nest"), Utl.gclass("Internet_Cafe"), Utl.gclass("Cube_Lair"), Utl.gclass("Coffee_Shop"), Utl.gclass("Pikachu_Nest"), Utl.gclass("Dank_Cesspool") //Utl.gclass("BadGuyTunnel") }; public static Class[] unique_special_nodes = { Utl.gclass("Programmer_Tower"), Utl.gclass("Champion_Hall")/*, Utl.gclass("Battle_Scene")*/ }; int x, y; // Node coordinates Node north, south, east, west; Vector mons; Vector items; String name, description, family = "Steam Tunnels Proper"; Spe[] spawn = null; boolean unique = false; boolean bridge = false; int region = 0; // Only the player can enter locked rooms. // Once the player enters, the room will be unlocked. // You can"t leave a locked room either. boolean locked = false; String special_symbol = " "; String color = Ifc.DEFAULT_COLOR; boolean visited = false; // Player been here? boolean seen = false; // Been traversed yet? Or, after that, not been traversed? // And so on. The meaning inverts of course each time it is traversed. // boolean trav = false; // presently executing a trap? private boolean in_trap = false; // Tunnel or proper room? boolean tunnel = false; int spawn_chance = 0; // % chance to spawn mon each turn public Node () { mons = new Vector(); items = new Vector(); north = south = east = west = null; name = description = "None provided"; g.nodes.add((Object)this); } // Hook for events. public void do_special(int which, Itm caller, Mon user) { Ifc.msg("Nothing Happens."); } public String describe () { return describe (false); } public String describe (boolean detail) { String tmp = description + "\n" + link_description() + "\n"; switch (mons.size() - 1) { // -1 because the player counts case 0: tmp += "You are alone.\n"; break; case 1: tmp += "There is a creature here:\n"; break; default: tmp += "There are creatures here:\n"; } for (int i = 0; i < mons.size(); ++i) { if (mons.elementAt(i) == g.player) continue; if (detail) tmp += " " + ((Mon)mons.elementAt(i)).detailed_describe() +(g.tall? "\n" : ", "); else tmp += " " + ((Mon)mons.elementAt(i)).describe() +(g.tall? "\n" : ", "); } switch (items.size()) { case 0: //tmp += "There are no items here.\n"; break; case 1: tmp += "There is an item here:\n"; break; default: tmp += "There are some things here:\n"; } for (int i = 0; i < items.size(); ++i) { tmp += " " +((Itm)items.elementAt(i)).describe() + (g.tall? "\n" : ", "); } return tmp; } // Vector interacting so poorly with types is an abomination. public void update () { //for (int i = 0; i < mons.size(); ++i) { //if (mons.elementAt(i) == g.player) continue; //if (((Mon)mons.elementAt(i)).hp <= 0) { //((Mon)mons.elementAt(i)).die(null); //continue; //} // Note that this will wake monsters // this needs to be done when the player enters // the room. //if (((Mon)mons.elementAt(i)).ai != 0 //|| mons.contains(g.player)) //((Mon)mons.elementAt(i)).update(); //} // Maybe create new creture. (Nonempty list) // Spawn chances now in per-mil if (this != g.here && spawn != null && Utl.rn(1000) < spawn_chance) add(Utl.rn(spawn).make()); if (this != g.here && spawn == null && Utl.rn(1000) < spawn_chance) add(Species.good_mon()); // add a mon good for the player"s level } public String link_description() { String tmp = ""; if (north != null) tmp += describe_link(north) + " to the north.\n"; if (south != null) tmp += describe_link(south) + " to the south.\n"; if (east != null) tmp += describe_link(east) + " to the east.\n"; if (west != null) tmp += describe_link(west) + " to the west.\n"; return tmp; } private String describe_link(Node extension) { if (tunnel) if (extension.tunnel) return "The tunnel continues"; else return "The tunnel opens into "+Ifc.color(extension.color) +(extension.unique? "the ":"a ")+extension.name+Ifc.color(); else if (extension.tunnel) return "There is a tunnel"; else return "There is another room, "+(extension.unique? "the ":"a ") +Ifc.color(extension.color)+extension.name+Ifc.color()+", "; } public void add(Mon m) { /*if (g.turns > 0 && !do_trap(m, m.here)) { m.here.add(m); return; }*/ // make sure traps that spawn with the add function don't trigger // recursively. int trap_result = 1; if (g.turns > 0 && !in_trap) { in_trap = true; trap_result = check_trap(m, m.here); if (trap_result == 0) { m.here.add(m); in_trap = false; return; } else in_trap = false; } if (m == g.player) { if (!visited) ++g.visited; visited = true; locked = false; g.here = this; } m.here = this; mons.add((Object)m); if (trap_result == 2) do_trap(m); } public void add(Itm m) { m.here = this; items.add((Object)m); } /* This is the hook for traps in rooms. * Overload this method and replace it by something * more painful. * coming_from - the node from whence the player * came. If you return false, they will be sent * back. Return true to let them pass. * The mon m is in the previous room when this function runs.*/ public int check_trap(Mon m, Node coming_from) { return 1; } public void do_trap(Mon m) { ; } private boolean horizontalp() { return (west != null || east != null); } private boolean verticalp() { return (north != null || south != null); } private static String[] DOS_REPRE = { "\262", //0 "\337", //0001 "\334", //0010 "\272", //0011 and so on "\336", //0100, "\310", // 0101 "\311", // 0110 "\314", // 0111 "\335", // 1000 "\274", // 1001 "\273", // 1010 "\263", // 1011 "\315", // 1100 "\312", // 1101 "\313", // 1110 "\316", // 1111 333 for block "\376", //1 0000 "|", //1 0001 "|", //1 0010 "\263", //1 0011 and so on "-", //1 0100, "\300", // 0101 "\332", // 0110 "\303", // 0111 "-", // 1000 "\331", // 1001 "\227", // 1010 "\264", // 1011 "\304", // 1100 "\301", // 1101 "\302", // 1110 "\305" // 1111 }; // For ye olde VT100 - or other terminal emulators. //nsew wesn private static String[] REPRE = { "\044", //0 "V", //0001 "^", //0010 "\170", //0011 and so on "<", //0100, "\155", // 0101 "\154", // 0110 "\164", // 0111 ">", // 1000 "\152", // 1001 "\153", // 1010 "\165", // 1011 "\161", // 1100 "\166", // 1101 "\167", // 1110 "\156", // 1111 333 for block }; // Return character representation. public String character () { //if (g.player.here == this) //return (Tunnels.VT100? "\251" : "@"); // You are here... //else /* I really like ?:, can you tell? */ if (special_symbol != " ") return special_symbol; else return (Tunnels.gmode != Tunnels.DOS? REPRE : DOS_REPRE)[ (north != null? 1 : 0) + (south != null? 2 : 0) + (east != null? 4 : 0) + (west != null? 8 : 0) + (tunnel && (Tunnels.gmode == Tunnels.DOS)? 16: 0)]; } public String unbiased_character () { return (Tunnels.gmode != Tunnels.DOS? REPRE : DOS_REPRE)[ (north != null? 1 : 0) + (south != null? 2 : 0) + (east != null? 4 : 0) + (west != null? 8 : 0) + (tunnel && (Tunnels.gmode == Tunnels.DOS)? 16: 0)]; } }