├── .gitignore ├── .travis.yml ├── README.md ├── pom.xml └── src ├── main ├── java │ └── mikera │ │ └── tyrant │ │ ├── AI.java │ │ ├── Action.java │ │ ├── ActionMapping.java │ │ ├── Amulet.java │ │ ├── Animal.java │ │ ├── Animation.java │ │ ├── Armour.java │ │ ├── ArtScreen.java │ │ ├── Artifact.java │ │ ├── Aura.java │ │ ├── Being.java │ │ ├── CLabel.java │ │ ├── Caves.java │ │ ├── CharacterScreen.java │ │ ├── Chest.java │ │ ├── Clothing.java │ │ ├── Coin.java │ │ ├── Combat.java │ │ ├── Damage.java │ │ ├── Decoration.java │ │ ├── DeepForest.java │ │ ├── DetailedListScreen.java │ │ ├── Door.java │ │ ├── Dungeon.java │ │ ├── Effect.java │ │ ├── EndGame.java │ │ ├── Equipment.java │ │ ├── Event.java │ │ ├── EventHandler.java │ │ ├── Fire.java │ │ ├── Food.java │ │ ├── Game.java │ │ ├── GameHandler.java │ │ ├── GameScreen.java │ │ ├── GameTile.java │ │ ├── GoblinVillage.java │ │ ├── Gods.java │ │ ├── Graveyard.java │ │ ├── Hero.java │ │ ├── IActionHandler.java │ │ ├── IMessageHandler.java │ │ ├── IThingFilter.java │ │ ├── ImageGadget.java │ │ ├── InfoScreen.java │ │ ├── InputHandler.java │ │ ├── Interface.java │ │ ├── InventoryPanel.java │ │ ├── InventoryScreen.java │ │ ├── IsFilter.java │ │ ├── Item.java │ │ ├── LevelMap.java │ │ ├── LevelMapPanel.java │ │ ├── ListItem.java │ │ ├── ListScreen.java │ │ ├── MapPanel.java │ │ ├── Maze.java │ │ ├── MessagePanel.java │ │ ├── Missile.java │ │ ├── Monster.java │ │ ├── Movement.java │ │ ├── Name.java │ │ ├── NameFilter.java │ │ ├── OrFilter.java │ │ ├── Outdoors.java │ │ ├── Person.java │ │ ├── Personality.java │ │ ├── Pit.java │ │ ├── Poison.java │ │ ├── Portal.java │ │ ├── PortalStone.java │ │ ├── Potion.java │ │ ├── Quest.java │ │ ├── QuestApp.java │ │ ├── QuestApplication.java │ │ ├── RangedWeapon.java │ │ ├── Recipe.java │ │ ├── Ring.java │ │ ├── RogueDungeon.java │ │ ├── RogueLikeFilter.java │ │ ├── Rune.java │ │ ├── RuneTrap.java │ │ ├── Scenery.java │ │ ├── Score.java │ │ ├── Screen.java │ │ ├── Scripts.java │ │ ├── Scroll.java │ │ ├── Secret.java │ │ ├── Skill.java │ │ ├── Special.java │ │ ├── Spell.java │ │ ├── SpellBook.java │ │ ├── StatusPanel.java │ │ ├── TPanel.java │ │ ├── TTextArea.java │ │ ├── Temple.java │ │ ├── TextZone.java │ │ ├── Theme.java │ │ ├── Tile.java │ │ ├── Time.java │ │ ├── TitleScreen.java │ │ ├── Town.java │ │ ├── Trap.java │ │ ├── Tutorial.java │ │ ├── Wand.java │ │ ├── Weapon.java │ │ ├── Wish.java │ │ ├── WorldMap.java │ │ ├── author │ │ ├── Designer.java │ │ ├── MapMaker.java │ │ ├── ThingEditor.java │ │ └── ThingMaker.java │ │ ├── engine │ │ ├── BaseObject.java │ │ ├── Describer.java │ │ ├── Description.java │ │ ├── Lib.java │ │ ├── Map.java │ │ ├── Modifier.java │ │ ├── Point.java │ │ ├── RPG.java │ │ ├── Script.java │ │ ├── StringList.java │ │ ├── Thing.java │ │ └── ThingOwner.java │ │ └── util │ │ ├── Count.java │ │ ├── LibMetaData.java │ │ ├── LibMetaDataHandler.java │ │ ├── MetaData.java │ │ ├── MetaDataEntry.java │ │ ├── PlugInUtility.java │ │ ├── PrintfFormat.java │ │ ├── Text.java │ │ ├── TyrantException.java │ │ ├── example_plugin.xml │ │ ├── tyrantLibraryItems.xsl │ │ └── tyrantLibrarySpecification.xsl └── resources │ ├── images │ ├── .cvsignore │ ├── Tyrant-Header.jpg │ ├── cancel.png │ ├── creature32.png │ ├── effects32.png │ ├── favicon.ico │ ├── hero.ico │ ├── isOverlay.gif │ ├── items32.png │ ├── plus.gif │ ├── scenery32.png │ ├── texture1.png │ ├── texture2.png │ ├── texture3.png │ ├── tiles32.png │ └── title.png │ ├── maps │ ├── special │ │ ├── dwarftown.txt │ │ ├── firetop.txt │ │ ├── grotto.txt │ │ └── woodfort.txt │ ├── temples │ │ └── yanthrall.txt │ ├── test │ │ └── testmap.txt │ └── world │ │ ├── annenvale.txt │ │ ├── doom.txt │ │ ├── karrain.txt │ │ └── wilds.txt │ └── version.txt └── test └── java └── mikera └── tyrant ├── perf ├── CreateLib.java ├── IThingsInspector.java ├── IWork.java ├── KillAllBaddies.java ├── LibInspector.java ├── Lib_Perf.java ├── MoreKilling.java ├── Perf.java └── SizeOfLib.java └── test ├── MapHelper.java ├── NullHandler.java ├── TestAction.java ├── TestActionMapping.java ├── TestAnimal.java ├── TestArtifact.java ├── TestBeing.java ├── TestCoin.java ├── TestCombat.java ├── TestDamage.java ├── TestDescriber.java ├── TestDoor.java ├── TestFilters.java ├── TestFood.java ├── TestGame.java ├── TestGameHandler.java ├── TestHero.java ├── TestItem.java ├── TestLOS.java ├── TestLib.java ├── TestMap.java ├── TestMapHelper.java ├── TestMapMaker.java ├── TestModifier.java ├── TestMonster.java ├── TestMovement.java ├── TestNullHandler.java ├── TestPortal.java ├── TestPotion.java ├── TestProperties.java ├── TestQuest.java ├── TestScenery.java ├── TestScripts.java ├── TestSpell.java ├── TestText.java ├── TestThing.java ├── TestThingMaker.java ├── TestTown.java ├── TestWorldMap.java └── TyrantTestCase.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.project 2 | .settings 3 | .classpath 4 | /target 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk7 4 | - openjdk7 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tyrant 2 | 3 | A classic graphical roguelike game written in Java. 4 | 5 | Tyrant was first written in 1997, and has been slowly extended ever since. 6 | 7 | ### Interesting Features 8 | 9 | - Graphical roguelike with a custom 32x32 tileset 10 | - A very flexible and configurable dynamic object model -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | tyrant 5 | 1.0.0-SNAPSHOT 6 | 7 | 8 | net.mikera 9 | mikera-pom 10 | 0.0.3 11 | 12 | 13 | 14 | scm:git:git@github.com:mikera/${project.artifactId}.git 15 | scm:git:git@github.com:mikera/${project.artifactId}.git 16 | scm:git:git@github.com:mikera/${project.artifactId}.git 17 | 18 | 19 | 20 | 21 | junit 22 | junit 23 | 4.13.1 24 | test 25 | 26 | 27 | com.jgoodies 28 | forms 29 | 1.3.0 30 | 31 | 32 | net.mikera 33 | mikera 34 | 1.5.1 35 | 36 | 37 | net.mikera 38 | mathz 39 | 0.1.0 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.apache.maven.plugins 47 | maven-compiler-plugin 48 | 49 | 1.7 50 | 1.7 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-jar-plugin 56 | 57 | 58 | 59 | mikera.tyrant.QuestApplication 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | clojars.org 70 | Clojars repository 71 | https://clojars.org/repo 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Action.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | 8 | public class Action implements Serializable { 9 | private static final long serialVersionUID = 1L; 10 | 11 | private static int nextId = 0; 12 | 13 | //Movement 14 | public static final Action UNKNOWN = new Action("Unknown"); 15 | public static final Action MOVE_N = new Action("N"); 16 | public static final Action MOVE_NE = new Action("NE"); 17 | public static final Action MOVE_E = new Action("E"); 18 | public static final Action MOVE_SE = new Action("SE"); 19 | public static final Action MOVE_S = new Action("S"); 20 | public static final Action MOVE_SW = new Action("SW"); 21 | public static final Action MOVE_W = new Action("W"); 22 | public static final Action MOVE_NW = new Action("NW"); 23 | public static final Action MOVE_NOWHERE = new Action("."); 24 | 25 | //Actions 26 | public static final Action APPLY_SKILL = new Action("apply skill"); 27 | public static final Action CHAT = new Action("chat"); 28 | public static final Action DROP = new Action("drop"); 29 | public static final Action EAT = new Action("eat"); 30 | public static final Action FIRE = new Action("fire"); 31 | public static final Action GIVE = new Action("give"); 32 | public static final Action INVENTORY = new Action("inventory"); 33 | public static final Action JUMP = new Action("jump"); 34 | public static final Action KICK = new Action("kick"); 35 | public static final Action LOOK = new Action("look"); 36 | public static final Action MESSAGES = new Action("messages"); 37 | public static final Action OPEN = new Action("open"); 38 | public static final Action PICKUP = new Action("pickup"); 39 | public static final Action QUAFF = new Action("quaff"); 40 | public static final Action READ = new Action("read"); 41 | public static final Action SEARCH = new Action("search"); 42 | public static final Action THROW = new Action("throw"); 43 | public static final Action USE = new Action("use"); 44 | public static final Action VIEW_STATS = new Action("view_stats"); 45 | public static final Action WIELD = new Action("wield"); 46 | public static final Action WAIT = new Action("wait"); 47 | public static final Action EXIT = new Action("exit"); 48 | public static final Action PRAY = new Action("pray"); 49 | public static final Action PRAY2 = new Action("pray2"); 50 | public static final Action ZAP = new Action("zap"); 51 | public static final Action ZAP_AGAIN = new Action("zap_again"); 52 | public static final Action HELP = new Action("help"); 53 | public static final Action SELECT_TILE = new Action("select_tile"); 54 | public static final Action SAVE_GAME = new Action("save"); 55 | public static final Action LOAD_GAME = new Action("load"); 56 | public static final Action QUIT_GAME = new Action("quit"); 57 | public static final Action SHOW_QUESTS = new Action("show_quests"); 58 | public static final Action DEBUG = new Action("debug"); 59 | public static final Action ZOOM_OUT = new Action("zoom"); 60 | public static final Action ZOOM_IN = new Action("zoom"); 61 | 62 | public static final Action OK = new Action("ok"); 63 | public static final Action CANCEL = new Action("cancel"); 64 | 65 | public static final Action DROP_EXTENDED = new Action("drop_extended"); 66 | public static final Action PICKUP_EXTENDED = new Action("pickup_extended"); 67 | 68 | private String name; 69 | private int id; 70 | 71 | private static Map allById; 72 | 73 | public Action(String name) { 74 | this(name, nextId++); 75 | } 76 | 77 | public Action(String name, int id) { 78 | this.name = name; 79 | this.id = id; 80 | getAllById().put(new Integer(id), this); 81 | } 82 | 83 | private Map getAllById() { 84 | if(allById == null) 85 | allById = new HashMap<>(); 86 | return allById; 87 | } 88 | 89 | public String toString() { 90 | return name; 91 | } 92 | 93 | public Object readResolve() { 94 | return allById.get(new Integer(id)); 95 | } 96 | 97 | public boolean isMovementKey() { 98 | return 99 | this == Action.MOVE_E || this == Action.MOVE_N || 100 | this == Action.MOVE_NE || this == Action.MOVE_NW || 101 | this == Action.MOVE_S || this == Action.MOVE_SE || 102 | this == Action.MOVE_SW || this == Action.MOVE_W; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Animal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 19-Jul-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import mikera.tyrant.engine.Lib; 9 | import mikera.tyrant.engine.RPG; 10 | import mikera.tyrant.engine.Thing; 11 | 12 | /** 13 | * @author Mike 14 | * 15 | * Animals are wild creatures that can be hunted 16 | * 17 | */ 18 | public class Animal { 19 | public static void init() { 20 | Thing t; 21 | 22 | // base monster template 23 | t=Lib.extend("base animal", "base being"); 24 | t.set("IsMonster",0); 25 | t.set(RPG.ST_AIMODE,"Evade"); 26 | t.set("IsHostile",0); 27 | t.set("IsAnimal",1); 28 | t.set("Frequency",50); 29 | t.set("IsIntelligent",0); 30 | t.set("LevelMin",1); 31 | t.set("LevelMax",100); 32 | t.set("XPValue",5); 33 | Lib.add(t); 34 | 35 | initWildLife(); 36 | } 37 | 38 | public static Thing create(int level) { 39 | // TODO: make specific for terrain types 40 | Thing t=Lib.createType("IsAnimal",level); 41 | return t; 42 | } 43 | 44 | public static void initWildLife() { 45 | Thing t; 46 | 47 | t=Lib.extend("rabbit", "base animal"); 48 | t.set("IsHostile",0); 49 | t.set("Image",285); 50 | t.set("IsOwned",1); 51 | t.set("MoveSpeed",140); 52 | Monster.stats(t,3,2,15,3,1,2,1,1); 53 | t.set("DeathDecoration","piece of rabbit meat"); 54 | Lib.add(t); 55 | 56 | t=Lib.extend("hare","rabbit"); 57 | t.set("MoveSpeed",240); 58 | Monster.stats(t,3,2,25,3,1,2,1,1); 59 | t.set("DeathDecoration","piece of hare meat"); 60 | Lib.add(t); 61 | 62 | t=Lib.extend("butterfly", "base animal"); 63 | t.set("IsHostile",0); 64 | t.set("IsBlocking",0); 65 | t.set("Image",294); 66 | t.set("IsItem",1); 67 | t.set("DeathDecoration",null); 68 | t.set("ItemWeight",100); 69 | Monster.stats(t,1,1,5,1,1,1,1,1); 70 | Lib.add(t); 71 | 72 | t=Lib.extend("snail", "base animal"); 73 | t.set("IsHostile",0); 74 | t.set("IsOwned",1); 75 | t.set("Image",387); 76 | t.set("MoveSpeed",40); 77 | Monster.stats(t,1,1,5,1,1,1,1,1); 78 | t.set("DeathDecoration","slime pool"); 79 | Lib.add(t); 80 | 81 | t=Lib.extend("escargot", "base animal"); 82 | t.set("IsHostile",0); 83 | t.set("IsOwned",1); 84 | t.set("Image",387); 85 | t.set("MoveSpeed",40); 86 | Monster.stats(t,1,1,5,1,1,1,1,1); 87 | t.set("DeathDecoration","escargot steak"); 88 | t.set("ASCII", "e"); 89 | Lib.add(t); 90 | 91 | t=Lib.extend("slug", "base animal"); 92 | t.set("IsHostile",0); 93 | t.set("Image",386); 94 | t.set("MoveSpeed",40); 95 | Monster.stats(t,1,1,5,1,1,1,1,1); 96 | t.set("DeathDecoration","poison cloud"); 97 | Lib.add(t); 98 | 99 | t=Lib.extend("flutterby","butterfly"); 100 | t.set("DecayRate",1000); 101 | t.addHandler("OnAction",Scripts.decay()); 102 | Lib.add(t); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/ArtScreen.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.GridLayout; 5 | import java.awt.event.KeyEvent; 6 | 7 | import mikera.tyrant.engine.RPG; 8 | import mikera.tyrant.engine.Thing; 9 | import mikera.tyrant.util.Text; 10 | 11 | public class ArtScreen extends Screen { 12 | private static final long serialVersionUID = 3257568408080953650L; 13 | String title = "List"; 14 | Thing[] arts = null; 15 | static int page = 0; 16 | 17 | private static int pagesize = 13; 18 | private static int lineheight = 20; 19 | 20 | public Thing getArt() { 21 | while (true) { 22 | KeyEvent k = Game.getInput(); 23 | 24 | if (k.getKeyCode() == KeyEvent.VK_ESCAPE) 25 | return null; 26 | 27 | char c = Character.toLowerCase(k.getKeyChar()); 28 | 29 | if ((c == 'p') && (page > 0)) { 30 | page--; 31 | repaint(); 32 | } 33 | 34 | if ((c == 'n' || c == ' ') 35 | && (((page + 1) * pagesize) < arts.length)) { 36 | page++; 37 | repaint(); 38 | } 39 | 40 | int kv = c - 'a'; 41 | if ((kv >= 0) && (kv < pagesize)) { 42 | kv = kv + page * pagesize; 43 | if ((kv >= 0) && (kv < arts.length)) 44 | return arts[kv]; 45 | } 46 | } 47 | } 48 | 49 | public ArtScreen(String s, Thing[] thearts) { 50 | super(Game.getQuestapp()); 51 | setLayout(new GridLayout(15, 1)); 52 | 53 | setForeground(QuestApp.INFOTEXTCOLOUR); 54 | setBackground(QuestApp.INFOSCREENCOLOUR); 55 | setFont(QuestApp.mainfont); 56 | 57 | // get the things 58 | arts = thearts; 59 | if (arts == null) 60 | arts = new Thing[0]; 61 | 62 | // set the list title 63 | title = s; 64 | } 65 | 66 | public void paint(Graphics g) { 67 | if ((page * pagesize) > arts.length) 68 | page = 0; 69 | 70 | g.drawString(title, 20, 1 * lineheight); 71 | 72 | for (int i = 0; i < Math.min(arts.length - (page * pagesize), pagesize); i++) { 73 | Thing t = arts[i + page * pagesize]; 74 | String s = "[" + (char) ('a' + i) + "] " + t.getName(Game.hero()); 75 | 76 | g.drawString(s, 50, lineheight * (i + 2)); 77 | } 78 | 79 | String bottomstring = "ESC=Cancel "; 80 | if (page > 0) 81 | bottomstring = bottomstring + " P=Previous "; 82 | if (((page + 1) * pagesize) < arts.length) 83 | bottomstring = bottomstring + " N=Next "; 84 | String powerstring = "Power: " + Game.hero().getStat(RPG.ST_MPS) + " / " 85 | + Game.hero().getStat(RPG.ST_MPSMAX); 86 | g.drawString(Text.centrePad(bottomstring, powerstring, 55), 20, 87 | getSize().height - 10); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Aura.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.Modifier; 5 | import mikera.tyrant.engine.Thing; 6 | 7 | public class Aura { 8 | public static void init() { 9 | Thing t; 10 | 11 | t=Lib.extend("base aura","base special"); 12 | t.set("IsAura",1); 13 | t.set("IsWishable",1); 14 | t.set("IsInvisible",1); 15 | t.set("Image",145); 16 | Lib.add(t); 17 | 18 | t=Lib.extend("speed aura","base aura"); 19 | { 20 | Modifier m=Modifier.bonus("Speed",10); 21 | m.set("ApplyMessage","You feel nimble and quick"); 22 | t.add("LocationModifiers",m); 23 | } 24 | Lib.add(t); 25 | 26 | t=Lib.extend("luck aura","base aura"); 27 | { 28 | Modifier m=Modifier.bonus("Luck",20); 29 | m.set("ApplyMessage","You feel lucky"); 30 | t.add("LocationModifiers",m); 31 | } 32 | Lib.add(t); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/CLabel.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Component; 4 | import java.awt.Dimension; 5 | import java.awt.Graphics; 6 | import java.awt.Image; 7 | 8 | public class CLabel extends Component { 9 | private static final long serialVersionUID = 3258416114332807730L; 10 | private String text; 11 | 12 | public CLabel(String text) { 13 | this.text = text; 14 | } 15 | 16 | public void setText(String text) { 17 | this.text = text; 18 | repaint(); 19 | } 20 | 21 | public String getText() { 22 | return text; 23 | } 24 | 25 | public void paint(Graphics g) { 26 | super.paint(g); 27 | g.drawString(text, 20, 0); 28 | } 29 | 30 | public Dimension getMinimumSize() { 31 | Image image = QuestApp.paneltexture; 32 | 33 | if (image == null) { 34 | return new Dimension(16, 16); 35 | } 36 | return new Dimension(image.getWidth(null), image.getHeight(null)); 37 | } 38 | 39 | public Dimension getPreferredSize() { 40 | return getMinimumSize(); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Chest.java: -------------------------------------------------------------------------------- 1 | // 2 | // A chest, possibly trapped, possibly containing something useful 3 | // 4 | 5 | package mikera.tyrant; 6 | 7 | import mikera.tyrant.engine.Lib; 8 | import mikera.tyrant.engine.Map; 9 | import mikera.tyrant.engine.Point; 10 | import mikera.tyrant.engine.RPG; 11 | import mikera.tyrant.engine.Script; 12 | import mikera.tyrant.engine.Thing; 13 | import mikera.util.Maths; 14 | import mikera.util.Rand; 15 | 16 | public class Chest { 17 | // create a chest 18 | // value determines usefulness of contents.... 19 | // ....and also potential danger of traps involved 20 | public static Thing create(int l) { 21 | Thing t=Lib.createType("IsChest",l); 22 | 23 | return t; 24 | } 25 | 26 | public static class ChestDamage extends Script { 27 | private static final long serialVersionUID = 4121411791663740466L; 28 | 29 | public boolean handle(Thing t, Event e) { 30 | Thing[] ts=t.getFlaggedContents("IsTrap"); 31 | Map m=t.getMap(); 32 | 33 | Thing a=e.getThing("Actor"); 34 | 35 | for (int i=0; i0; i--) { 61 | t.addThing(Lib.createItem(l+Rand.r(5))); 62 | } 63 | if (RPG.test(l,10)) t.addThing(Trap.createTrap(l)); 64 | return false; 65 | } 66 | } 67 | 68 | public static class ChestClosed extends Script { 69 | private static final long serialVersionUID = 3256718494266373688L; 70 | 71 | public boolean handle(Thing t, Event e) { 72 | // TODO 73 | return false; 74 | } 75 | } 76 | 77 | public static class ChestOpen extends Script { 78 | private static final long serialVersionUID = 4120851040649491762L; 79 | 80 | public boolean handle(Thing t, Event e) { 81 | Thing[] ts=t.getItems(); 82 | Score.scoreExplore(t); 83 | for (int i=0; i 0 ){ 49 | currentchoice--; 50 | repaint(); 51 | } 52 | return null; 53 | } 54 | 55 | if( c == '2' || k.getKeyCode() == KeyEvent.VK_DOWN ){ 56 | currentchoice++; 57 | if( currentchoice + page * pagesize < strings.length){ 58 | repaint(); 59 | }else{ 60 | currentchoice--; 61 | } 62 | } 63 | //Game.warn(Character.toString(c)); 64 | 65 | if ((c == 'p' || c == '-') && (page > 0)) { 66 | page--; 67 | repaint(); 68 | currentchoice = 0; 69 | } 70 | 71 | if ((c == 'n' || c == '+' || c == ' ') 72 | && (((page + 1) * pagesize) < strings.length)) { 73 | page++; 74 | repaint(); 75 | currentchoice = 0; 76 | } 77 | 78 | 79 | 80 | int kv = c - 'a'; 81 | if ((kv >= 0) && (kv < pagesize)) { 82 | kv = kv + page * pagesize; 83 | if ((kv >= 0) && (kv < strings.length)) 84 | return strings[kv]; 85 | } 86 | } 87 | } 88 | return null; 89 | } 90 | 91 | public void activate() { 92 | // questapp.setKeyHandler(keyhandler); 93 | } 94 | 95 | private static String[] getStringArray(Collection c) { 96 | String[] ss=new String[c.size()]; 97 | Iterator it=c.iterator(); 98 | int i=0; 99 | while (it.hasNext()) { 100 | ss[i++]=it.next(); 101 | } 102 | return ss; 103 | } 104 | 105 | public DetailedListScreen(String s, Collection c1 , Collection c2) { 106 | this(s,getStringArray(c1),getStringArray(c2)); 107 | } 108 | 109 | public DetailedListScreen(String s, String[] invstrings, String[] detailstrings) { 110 | super(Game.getQuestapp()); 111 | setLayout(new GridLayout(15, 1)); 112 | setFont(QuestApp.mainfont); 113 | 114 | addKeyListener(questapp.keyadapter); 115 | 116 | // get the strings 117 | strings = invstrings; 118 | details = detailstrings; 119 | if (strings == null) 120 | strings = new String[0]; 121 | 122 | // set the list title 123 | title = s; 124 | } 125 | 126 | public void paint(Graphics g) { 127 | super.paint(g); 128 | 129 | if ((page * pagesize) > strings.length) 130 | page = 0; 131 | 132 | Dimension d = getSize(); 133 | 134 | g.setColor(QuestApp.INFOTEXTCOLOUR); 135 | 136 | g.drawString(title, leftborder , 1 * lineheight); 137 | 138 | for (int i = 0; i < Math.min(strings.length - (page * pagesize), 139 | pagesize); i++) { 140 | String t = strings[i + page * pagesize]; 141 | String s = "[" + (char) ('a' + i) + "] " + Text.properCase( t ); 142 | //Make sure the current selection gets highlighted 143 | g.setColor( i==currentchoice?selectionColor:QuestApp.INFOTEXTCOLOUR ); 144 | g.drawString(s, 50, lineheight * (i + 2)); 145 | } 146 | //Make sure that detail and bottom is in proper color 147 | g.setColor( QuestApp.INFOTEXTCOLOUR ); 148 | //Draw detail string 149 | //Detail is not allowed to take more than 3 lines for now 150 | String[] detaillines = Text.wrapString(details[currentchoice], TextZone.linelength); 151 | for( int i = 0; i < ( detaillines.length ) ; i++ ){ 152 | g.drawString( detaillines[i] , leftborder , d.height - lineheight * (2 + detaillines.length - i) ); 153 | } 154 | //Draw bottom string 155 | String bottomstring = bottomString+" "; 156 | if (page > 0) 157 | bottomstring = bottomstring + " Up = Previous "; 158 | if (((page + 1) * pagesize) < strings.length) 159 | bottomstring = bottomstring + " Down = Next "; 160 | g.drawString(bottomstring, leftborder , d.height - lineheight); 161 | } 162 | 163 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/EndGame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 08-Dec-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import mikera.tyrant.engine.Lib; 9 | import mikera.tyrant.engine.Map; 10 | import mikera.tyrant.engine.Script; 11 | import mikera.tyrant.engine.Thing; 12 | 13 | /** 14 | * @author Mike 15 | * 16 | * To change the template for this generated type comment go to 17 | * Window - Preferences - Java - Code Generation - Code and Comments 18 | */ 19 | public class EndGame { 20 | public static Map getFinalMap() { 21 | Map m=new Map(21,41); 22 | m.setTheme("metal"); 23 | m.set("Level",30); 24 | m.set("Description","The Tyrant's Throne Room"); 25 | m.set("EnterMessage","\"Prepare to DIE, puny mortal!!\""); 26 | 27 | m.fillArea(0,0,20,40,m.wall()); 28 | m.fillArea(1,1,19,19,Tile.LAVA); 29 | m.fillOval(5,7,15,13,m.floor()); 30 | m.fillArea(9,10,11,39,m.floor()); 31 | 32 | // the tyrant!!! 33 | m.addThing(Lib.create("The Tyrant"),10,10); 34 | 35 | // base room 36 | m.fillArea(1,21,19,39,m.floor()); 37 | for (int i=22; i<=39; i+=2) { 38 | m.addThing("demon vortex",7,i); 39 | m.addThing("demon vortex",13,i); 40 | } 41 | 42 | // the entrance 43 | m.addEntrance("stairs down"); 44 | 45 | return m; 46 | } 47 | 48 | public static void init() { 49 | Thing t=Lib.extendNamed("The Tyrant","human"); 50 | Monster.stats(t,300,200,250,300,100,300,100,150); 51 | t.set("ARM",400); 52 | Monster.strengthen(t,0.6); // low power right now 53 | t.set("IsHostile",1); 54 | t.set("MoveSpeed",200); 55 | t.set("AttackSpeed",200); 56 | t.set("Image",503); 57 | t.set(Skill.UNARMED,2); 58 | t.set(Skill.ATTACK,3); 59 | t.set(Skill.DEFENCE,4); 60 | t.set(Skill.CASTING,4); 61 | t.set(Skill.TRUEMAGIC,5); 62 | t.set(Skill.MAGICRESISTANCE,4); 63 | t.set(Skill.BRAVERY,5); 64 | t.set("RES:fire",1000); 65 | t.set("IsDisplaceable",0); 66 | t.set("DefaultThings","The Tyrant's Mace,The Tyrant's Armour,[IsSpell],[IsSpell],[IsSpell],[IsSpell],[IsSpell],[IsSpell]"); 67 | t.set("LevelMin",30); 68 | t.set("Luck",100); 69 | t.set("ASCII","T"); 70 | t.addHandler("OnDeath",new Script() { 71 | private static final long serialVersionUID = 1L; 72 | 73 | public boolean handle(Thing t,Event e) { 74 | Game.over=true; 75 | return false; 76 | } 77 | }); 78 | Lib.add(t); 79 | 80 | t=Lib.extendNamed("Bel-Gorimoth","master voidling"); 81 | Monster.stats(t,2000,2000,2000,3000,1500,3000,1000,3000); 82 | t.set("Armour",2000); 83 | t.set(Skill.UNARMED,5); 84 | t.set(Skill.ATTACK,5); 85 | t.set(Skill.DEFENCE,5); 86 | t.set(Skill.CASTING,20); 87 | t.set(Skill.FOCUS,10); 88 | t.set(Skill.TRUEMAGIC,5); 89 | t.set(Skill.MAGICRESISTANCE,6); 90 | t.set(Skill.BRAVERY,10); 91 | t.set("Luck",200); 92 | t.set("Speed",200); 93 | t.set("AttackSpeed",300); 94 | t.set("MoveSpeed",300); 95 | t.set("UnarmedWeapon",Lib.create("disintegrate attack")); 96 | Lib.add(t); 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Event.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 19-Jun-2004 3 | * 4 | * To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Generation - Code and Comments 6 | */ 7 | package mikera.tyrant; 8 | 9 | import mikera.tyrant.engine.BaseObject; 10 | 11 | /** 12 | * @author Mike 13 | * 14 | * Events are created to notify game objects about 15 | * occurences in the game that they may need to respond to 16 | * 17 | * Typical usage: 18 | * 19 | * Thing t=.... 20 | * 21 | * if (t.handles("OnAction")) { 22 | * Event e=new Event("Action"); 23 | * e.set("SomeProperty",10); 24 | * e.set("SomeOtherProperty","Hello"); 25 | * t.handle(e); 26 | * } 27 | * 28 | */ 29 | public final class Event extends BaseObject { 30 | 31 | private static final long serialVersionUID = 3546358448502944819L; 32 | 33 | public Event(String s) { 34 | Game.assertTrue(!s.startsWith("On")); 35 | set("Name",s); 36 | set("HandlerName",("On"+s).intern()); 37 | } 38 | 39 | public String handlerName() { 40 | return getString("HandlerName"); 41 | } 42 | 43 | public static Event createActionEvent(int time) { 44 | Event e=new Event("Action"); 45 | e.set("Time",time); 46 | return e; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/EventHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 27-Jun-2004 3 | * 4 | * To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Generation - Code and Comments 6 | */ 7 | package mikera.tyrant; 8 | 9 | import mikera.tyrant.engine.Thing; 10 | 11 | /** 12 | * @author Mike 13 | * 14 | * To change the template for this generated type comment go to 15 | * Window - Preferences - Java - Code Generation - Code and Comments 16 | */ 17 | public interface EventHandler { 18 | public boolean handle(Thing t, Event e); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Fire.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.Map; 5 | import mikera.tyrant.engine.RPG; 6 | import mikera.tyrant.engine.Thing; 7 | 8 | public class Fire { 9 | public static Thing create(int strength) { 10 | Thing t=Lib.create("fire"); 11 | t.set("AreaDamage",strength); 12 | return t; 13 | } 14 | 15 | // create fire at specified map location 16 | // add to existing fire if present 17 | public static void createFire(Map m, int tx, int ty, int s) { 18 | if (m == null) 19 | return; 20 | Thing f = m.getNamedObject(tx,ty,"fire"); 21 | if (f == null) { 22 | m.addThing(Fire.create(s), tx, ty); 23 | } else { 24 | f.incStat("AreaDamage",s); 25 | } 26 | } 27 | 28 | public static void init() { 29 | Thing t=Lib.extend("fire", "base scenery"); 30 | t.set("HPS",15); 31 | t.set("IsFire",1); 32 | t.set("IsBlocking",0); 33 | t.set("IsWarning",1); 34 | t.set("LevelMin",6); 35 | t.set("IsDestructible",1); 36 | t.addHandler("OnAction",Scripts.areaDamage(RPG.DT_FIRE,5,10000,"The fire burns you!","IsPhysical")); 37 | t.set("RES:normal",30); 38 | t.set("RES:impact",20); 39 | t.set("RES:piercing",20); 40 | t.set("RES:fire",1000); 41 | t.set("RES:ice",-10); 42 | t.set("ImageSource","Scenery"); 43 | t.set("Image",180); 44 | t.addHandler("OnAction",Scripts.decay()); 45 | Lib.add(t); 46 | 47 | t=Lib.extend("medium fire","fire"); 48 | t.set("DecayRate",1500); 49 | Lib.add(t); 50 | 51 | t=Lib.extend("small fire","fire"); 52 | t.set("HPS",5); 53 | t.set("DecayRate",2000); 54 | Lib.add(t); 55 | 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/GameHandler.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.event.KeyEvent; 4 | 5 | import mikera.tyrant.engine.Map; 6 | import mikera.tyrant.engine.Point; 7 | import mikera.tyrant.engine.Thing; 8 | 9 | 10 | public class GameHandler { 11 | private ActionMapping actionMapping; 12 | 13 | public GameHandler() { 14 | actionMapping = new ActionMapping(); 15 | actionMapping.addDefaultMappings(); 16 | // actionMapping.addRougeLikeMappings(); 17 | } 18 | 19 | public void doDirection(Thing thing, Action action, boolean isShiftDown) { 20 | Map map = thing.getMap(); 21 | Point direction = convertActionToDirection(action); 22 | 23 | // handle movement commands 24 | if (map.getTile(thing.x + direction.x, thing.y + direction.y) != 0) { 25 | if (isShiftDown) { 26 | if (thing.getStat("DirectionX") != direction.x || thing.getStat("DirectionY") != direction.y || !thing.isRunning()) { 27 | /* This is needed for running around corners. The DirectionX changes when you run around a corner 28 | * but the key sent doesn't so direction.x is stale. Only clear the path when RunDirectionX is reset. 29 | */ 30 | if(thing.getStat("RunDirectionX") == Integer.MIN_VALUE) { 31 | map.clearPath(); 32 | } 33 | } 34 | thing.isRunning(true); 35 | } 36 | boolean moved = Movement.tryMove(thing, map, thing.x + direction.x, thing.y + direction.y); 37 | if (!moved) { 38 | thing.isRunning(false); 39 | } 40 | } else if (map.canExit()) { 41 | thing.isRunning(false); // end running 42 | Game.message("Exit area? (y/n)"); 43 | char c = Game.getOption("yn123456789"); 44 | Game.messagepanel.clear(); 45 | if ((thing.x == 0) && ("147".indexOf(c) >= 0)) c = 'y'; 46 | if ((thing.y == 0) && ("789".indexOf(c) >= 0)) c = 'y'; 47 | if ((thing.x == (map.getWidth() - 1)) && ("369".indexOf(c) >= 0)) c = 'y'; 48 | if ((thing.y == (map.getWidth() - 1)) && ("123".indexOf(c) >= 0)) c = 'y'; 49 | 50 | if (c == 'y') { 51 | map.exitMap(thing.x, thing.y); 52 | } 53 | } else if(map.getFlag("IsWorldMap")) { 54 | if(isShiftDown) { 55 | boolean atEdge = (thing.x == 0 && direction.x == -1) || 56 | (thing.x == map.getWidth() - 1 && direction.x == 1) || 57 | (thing.y == 0 && direction.y == -1) || 58 | (thing.y == map.getHeight() - 1 && direction.y == 1); 59 | thing.isRunning(!atEdge); 60 | } 61 | } 62 | } 63 | 64 | public void calculateVision(Thing thing) { 65 | thing.calculateVision(); 66 | } 67 | 68 | public Action actionFor(KeyEvent keyEvent) { 69 | return actionMapping.actionFor(keyEvent); 70 | } 71 | 72 | public Point convertKeyToDirection(char k) { 73 | Action action = actionMapping.convertKeyToAction(k); 74 | return convertActionToDirection(action); 75 | } 76 | 77 | public static Point convertActionToDirection(Action action) { 78 | Point direction = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); 79 | if (action == Action.MOVE_N) { 80 | direction.x = 0; 81 | direction.y = -1; 82 | } 83 | if (action == Action.MOVE_S) { 84 | direction.x = 0; 85 | direction.y = 1; 86 | } 87 | if (action == Action.MOVE_W) { 88 | direction.x = -1; 89 | direction.y = 0; 90 | } 91 | if (action == Action.MOVE_E) { 92 | direction.x = 1; 93 | direction.y = 0; 94 | } 95 | if (action == Action.MOVE_NW) { 96 | direction.x = -1; 97 | direction.y = -1; 98 | } 99 | if (action == Action.MOVE_NE) { 100 | direction.x = 1; 101 | direction.y = -1; 102 | } 103 | if (action == Action.MOVE_SW) { 104 | direction.x = -1; 105 | direction.y = 1; 106 | } 107 | if (action == Action.MOVE_SE) { 108 | direction.x = 1; 109 | direction.y = 1; 110 | } 111 | if (action == Action.MOVE_NOWHERE) { 112 | direction.x = 0; 113 | direction.y = 0; 114 | } 115 | return direction.x == Integer.MIN_VALUE ? null : direction; 116 | } 117 | 118 | public void setActionMapping(ActionMapping actionMapping) { 119 | this.actionMapping = actionMapping; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/GameTile.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.*; 4 | 5 | public class GameTile extends Tile { 6 | private int image; 7 | private boolean transparent; 8 | private boolean blocking; 9 | 10 | public GameTile(int i, boolean b, boolean t) { 11 | image = i; 12 | blocking = b; 13 | transparent = t; 14 | } 15 | 16 | public int getImage() { 17 | return image; 18 | } 19 | 20 | public boolean isBlocking() { 21 | return blocking; 22 | } 23 | 24 | public boolean isTranparent() { 25 | return transparent; 26 | } 27 | 28 | public void draw(Graphics g, int x, int y) { 29 | int w = MapPanel.TILEWIDTH; 30 | int h = MapPanel.TILEHEIGHT; 31 | int sx = (image % 20) * w; 32 | int sy = (image / 20) * h; 33 | g.drawImage(QuestApp.tiles, x, y, x + w, y + h, sx, sy, sx + w, sy + h, 34 | null); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/IActionHandler.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Thing; 4 | 5 | 6 | public interface IActionHandler { 7 | /** 8 | * Answer true if event propagation should stop, false if it should continue. 9 | */ 10 | boolean handleAction(Thing actor, Action action, boolean isShiftDown); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/IMessageHandler.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Color; 4 | 5 | public interface IMessageHandler { 6 | public void clear(); 7 | public void add(String s); 8 | public void add(String s, Color c); 9 | 10 | /** 11 | * If headless this may answer null. 12 | */ 13 | public TPanel getPanel(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/IThingFilter.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Thing; 4 | 5 | 6 | public interface IThingFilter { 7 | boolean accept(Thing thing, String query); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/InfoScreen.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Font; 4 | import java.awt.FontMetrics; 5 | import java.awt.Graphics; 6 | import java.awt.Rectangle; 7 | 8 | import mikera.tyrant.util.Text; 9 | 10 | public class InfoScreen extends Screen { 11 | private static final long serialVersionUID = 3256727281736168249L; 12 | public String text; 13 | public Font font; 14 | 15 | private int border = 20; 16 | 17 | public InfoScreen(QuestApp q, String t) { 18 | super(q); 19 | 20 | text = t; 21 | font = QuestApp.mainfont; 22 | setForeground(QuestApp.INFOTEXTCOLOUR); 23 | setBackground(QuestApp.INFOSCREENCOLOUR); 24 | setFont(font); 25 | } 26 | 27 | public void activate() { 28 | // questapp.setKeyHandler(keyhandler); 29 | } 30 | 31 | public void paint(Graphics g) { 32 | super.paint(g); 33 | 34 | FontMetrics met = g.getFontMetrics(g.getFont()); 35 | 36 | Rectangle r = getBounds(); 37 | int charsize = met.charWidth(' '); 38 | 39 | int linelength; 40 | int y; 41 | int lineinc; 42 | { 43 | linelength = (r.width - border * 2) / charsize; 44 | y = border + met.getMaxAscent(); 45 | lineinc = met.getMaxAscent() + met.getMaxDescent(); 46 | } 47 | 48 | String[] st = Text.separateString(text, '\n'); 49 | 50 | for (int i = 0; i < st.length; i++) { 51 | String s = st[i]; 52 | 53 | String[] lines = Text.wrapString(s, linelength); 54 | 55 | for (int l = 0; l < lines.length; l++) { 56 | String line = lines[l]; 57 | 58 | g.setColor(QuestApp.INFOTEXTCOLOUR); 59 | g.drawString(line, border, y); 60 | y += lineinc; 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/InputHandler.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.event.KeyEvent; 4 | 5 | public class InputHandler { 6 | public char getCharacter() { 7 | return getKeyEvent().getKeyChar(); 8 | } 9 | 10 | public KeyEvent getKeyEvent() { 11 | throw new Error("Base input handler not overridden"); 12 | } 13 | 14 | public static InputHandler repeat(final char c) { 15 | return new InputHandler() { 16 | public KeyEvent getKeyEvent() { 17 | return new KeyEvent(Game.getQuestapp(), 18 | KeyEvent.KEY_PRESSED, 19 | System.currentTimeMillis(), 20 | 0, 21 | KeyEvent.VK_UNDEFINED, 22 | c); 23 | } 24 | }; 25 | 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Interface.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.event.KeyEvent; 4 | 5 | public class Interface { 6 | protected KeyEvent keyevent; 7 | private Object lock = new Object(); 8 | 9 | public void go(KeyEvent k) { 10 | keyevent = k; 11 | synchronized(lock) { 12 | lock.notifyAll(); 13 | } 14 | } 15 | 16 | public void getInput() { 17 | try { 18 | synchronized(lock) { 19 | lock.wait(); 20 | } 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/IsFilter.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Thing; 4 | 5 | 6 | public class IsFilter implements IThingFilter { 7 | public boolean accept(Thing thing, String query) { 8 | if(query == null || query.length() < 1) return false; 9 | char firstLetter = query.charAt(0); 10 | char lastLetter = query.charAt(query.length()-1); 11 | if(firstLetter != '[' && Character.toUpperCase(firstLetter) != 'I') return false; 12 | String name = query; 13 | if((firstLetter == '[')&&(lastLetter==']')) { 14 | name = query.substring(1,query.length()-1); 15 | } 16 | return thing.getFlag(name); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/LevelMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 26-Jul-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import java.util.HashMap; 9 | 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.Thing; 12 | import mikera.util.Maths; 13 | import mikera.util.Rand; 14 | 15 | /** 16 | * @author Mike 17 | * 18 | * Implements static methods for handling level maps 19 | */ 20 | public class LevelMap implements java.io.Serializable { 21 | private static final long serialVersionUID = 3545517309273125684L; 22 | // current pixels 23 | private int[] pixels=null; 24 | private int[] currentMemory=null; 25 | private Map lastMap=null; 26 | private HashMap mapMemory=new HashMap<>(); 27 | 28 | public static LevelMap instance() { 29 | LevelMap l=(LevelMap)Game.instance().get("MapMemory"); 30 | if (l==null) { 31 | l=new LevelMap(); 32 | Game.instance().set("MapMemory",l); 33 | } 34 | return l; 35 | } 36 | 37 | private HashMap getMapMemory() { 38 | return mapMemory; 39 | } 40 | 41 | private int[] getMapMemory(Map m) { 42 | HashMap h=getMapMemory(); 43 | int[] memory=h.get(m); 44 | if ((memory==null)&&(m==lastMap)) { 45 | memory=currentMemory; 46 | } 47 | if (memory==null) { 48 | memory=new int[m.width*m.height]; 49 | if (!m.getFlag("ForgetMap")) { 50 | h.put(m,memory); 51 | } 52 | } 53 | currentMemory=memory; 54 | lastMap=m; 55 | return memory; 56 | } 57 | 58 | public static void reveal(Map map) { 59 | int w=map.width; 60 | int h=map.height; 61 | int[] mem= instance().getMapMemory(map); 62 | 63 | for (int y=0;y0) { 171 | c=mc; 172 | } 173 | t=t.next; 174 | } 175 | 176 | pixels[x+map.width*y]=c; 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/LevelMapPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 22-Jul-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import java.awt.Color; 9 | import java.awt.Dimension; 10 | import java.awt.Graphics; 11 | import java.awt.image.BufferedImage; 12 | 13 | import mikera.tyrant.engine.Map; 14 | 15 | /** 16 | * @author Mike 17 | * 18 | * To change the template for this generated type comment go to 19 | * Window - Preferences - Java - Code Generation - Code and Comments 20 | */ 21 | @SuppressWarnings("serial") 22 | public class LevelMapPanel extends TPanel { 23 | 24 | private BufferedImage mapBuffer; 25 | private Map permanentMap=null; 26 | 27 | public LevelMapPanel() { 28 | super(Game.getQuestapp()); 29 | } 30 | 31 | public Dimension getPreferredSize() { 32 | return new Dimension(200,150); 33 | } 34 | 35 | public void setMap(Map m) { 36 | permanentMap=m; 37 | } 38 | 39 | public void paint(Graphics g) { 40 | 41 | Map map; 42 | if (permanentMap!=null) { 43 | map=permanentMap; 44 | } else { 45 | map=Game.hero().getMap(); 46 | } 47 | super.paint(g); 48 | if (map!=null) paintMap(g,map); 49 | } 50 | 51 | 52 | 53 | 54 | 55 | public void paintMap(Graphics g,Map map) { 56 | int w=map.width; 57 | int h=map.height; 58 | int[] mem=LevelMap.instance().getMapView(map); 59 | 60 | // create back buffer if needed 61 | if ((mapBuffer == null)||(mapBuffer.getHeight()!=h)||(mapBuffer.getWidth()!=w)) { 62 | mapBuffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); 63 | } 64 | 65 | mapBuffer.setRGB(0,0,w,h,mem,0,w); 66 | 67 | g.setColor(Color.BLACK); 68 | // g.drawRect(0,0,10,10); 69 | int cx=getWidth()/2; 70 | int cy=getHeight()/2; 71 | int cw=w*2; 72 | int ch=h*2; 73 | if (cw>cx) { 74 | ch=(ch*cx)/cw; 75 | cw=(cw*cx)/cw; 76 | } 77 | if (ch>cy) { 78 | cw=(cw*cy)/ch; 79 | ch=(ch*cy)/ch; 80 | } 81 | try { 82 | g.drawImage(mapBuffer,cx-cw,cy-ch,cx+cw,cy+ch,0,0,w,h,null); 83 | } catch(Throwable t) { 84 | Game.warn(t.toString()); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/ListItem.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.*; 4 | 5 | import mikera.tyrant.engine.Thing; 6 | 7 | public class ListItem extends Panel { 8 | private static final long serialVersionUID = 3978147629882421811L; 9 | private String text; 10 | 11 | public ListItem(Thing t) { 12 | super(); 13 | text = t.getName(Game.hero()); 14 | } 15 | 16 | public void paint(Graphics g) { 17 | super.paint(g); 18 | g.drawString(text, 32, getHeight()); 19 | //int sx=(image%20)*MapPanel.TILEWIDTH; 20 | //int sy=(image/20)*MapPanel.TILEHEIGHT; 21 | //g.drawImage(QuestApp.items,0,0,16,16,sx,sy,sx+MapPanel.TILEWIDTH,sy+MapPanel.TILEHEIGHT,null); 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/ListScreen.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.Graphics; 5 | import java.awt.GridLayout; 6 | import java.awt.event.KeyEvent; 7 | import java.util.Collection; 8 | import java.util.Iterator; 9 | 10 | public class ListScreen extends Screen { 11 | private static final long serialVersionUID = 3257003267744478006L; 12 | String title = "List"; 13 | String[] strings = null; 14 | static int page = 0; 15 | Object result; 16 | 17 | private static int pagesize = 26; 18 | private static int lineheight = 20; 19 | public String bottomString="ESC = Cancel"; 20 | 21 | public Object getObject() { 22 | boolean end = false; 23 | while (!end) { 24 | KeyEvent k = Game.getInput(); 25 | if (k != null) { 26 | if ((k.getKeyCode() == KeyEvent.VK_ESCAPE)||(k.getKeyCode()==KeyEvent.VK_ENTER)) 27 | return null; 28 | 29 | char c = Character.toLowerCase(k.getKeyChar()); 30 | 31 | if (k.getKeyCode() == KeyEvent.VK_UP) c = '-'; 32 | if (k.getKeyCode() == KeyEvent.VK_DOWN) c = '+'; 33 | 34 | //Game.warn(Character.toString(c)); 35 | 36 | if ((c == 'p' || c == '-') && (page > 0)) { 37 | page--; 38 | repaint(); 39 | } 40 | 41 | if ((c == 'n' || c == '+' || c == ' ') 42 | && (((page + 1) * pagesize) < strings.length)) { 43 | page++; 44 | repaint(); 45 | } 46 | 47 | int kv = c - 'a'; 48 | if ((kv >= 0) && (kv < pagesize)) { 49 | kv = kv + page * pagesize; 50 | if ((kv >= 0) && (kv < strings.length)) 51 | return strings[kv]; 52 | } 53 | } 54 | } 55 | return null; 56 | } 57 | 58 | public void activate() { 59 | // questapp.setKeyHandler(keyhandler); 60 | } 61 | 62 | private static String[] getStringArray(Collection c) { 63 | String[] ss=new String[c.size()]; 64 | Iterator it=c.iterator(); 65 | int i=0; 66 | while (it.hasNext()) { 67 | ss[i++]=it.next(); 68 | } 69 | return ss; 70 | } 71 | 72 | public ListScreen(String s, Collection c) { 73 | this(s,getStringArray(c)); 74 | } 75 | 76 | public ListScreen(String s, String[] invstrings) { 77 | super(Game.getQuestapp()); 78 | setLayout(new GridLayout(15, 1)); 79 | setFont(QuestApp.mainfont); 80 | 81 | addKeyListener(questapp.keyadapter); 82 | 83 | // get the strings 84 | strings = invstrings; 85 | if (strings == null) 86 | strings = new String[0]; 87 | 88 | // set the list title 89 | title = s; 90 | } 91 | 92 | public void paint(Graphics g) { 93 | super.paint(g); 94 | 95 | if ((page * pagesize) > strings.length) 96 | page = 0; 97 | 98 | Dimension d = getSize(); 99 | 100 | g.setColor(QuestApp.INFOTEXTCOLOUR); 101 | 102 | g.drawString(title, 20, 1 * lineheight); 103 | 104 | for (int i = 0; i < Math.min(strings.length - (page * pagesize), 105 | pagesize); i++) { 106 | String t = strings[i + page * pagesize]; 107 | String s = "[" + (char) ('a' + i) + "] " + t; 108 | g.drawString(s, 50, lineheight * (i + 2)); 109 | } 110 | 111 | String bottomstring = bottomString+" "; 112 | if (page > 0) 113 | bottomstring = bottomstring + " Up = Previous "; 114 | if (((page + 1) * pagesize) < strings.length) 115 | bottomstring = bottomstring + " Down = Next "; 116 | g.drawString(bottomstring, 20, d.height - 20); 117 | } 118 | 119 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Maze.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 26-Jul-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import mikera.tyrant.engine.Map; 9 | import mikera.util.Rand; 10 | 11 | /** 12 | * @author Mike 13 | * 14 | * Maze implements methods for constructing maze-like dungeons 15 | */ 16 | 17 | public class Maze { 18 | public static void buildMaze(Map m, int x1, int y1, int x2, int y2) { 19 | m.fillArea(x1,y1,x2,y2,m.wall()); 20 | buildInnerMaze(m,x1+1,y1+1,x2-1,y2-1); 21 | } 22 | 23 | public static void buildInnerMaze(Map m, int x1, int y1, int x2, int y2) { 24 | int floor=m.floor(); 25 | int wall=m.wall(); 26 | 27 | m.fillArea(x1,y1,x2,y2,wall); 28 | 29 | int w=x2-x1+1; int rw=(w+1)/2; 30 | int h=y2-y1+1; int rh=(h+1)/2; 31 | 32 | int sx=x1+2*Rand.r(rw); 33 | int sy=y1+2*Rand.r(rh); 34 | m.setTile(sx,sy,floor); 35 | 36 | int finishedCount=0; 37 | for (int i=1; (i<(rw*rh*1000))&&(finishedCount<(rw*rh)); i++) { 38 | int x=x1+2*Rand.r(rw); 39 | int y=y1+2*Rand.r(rh); 40 | if (m.getTile(x,y)!=wall) continue; 41 | int dx=(Rand.d(2)==1)?(Rand.r(2)*2-1):0; 42 | int dy=(dx==0) ?(Rand.r(2)*2-1):0; 43 | int lx=x+dx*2; 44 | int ly=y+dy*2; 45 | if ((lx>=x1)&&(lx<=x2)&&(ly>=y1)&&(ly<=y2)) { 46 | if (m.getTile(lx,ly)!=wall) { 47 | m.setTile(x,y,floor); 48 | m.setTile(x+dx,y+dy,floor); 49 | finishedCount++; 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/MessagePanel.java: -------------------------------------------------------------------------------- 1 | // 2 | // Panel for displaying game status messages at the botton of the screen 3 | // 4 | 5 | package mikera.tyrant; 6 | 7 | import java.awt.BorderLayout; 8 | import java.awt.Color; 9 | import java.awt.Dimension; 10 | 11 | public class MessagePanel extends TPanel implements IMessageHandler { 12 | //private String text=""; 13 | 14 | // public MessagePanel() { 15 | // super("",0,0,SCROLLBARS_VERTICAL_ONLY); 16 | // setEditable(false); 17 | // setForeground(QuestApp.textcolor); 18 | // setBackground(QuestApp.backcolor); 19 | // setFont(QuestApp.mainfont); 20 | // Game.messagepanel=this; 21 | // } 22 | 23 | private static final long serialVersionUID = 3258416114332807730L; 24 | //private TextArea textzone = new TTextArea("",0,0,TextArea.SCROLLBARS_VERTICAL_ONLY); 25 | private TextZone textzone = new TextZone(); 26 | 27 | public MessagePanel(QuestApp q) { 28 | super(q); 29 | setLayout(new BorderLayout()); 30 | textzone.setBackground(QuestApp.PANELCOLOUR); 31 | textzone.setForeground(QuestApp.INFOTEXTCOLOUR); 32 | 33 | add("Center", textzone); 34 | Game.messagepanel = this; 35 | } 36 | 37 | private void setText(String s) { 38 | textzone.setText(s); 39 | } 40 | 41 | private String getText() { 42 | return textzone.getText(); 43 | } 44 | 45 | public void clear() { 46 | textzone.setText(""); 47 | } 48 | 49 | public void add(String s) { 50 | add(s,Color.lightGray); 51 | 52 | } 53 | 54 | public void add(String s, Color c ) { 55 | String t = getText(); 56 | if (t.length() > 2000) { 57 | setText(t.substring(t.length() - 2000, t.length())); 58 | } 59 | 60 | String newtext = getText() + s; 61 | setText(newtext); 62 | 63 | // try { 64 | // setCaretPosition(newtext.length()-1); 65 | // } catch (Exception e) {} 66 | } 67 | 68 | //public void append(String s){ 69 | // text=text+s; 70 | // repaint(); 71 | //} 72 | 73 | //public void setText(String s) { 74 | // text=s; 75 | // repaint(); 76 | //} 77 | 78 | public Dimension getPreferredSize() { 79 | return new Dimension(500, 120); 80 | } 81 | 82 | public TPanel getPanel() { 83 | return this; 84 | } 85 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Name.java: -------------------------------------------------------------------------------- 1 | // Class to manage names of creatures and characters 2 | 3 | package mikera.tyrant; 4 | 5 | import mikera.tyrant.engine.RPG; 6 | import mikera.tyrant.util.Text; 7 | 8 | public class Name { 9 | 10 | public static String[][] names= 11 | {{"The Tyrant"}, 12 | {"Benn","Kiern","Fayd","Rodrik","Gabe","Jobe","Mert","Janik","Jonn","Joharn","Andrin","Artur","Arthor","Aron","Bod","Bikk"}, 13 | {"Alarna","Bamdia","Carrel","Dula","Sarra","Gail","Jeela","Ciina","Waydia","Kaydia","Faydia","Kassara","Jenn","Keri","Weyla","Gerrie"}, 14 | {"Rutlud","Gombag","Snogi","Grashnak","Gruttug","Gritnak","Gumnak","Shondag","Stugrat","Kretlig","Gromnark","Bitnak"}, 15 | 16 | {} 17 | }; 18 | 19 | 20 | private static String[] gobboFirstParts={"gom","grash","grut","gum","stug","kret","krom","kar"}; 21 | private static String[] gobboLastParts={"nak","lug","tug","bag","dag","lig","rat","nark"}; 22 | public static String createGoblinName() { 23 | String a=RPG.pick(gobboFirstParts); 24 | String b=RPG.pick(gobboLastParts); 25 | return Text.capitalise(a+b); 26 | } 27 | 28 | public static String createOrcName() { 29 | return createGoblinName(); 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/NameFilter.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Describer; 4 | import mikera.tyrant.engine.Description; 5 | import mikera.tyrant.engine.Thing; 6 | 7 | 8 | public class NameFilter implements IThingFilter { 9 | public boolean accept(Thing thing, String query) { 10 | if(query == null) return true; 11 | query = query.trim(); 12 | String name = Describer.describe(null, thing, Description.ARTICLE_NONE); 13 | return name.indexOf(query) >= 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/OrFilter.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.util.Iterator; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | import mikera.tyrant.engine.Thing; 8 | 9 | 10 | public class OrFilter implements IThingFilter { 11 | private List filters = new LinkedList<>(); 12 | 13 | public OrFilter(IThingFilter filterA, IThingFilter filterB) { 14 | addFilter(filterA); 15 | addFilter(filterB); 16 | } 17 | public OrFilter(IThingFilter filterA, IThingFilter filterB, IThingFilter filterC) { 18 | addFilter(filterA); 19 | addFilter(filterB); 20 | addFilter(filterC); 21 | } 22 | 23 | public void addFilter(IThingFilter filter) { 24 | filters.add(filter); 25 | } 26 | 27 | public boolean accept(Thing thing, String query) { 28 | for (Iterator iter = filters.iterator(); iter.hasNext();) { 29 | IThingFilter filter = iter.next(); 30 | if(filter.accept(thing, query)) return true; 31 | } 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/PortalStone.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on May 24, 2006 by tomdemuyt 3 | * 4 | */ 5 | package mikera.tyrant; 6 | 7 | import mikera.tyrant.engine.Lib; 8 | import mikera.tyrant.engine.Map; 9 | import mikera.tyrant.engine.Script; 10 | import mikera.tyrant.engine.Thing; 11 | 12 | 13 | /** 14 | * PortalStone by @author tomdemuyt 15 | */ 16 | public class PortalStone { 17 | 18 | @SuppressWarnings("serial") 19 | private static class PortalStoneAction extends Script { 20 | public boolean handle(Thing t, Event e) { 21 | Thing user=e.getThing("User"); 22 | PortalStone.use( user , t ); 23 | return true; 24 | } 25 | } 26 | 27 | static private int maxSlots = 10; 28 | 29 | public static void init() { 30 | Thing t = Lib.extend("portal stone", "base item"); 31 | t.set("Image", 104); 32 | //t.set("Image", 190); 33 | t.set("ValueBase", 0); 34 | t.set("ItemWeight", 50); 35 | t.set("Frequency", 2); //This is a rare item 36 | t.set("LevelMin",1); 37 | t.set("ASCII","*"); 38 | t.set("OnUse",new PortalStoneAction()); 39 | t.set("Slots" , new Thing[maxSlots+1]); 40 | t.set("SlotCount" , 2); 41 | Lib.add(t); 42 | } 43 | 44 | static public void use( Thing user , Thing portalStone){ 45 | //Default to first slot 46 | int slot=1; 47 | int slots = portalStone.getStat( "SlotCount" ); 48 | Thing[] Slots = (Thing[])portalStone.get("Slots"); 49 | 50 | //We can use it to mark location and to cast portal 51 | Game.message("Do you want to Mark your location, or cast a Portal (M or P)"); 52 | 53 | if (Game.getOption("pm") == 'm'){ 54 | //Player wants to mark the current location 55 | slot = Game.getNumber( "Which slot do you want to use ?\n" + PortalStone.toString(portalStone) , slots ); 56 | //Delete previous portals so that we do not unbalance the time/space continuum 57 | if(Slots[slot]!=null){ 58 | Slots[slot].die(); 59 | } 60 | Slots[slot] = Portal.create( "traveler portal" ); 61 | Portal.setDestination( Slots[slot] , user.getMap() , user.x , user.y ); 62 | }else{ 63 | //Player wants to cast a portal 64 | slot = Game.getNumber( "Which slot do you want to use ?\n" + PortalStone.toString(portalStone) , slots ); 65 | if( Slots[slot] != null ){ 66 | //Dont create portals on the same level, ca n'a pas d'allure 67 | if( user.getMap().equals( Slots[slot].get("PortalTargetMap") ) ){ 68 | Game.message( "You are already at " + ((Map)Slots[slot].get("PortalTargetMap" )).getDescription() ); 69 | }else{ 70 | user.getMap().addThing( Slots[slot], user.x, user.y); 71 | } 72 | }else{ 73 | Game.message("You have not marked this slot."); 74 | } 75 | 76 | } 77 | } 78 | 79 | //One time in the future, the portal mage will allow to increase slots 80 | static public boolean addSlot( Thing portalStone ){ 81 | int slots = portalStone.getStat( "SlotCount" ); 82 | if( slots != maxSlots ){ 83 | slots++; 84 | portalStone.set("SlotCount",slots); 85 | return true; 86 | } 87 | return false; 88 | } 89 | 90 | 91 | //List all slots, with a description of their map or a blank 92 | //I might restrict slots just for gui reasons, which is frankly pretty stupid 93 | static public String toString( Thing portalStone ){ 94 | String s = ""; 95 | int slots = portalStone.getStat( "SlotCount" ); 96 | Thing[] Slots = (Thing[])portalStone.get("Slots"); 97 | for( int i = 1 ; i <= slots ; i++){ 98 | s = s + String.valueOf( i ) + ". "; 99 | if( Slots[i] != null ){ 100 | s = s + ((Map)Slots[i].get("PortalTargetMap" )).getDescription() + ".\n"; 101 | }else{ 102 | s = s + ".\n"; 103 | } 104 | } 105 | return s; 106 | } 107 | 108 | public static void main(String[] args) { 109 | //TODO : test... 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/QuestApplication.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.awt.Frame; 6 | import java.awt.Toolkit; 7 | import java.awt.event.WindowAdapter; 8 | import java.awt.event.WindowEvent; 9 | // import mikera.tyrant.util.PlugInUtility; 10 | 11 | /** 12 | * Main class for Tyrant when run as an application 13 | * 14 | * Just creates a simple frame for a QuestApp component and 15 | * calls QuestApp.init() to initialise the game 16 | * 17 | * @author Mike 18 | * 19 | */ 20 | public class QuestApplication { 21 | public static void main(String args[]) { 22 | Game.loadVersionNumber(); 23 | 24 | Frame f = new Frame("Tyrant - The Adventure - v"+Game.VERSION); 25 | f.setIconImage(Toolkit.getDefaultToolkit().getImage("images/favicon.ico")); 26 | f.setBackground(Color.black); 27 | f.addWindowListener(new WindowAdapter() { 28 | public void windowClosing(WindowEvent e) { 29 | System.exit(0); 30 | } 31 | }); 32 | 33 | f.setLayout(new BorderLayout()); 34 | QuestApp q=new QuestApp(); 35 | QuestApp.isapplet=false; 36 | if (args.length > 0) { 37 | QuestApp.gameFileFromCommandLine = args[0]; 38 | } 39 | 40 | // do we have a script to execute? 41 | // activate debug mode if we do.... 42 | java.io.File script=new java.io.File("mikeradebug"); 43 | 44 | // old method to activate debug cheat 45 | Game.setDebug(script.exists()); 46 | 47 | q.setVisible(false); 48 | f.add(q); 49 | 50 | f.setSize(q.getPreferredSize().width,q.getPreferredSize().height); 51 | 52 | f.addKeyListener(q.keyadapter); 53 | 54 | q.setVisible(true); 55 | f.setVisible(true); 56 | 57 | q.init(); 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/RogueLikeFilter.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import mikera.tyrant.engine.Thing; 7 | 8 | 9 | public class RogueLikeFilter implements IThingFilter { 10 | private Map types = new HashMap<>(); 11 | 12 | public RogueLikeFilter() { 13 | setupMappings(); 14 | } 15 | 16 | private void setupMappings() { 17 | types.put("%", "IsFood"); 18 | types.put("$", "IsMoney"); 19 | types.put("]", "IsEquipment"); 20 | types.put("[", "IsArmour"); 21 | types.put("=", "IsRing"); 22 | types.put("?", "IsScroll"); 23 | types.put("!", "IsPotion"); 24 | types.put("+", "IsBook"); 25 | types.put("(", "IsWeapon"); 26 | types.put(")", "IsRangedWeapon"); 27 | types.put("/", "IsMissile"); 28 | } 29 | 30 | public boolean accept(Thing thing, String text) { 31 | if(text == null) return true; 32 | text = text.trim(); 33 | if(text.length() == 0) return true; 34 | String type = types.get(text); 35 | return type != null && thing.get(type) != null; 36 | } 37 | 38 | public boolean isRougeMatch(String aChar) { 39 | return types.containsKey(aChar); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/RuneTrap.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.Thing; 5 | import mikera.util.Rand; 6 | 7 | public class RuneTrap extends Trap { 8 | 9 | public static Thing create(int level) { 10 | Thing t=Lib.create("rune trap"); 11 | 12 | t.set("Image", 160 + Rand.r(3)); 13 | t.set("TrapSpellName",Spell.randomOffensiveSpell(Skill.TRUEMAGIC,level).name()); 14 | return t; 15 | } 16 | 17 | public static Thing create(Thing owner, Thing thespell) { 18 | Thing t=create(); 19 | t.set("Actor", owner); 20 | Game.assertTrue(thespell.getFlag("IsSpell")); 21 | t.set("TrapSpellName",thespell.getName(Game.hero())); 22 | return t; 23 | } 24 | 25 | 26 | public static void init() { 27 | Thing t=Lib.extend("rune trap","base trap"); 28 | t.set("IsInvisible",0); 29 | t.set("Image",160); 30 | t.set("ImageSource","Scenery"); 31 | t.set("TrapSpell","Fireball"); // default spell 32 | t.set("OnEnterTrigger",new SpellTrapTrigger()); 33 | Lib.add(t); 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Score.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 27-Jul-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant; 7 | 8 | import mikera.tyrant.engine.Lib; 9 | import mikera.tyrant.engine.RPG; 10 | import mikera.tyrant.engine.Thing; 11 | 12 | /** 13 | * @author Mike 14 | * 15 | * Implements Tyrant point-scoring 16 | * 17 | * Most notable feature is an exponential decay in the rate of 18 | * point scoring. This is to encourage risk taking and skilled 19 | * play rather than slow, tedious level-building and hoarding 20 | */ 21 | public class Score { 22 | private static final double SCORE_HALFLIFE=3000000.0; 23 | public static void scoreIdentify(Thing hero, Thing thing) { 24 | // score for non-obvious items 25 | if (!Item.isDisguisedName(thing)) { 26 | addScore(hero, Lib.getDefaultStat(thing,"Level")*2); 27 | } 28 | } 29 | 30 | public static void scoreExplore(Thing t) { 31 | int score=t.getStat("ExploreScore"); 32 | if (score>0) { 33 | addScore(Game.hero(), score); 34 | t.incStat("ExploreScore",-score); 35 | } 36 | } 37 | 38 | public static void scoreFirstKill(Thing t) { 39 | addScore(Game.hero(), Lib.getDefaultStat(t,"Level")*5); 40 | } 41 | 42 | public static void scoreSecretDoor(int lev) { 43 | addScore(Game.hero(), lev*10); 44 | } 45 | 46 | /** 47 | * Adds to the players score. The actual score added is modified 48 | * by a factor that decay exponentially over game time. 49 | * 50 | * @param rawscore 51 | */ 52 | private static void addScore(Thing hero, int rawscore) { 53 | int score=RPG.round(rawscore*Math.pow(0.5,hero.getStat("GameTime")/SCORE_HALFLIFE)); 54 | 55 | hero.incStat("Score",score); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Screen.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | 4 | public class Screen extends TPanel { 5 | 6 | /** 7 | * 8 | */ 9 | private static final long serialVersionUID = 3546923567481894199L; 10 | 11 | public Screen(QuestApp questapp) { 12 | super(questapp); 13 | 14 | setFont(QuestApp.mainfont); 15 | setForeground(QuestApp.INFOTEXTCOLOUR); 16 | setBackground(QuestApp.INFOSCREENCOLOUR); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Secret.java: -------------------------------------------------------------------------------- 1 | // This represents a secret/hidden map element 2 | // Does not appear unless discovered 3 | 4 | package mikera.tyrant; 5 | 6 | import mikera.tyrant.engine.Lib; 7 | import mikera.tyrant.engine.Map; 8 | import mikera.tyrant.engine.Thing; 9 | 10 | public class Secret { 11 | 12 | 13 | 14 | public static void searchAround() { 15 | Thing h=Game.hero(); 16 | Map map = h.getMap(); 17 | if (map == null) { 18 | Game.warn("Hero not on map in Secret.searchAround!"); 19 | return; 20 | } 21 | 22 | 23 | if (h.getFlag("IsBlind")) { 24 | Game.message("You fumble around ineffectively"); 25 | return; 26 | } 27 | 28 | boolean searchFlag = search(); 29 | 30 | if(!searchFlag) 31 | Game.message("You search but find nothing of interest"); 32 | } 33 | 34 | public static boolean search() { 35 | Thing h=Game.hero(); 36 | 37 | boolean searchFlag = false; 38 | Thing[] th = h.getMap().getThings(h.x - 1, h.y - 1, h.x + 1, h.y + 1); 39 | for (int i = 0; i < th.length; i++) { 40 | Thing st = th[i]; 41 | // use the OR operator ... 42 | // so if something is found, the flag 43 | // will stay true. 44 | searchFlag |= search(st); 45 | } 46 | 47 | return searchFlag; 48 | } 49 | 50 | public static boolean search(Thing t) { 51 | //public static void search(Thing t) { 52 | Map map = t.getMap(); 53 | 54 | if (!t.getFlag("IsSecret")) return false; 55 | 56 | if (t.getFlag("IsSecretDoor")) { 57 | Game.message("You have found a secret door!"); 58 | map.setTile(t.x, t.y, map.floor()); 59 | String s=t.getString("SecretDoorType"); 60 | Thing door; 61 | if (s==null) { 62 | door=Door.createDoor(map.getLevel()); 63 | } else { 64 | door=Lib.create(s); 65 | } 66 | Score.scoreSecretDoor(map.getLevel()); 67 | map.addThing(door, t.x, t.y); 68 | map.setVisible(t.x,t.y); 69 | t.remove(); 70 | return true; 71 | } 72 | 73 | if (t.getFlag("IsTrap")&&(t.getFlag("IsInvisible"))) { 74 | Game.message("You have found a "+t.name()+"!!"); 75 | t.set("IsDiscovered",1); 76 | t.set("IsInvisible",0); 77 | return true; 78 | } 79 | 80 | if (t.getFlag("IsSecretPassage")) { 81 | Game.message("You have found a hidden passage!"); 82 | map.setTile(t.x, t.y, map.floor()); 83 | t.remove(); 84 | return true; 85 | } 86 | 87 | if (t.getFlag("IsHiddenItem")) { 88 | Thing it=(Thing)t.get("HiddenThing"); 89 | if (it==null) { 90 | String s=t.getString("HiddenItem"); 91 | if (s==null) it=Lib.createItem(map.getLevel()); 92 | else it=Lib.create(s); 93 | } 94 | Game.message("You have discovered "+it.getAName()+"!"); 95 | map.addThing(it,t.x,t.y); 96 | t.remove(); 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | public static Thing hide(Thing t) { 103 | Thing s=Lib.create("secret item"); 104 | s.set("HiddenThing",t); 105 | t.remove(); 106 | s.addThing(t); 107 | return s; 108 | } 109 | 110 | public static void init() { 111 | Thing t; 112 | 113 | t=Lib.extend("base secret","base special"); 114 | t.set("IsPhysical",0); 115 | t.set("IsDestructible",0); 116 | t.set("Image",5); 117 | t.set("IsSecret",1); 118 | t.set("ASCII", "o"); 119 | Lib.add(t); 120 | 121 | t=Lib.extend("secret door","base secret"); 122 | t.set("IsSecretDoor",1); 123 | Lib.add(t); 124 | 125 | t=Lib.extend("secret passage","base secret"); 126 | t.set("IsSecretPassage",1); 127 | Lib.add(t); 128 | 129 | t=Lib.extend("secret item","base secret"); 130 | t.set("IsHiddenItem",1); 131 | Lib.add(t); 132 | 133 | } 134 | 135 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/TPanel.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Image; 5 | import java.awt.Panel; 6 | import java.awt.Rectangle; 7 | 8 | public class TPanel extends Panel { 9 | public QuestApp questapp; 10 | 11 | private static final long serialVersionUID = 3257289145112998709L; 12 | 13 | public TPanel(QuestApp q) { 14 | super(); 15 | setFocusable(true); 16 | setBackground(QuestApp.PANELCOLOUR); 17 | 18 | globalKeyListenerHasBeenAdded = true; 19 | 20 | if (q!=null) { 21 | questapp=q; 22 | 23 | addKeyListener(questapp.keyadapter); 24 | } 25 | } 26 | 27 | 28 | public Image getTexture() { 29 | return QuestApp.paneltexture; 30 | } 31 | 32 | protected Image buffer; 33 | protected boolean globalKeyListenerHasBeenAdded; 34 | 35 | // update with double buffering. 36 | public void update(Graphics g) { 37 | // graphics context for the buffer 38 | Graphics bg; 39 | 40 | // only build when needed 41 | if ((buffer==null) || (buffer.getWidth(this) != this.getSize().width) || (buffer.getHeight(this) != this.getSize().height)) { 42 | try { 43 | buffer = this.createImage(getSize().width, getSize().height); 44 | } catch(Throwable x) { 45 | Game.warn("TPanel.update() exception"); 46 | return; 47 | } 48 | } 49 | 50 | bg = buffer.getGraphics(); 51 | 52 | // paint the panel 53 | paint(bg); 54 | super.paint(bg); 55 | 56 | g.drawImage(buffer, 0, 0, this); 57 | } 58 | 59 | public void paint(Graphics g) { 60 | Rectangle bounds=getBounds(); 61 | int width=bounds.width; 62 | int height=bounds.height; 63 | 64 | Image texture=getTexture(); 65 | if (texture!=null) { 66 | int twidth=texture.getWidth(null); 67 | int theight=texture.getHeight(null); 68 | for (int lx=0; lx themes=null; 34 | 35 | private static void addTheme(Theme t) { 36 | themes.put(t.getString("Name"),t); 37 | } 38 | 39 | private static void init() { 40 | themes=new HashMap<>(); 41 | 42 | Theme t=new Theme(); 43 | t.set("Name","base theme"); 44 | t.set("WallTile",Tile.CAVEWALL); 45 | t.set("FloorTile",Tile.CAVEFLOOR); 46 | t.set("DungeonDensity",0.15); 47 | addTheme(t); 48 | 49 | t=new Theme("standard","base theme"); 50 | t.set("WallTile",Tile.WALL); 51 | t.set("FloorTile",Tile.FLOOR); 52 | t.set("DungeonDNA","tttkrrroozhs"); 53 | addTheme(t); 54 | 55 | t=new Theme("deep halls","base theme"); 56 | t.set("WallTile",Tile.WALL); 57 | t.set("FloorTile",Tile.FLOOR); 58 | t.set("DungeonDNA","nrr"); 59 | addTheme(t); 60 | 61 | t=new Theme("woods","base theme"); 62 | t.set("WallTile",Tile.TREE); 63 | t.set("FloorTile",Tile.FORESTFLOOR); 64 | addTheme(t); 65 | 66 | t=new Theme("deepforest","base theme"); 67 | t.set("WallTile",Tile.TREE); 68 | t.set("FloorTile",Tile.FORESTFLOOR); 69 | addTheme(t); 70 | 71 | t=new Theme("caves","base theme"); 72 | t.set("WallTile",Tile.CAVEWALL); 73 | t.set("FloorTile",Tile.CAVEFLOOR); 74 | t.set("DungeonDNA","conn"); 75 | addTheme(t); 76 | 77 | t=new Theme("mines","base theme"); 78 | t.set("WallTile",Tile.CAVEWALL); 79 | t.set("FloorTile",Tile.CAVEFLOOR); 80 | t.set("DungeonDNA","rcot"); 81 | addTheme(t); 82 | 83 | t=new Theme("sewer","base theme"); 84 | t.set("WallTile",Tile.CAVEWALL); 85 | t.set("FloorTile",Tile.GUNK); 86 | t.set("DungeonDNA","cttttkkkrrrrozs"); 87 | addTheme(t); 88 | 89 | t=new Theme("ice","base theme"); 90 | t.set("WallTile",Tile.ICEWALL); 91 | t.set("FloorTile",Tile.ICEFLOOR); 92 | t.set("DungeonDNA","cttttkkkrrrrozs"); 93 | addTheme(t); 94 | 95 | t=new Theme("fire","base theme"); 96 | t.set("WallTile",Tile.REDWALL); 97 | t.set("FloorTile",Tile.REDFLOOR); 98 | t.set("DungeonDNA","cttttkkkrrrrozs"); 99 | addTheme(t); 100 | 101 | t=new Theme("hell","base theme"); 102 | t.set("WallTile",Tile.REDWALL); 103 | t.set("FloorTile",Tile.REDFLOOR); 104 | t.set("DungeonDNA","cttttkkkrrrrozs"); 105 | t.set("MonsterType","IsDemonic"); 106 | t.set("WanderingRate",1000); 107 | addTheme(t); 108 | 109 | t=new Theme("labyrinthe","base theme"); 110 | t.set("WallTile",Tile.CAVEWALL); 111 | t.set("FloorTile",Tile.CAVEFLOOR); 112 | t.set("DungeonDNA","cczzzrrrkkkk"); 113 | addTheme(t); 114 | 115 | t=new Theme("stone","base theme"); 116 | t.set("WallTile",Tile.STONEWALL); 117 | t.set("FloorTile",Tile.STONEFLOOR); 118 | t.set("DungeonDNA","tttkrrroozhs"); 119 | t.set("DungeonDensity",0.15); 120 | addTheme(t); 121 | 122 | t=new Theme("goblins","caves"); 123 | t.set("MonsterType","IsGoblinoid"); 124 | addTheme(t); 125 | 126 | t=new Theme("goblin village","goblins"); 127 | t.set("MonsterType","IsGoblinoid"); 128 | t.set("WallTile",Tile.CAVEWALL); 129 | t.set("FloorTile",Tile.FORESTFLOOR); 130 | addTheme(t); 131 | 132 | t=new Theme("dungeon","standard"); 133 | addTheme(t); 134 | 135 | t=new Theme("metal","base theme"); 136 | t.set("WallTile",Tile.METALWALL); 137 | t.set("FloorTile",Tile.METALFLOOR); 138 | t.set("DungeonDNA","tttkrrroozhs"); 139 | t.set("DungeonDensity",0.2); 140 | addTheme(t); 141 | 142 | t=new Theme("plains","base theme"); 143 | t.set("WallTile",Tile.CAVEWALL); 144 | t.set("FloorTile",Tile.GRASS); 145 | addTheme(t); 146 | 147 | t=new Theme("swamp","base theme"); 148 | t.set("WallTile",Tile.CAVEWALL); 149 | t.set("FloorTile",Tile.GUNK); 150 | addTheme(t); 151 | 152 | 153 | t=new Theme("village","base theme"); 154 | t.set("WallTile",Tile.CAVEWALL); 155 | t.set("FloorTile",Tile.GRASS); 156 | addTheme(t); 157 | } 158 | 159 | public static Theme getTheme(String s) { 160 | if (themes==null) { 161 | init(); 162 | } 163 | 164 | Theme t=(themes.get(s)); 165 | 166 | if (t==null) throw new Error("Theme ["+s+"] not found!"); 167 | 168 | return t; 169 | } 170 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/Time.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 12-Jun-2004 3 | * 4 | * To change the template for this generated file go to 5 | * Window - Preferences - Java - Code Generation - Code and Comments 6 | */ 7 | package mikera.tyrant; 8 | 9 | import mikera.tyrant.engine.Map; 10 | import mikera.tyrant.engine.Thing; 11 | 12 | /** 13 | * @author Mike 14 | * 15 | * To change the template for this generated type comment go to Window - 16 | * Preferences - Java - Code Generation - Code and Comments 17 | */ 18 | public class Time { 19 | public static void advance(int t) { 20 | int advance=t; 21 | Thing h=Game.hero(); 22 | 23 | //Game.warn("Time.advance: "+t); 24 | 25 | while (advance >= 0) { 26 | Map map=h.getMap(); 27 | 28 | // divide into smaller steps if needed 29 | int step = advance; 30 | 31 | // call map action 32 | if (map!=null) { 33 | if ((step > 100)&&(!map.getFlag("IsWorldMap"))) 34 | step = 100; 35 | 36 | Event actionEvent=Event.createActionEvent(step); 37 | map.action(actionEvent); 38 | Quest.notifyAction(actionEvent); 39 | } 40 | 41 | advance -= step; 42 | 43 | if (advance==0) break; 44 | } 45 | 46 | logTime(t); 47 | h.incStat("TurnCount",1); 48 | } 49 | 50 | public static void logTime(int t) { 51 | Thing h=Game.hero(); 52 | h.incStat("GameTime",t); 53 | 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/TitleScreen.java: -------------------------------------------------------------------------------- 1 | // 2 | // A simple class to display the title image 3 | // 4 | package mikera.tyrant; 5 | 6 | import java.awt.Graphics; 7 | import java.awt.Image; 8 | 9 | public class TitleScreen extends Screen { 10 | 11 | public TitleScreen(QuestApp q) { 12 | super(q); 13 | } 14 | 15 | private static final long serialVersionUID = 3904958651298164789L; 16 | 17 | public void paint(Graphics g) { 18 | super.paint(g); 19 | Image im = QuestApp.title; 20 | g.drawImage(im, (getBounds().width - im.getWidth(null)) / 2, 21 | (getBounds().height - im.getHeight(null)) / 2, null); 22 | 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/engine/Description.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.engine; 2 | 3 | // interface for all object descriptions 4 | // Describer is the standard Description object 5 | public interface Description { 6 | // Description type constants 7 | public static final int NAMETYPE_NORMAL = 0; // most items and monsters 8 | public static final int NAMETYPE_PROPER = 1; // proper names 9 | public static final int NAMETYPE_QUANTITY = 2; // materials, measurable 10 | // quantities and plural 11 | // nouns (e.g. "trousers") 12 | 13 | public static final int GENDER_NEUTER = 0; 14 | public static final int GENDER_MALE = 1; 15 | public static final int GENDER_FEMALE = 2; 16 | 17 | public static final int CASE_NOMINATIVE = 0; 18 | public static final int CASE_ACCUSATIVE = 1; 19 | public static final int CASE_GENITIVE = 2; 20 | 21 | public static final int ARTICLE_NONE = 0; 22 | public static final int ARTICLE_DEFINITE = 1; 23 | public static final int ARTICLE_INDEFINITE = 2; 24 | public static final int ARTICLE_POSSESIVE = 3; 25 | 26 | public static final int NUMBER_SINGULAR = 1; 27 | public static final int NUMBER_PLURAL = 1000000; 28 | 29 | public String getName(int number, int article); 30 | 31 | public String getDescriptionText(); 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/engine/Point.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.engine; 2 | 3 | import mikera.util.Maths; 4 | import mikera.util.Rand; 5 | 6 | 7 | /** 8 | * Just a simple (x,y) point 9 | * 10 | * Used by maps for passing return values, 11 | * e.g. Map.findFreeSquare() 12 | * 13 | * @author Mike 14 | * 15 | */ 16 | public final class Point implements java.io.Serializable { 17 | private static final long serialVersionUID = 3256720701829165623L; 18 | public int x=0; 19 | public int y=0; 20 | 21 | public Point() { 22 | // default point is (0,0) 23 | } 24 | 25 | public Point(int px, int py) { 26 | x = px; 27 | y = py; 28 | } 29 | 30 | public Point(Thing t) { 31 | x = t.x; 32 | y = t.y; 33 | } 34 | 35 | /** 36 | * Calculate distance based on horizontal/vertical aligned square 37 | * @param a point to compare with 38 | * @return distance 39 | */ 40 | public int hvDistance(Point a) { 41 | return Maths.max(Math.abs(x-a.x),Math.abs(y-a.y)); 42 | } 43 | 44 | public Point(Point p) { 45 | x = p.x; 46 | y = p.y; 47 | } 48 | 49 | public void offset(int dx, int dy) { 50 | x += dx; 51 | y += dy; 52 | } 53 | 54 | public String toString() { 55 | return x + "," + y; 56 | } 57 | 58 | public static Point randomDirection(boolean diagonals) { 59 | if (!diagonals) { 60 | return randomDirection4(); 61 | } 62 | 63 | return randomDirection8(); 64 | } 65 | 66 | public static Point randomDirection4() { 67 | int dx = 0; 68 | int dy = 0; 69 | switch (Rand.d(4)) { 70 | case 1 : 71 | dx = 1; 72 | break; //W 73 | case 2 : 74 | dx = -1; 75 | break; //E 76 | case 3 : 77 | dy = 1; 78 | break; //N 79 | case 4 : 80 | dy = -1; 81 | break; //S 82 | } 83 | return new Point(dx,dy); 84 | } 85 | 86 | public static Point randomDirection8() { 87 | int dx = 0; 88 | int dy = 0; 89 | switch (Rand.d(8)) { 90 | case 1 : 91 | dx = 1; 92 | break; //W 93 | case 2 : 94 | dx = -1; 95 | break; //E 96 | case 3 : 97 | dy = 1; 98 | break; //N 99 | case 4 : 100 | dy = -1; 101 | break; //S 102 | case 5 : 103 | dx = 1; 104 | dy=1; 105 | break; //W 106 | case 6 : 107 | dx = -1; 108 | dy=-1; 109 | break; //E 110 | case 7 : 111 | dy = 1; 112 | dx=-1; 113 | break; //N 114 | case 8 : 115 | dy = -1; 116 | dx=1; 117 | break; //S 118 | } 119 | return new Point(dx,dy); 120 | 121 | } 122 | public boolean equals(Object obj) { 123 | if (obj instanceof Point) { 124 | Point pt = (Point) obj; 125 | return (x == pt.x) && (y == pt.y); 126 | } 127 | return super.equals(obj); 128 | } 129 | 130 | public int hashCode() { 131 | long bits = java.lang.Double.doubleToLongBits(x); 132 | bits ^= java.lang.Double.doubleToLongBits(y) * 31; 133 | return (((int) bits) ^ ((int) (bits >> 32))); 134 | } 135 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/engine/Script.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 27-Jun-2004 3 | * 4 | */ 5 | package mikera.tyrant.engine; 6 | 7 | import mikera.tyrant.engine.BaseObject; 8 | import mikera.tyrant.Event; 9 | import mikera.tyrant.EventHandler; 10 | 11 | /** 12 | * @author Mike 13 | * 14 | * Script represents a piece of code that can respond 15 | * to an Event. 16 | * 17 | * Script should be subclassed with handle(...) overriden 18 | * in order to implement scripted behaviour 19 | * 20 | */ 21 | public class Script extends BaseObject implements EventHandler { 22 | 23 | private static final long serialVersionUID = -8185055965927876189L; 24 | 25 | /** 26 | * Stub event handler 27 | * 28 | * @param t The Thing to which the event has been sent 29 | * @param e The event to respond to 30 | */ 31 | public boolean handle(Thing t, Event e) { 32 | 33 | return false; 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/engine/StringList.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.engine; 2 | 3 | public class StringList { 4 | private String[] strings = new String[3]; 5 | private int size = 3; 6 | private int count = 0; 7 | private static final int delta = 3; 8 | 9 | public void ensureSize(int s) { 10 | if (s > size) { 11 | s = s + delta; 12 | String[] newstrings = new String[s]; 13 | for (int i = 0; i < count; i++) 14 | newstrings[i] = strings[i]; 15 | size = s; 16 | strings = newstrings; 17 | } 18 | } 19 | 20 | public int getCount() { 21 | return count; 22 | } 23 | 24 | public void add(String s) { 25 | ensureSize(count + 1); 26 | strings[count] = s; 27 | count = count + 1; 28 | } 29 | 30 | public void setString(int i, String s) { 31 | if ((i < 0) || (i >= count)) 32 | return; 33 | if (s == null) 34 | throw new NullPointerException(); 35 | strings[i] = s; 36 | } 37 | 38 | public String getString(int i) { 39 | if ((i < 0) || (i >= count)) 40 | return null; 41 | return strings[i]; 42 | } 43 | 44 | public String getText(String delimiter) { 45 | if (count <= 0) 46 | return ""; 47 | StringBuffer sb = new StringBuffer(strings[0]); 48 | for (int i = 1; i < count; i++) { 49 | sb.append(delimiter); 50 | sb.append(strings[i]); 51 | } 52 | return sb.toString(); 53 | } 54 | 55 | public void insert(String s, int p) { 56 | if (s == null) 57 | throw new NullPointerException(); 58 | ensureSize(count + 1); 59 | if (p < 0) 60 | p = 0; 61 | if (p > count) 62 | p = count; 63 | if (count > p) 64 | System.arraycopy(strings, p, strings, p + 1, count - p); 65 | strings[p] = s; 66 | count++; 67 | } 68 | 69 | public void swap(int a, int b) { 70 | if ((a >= 0) && (b >= 0) && (a < count) && (b < count)) { 71 | String s = strings[a]; 72 | strings[a] = strings[b]; 73 | strings[b] = s; 74 | } 75 | } 76 | 77 | // sort the strings 78 | public void sort() { 79 | boolean end = false; 80 | while (end == false) { 81 | end = true; 82 | for (int i = 0; i < (count - 1); i++) { 83 | if (strings[i].compareTo(strings[i + 1]) > 0) { 84 | swap(i, i + 1); 85 | end = false; 86 | } 87 | } 88 | } 89 | } 90 | 91 | // compresses identical items and adds count 92 | public StringList compress() { 93 | sort(); 94 | StringList s = new StringList(); 95 | if (count <= 0) 96 | return s; 97 | int c = 1; 98 | String d = strings[0]; 99 | for (int i = 1; i < count; i++) { 100 | if (strings[i].compareTo(d) != 0) { 101 | s.add((c == 1) ? d : d + " (x" + Integer.toString(c) + ")"); 102 | d = strings[i]; 103 | c = 0; 104 | } 105 | c++; 106 | } 107 | s.add((c == 1) ? d : d + " (x" + Integer.toString(c) + ")"); 108 | return s; 109 | } 110 | 111 | public StringList compact(int len, String sep) { 112 | StringList s=new StringList(); 113 | if (count<=0) return s; 114 | String t=strings[0]; 115 | for (int i=1; ilen) { 118 | s.add(t+sep); 119 | t=strings[i]; 120 | } else { 121 | t=t+sep+strings[i]; 122 | } 123 | } 124 | s.add(t); 125 | return s; 126 | } 127 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/engine/ThingOwner.java: -------------------------------------------------------------------------------- 1 | // 2 | // Interface to descibe an object capable of containing 3 | // one or more instances of Thing 4 | // 5 | // e.g. 6 | // Maps 7 | // Beings with inventories 8 | // Boxes/bags 9 | // 10 | 11 | package mikera.tyrant.engine; 12 | 13 | 14 | public interface ThingOwner { 15 | 16 | public void removeThing(Thing thing); 17 | 18 | public Map getMap(); 19 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/Count.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.util; 2 | 3 | public class Count { 4 | public int value = 0; 5 | 6 | public Count() { 7 | this(0); 8 | } 9 | public Count(int value) { 10 | this.value = value; 11 | } 12 | 13 | public String toString() { 14 | return String.valueOf(value); 15 | } 16 | 17 | public void increment() { 18 | value++; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/LibMetaData.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.util; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | import java.util.ArrayList; 6 | import java.util.Iterator; 7 | 8 | /** 9 | * 10 | * @author Carsten Muessig 11 | */ 12 | 13 | public class LibMetaData { 14 | 15 | private static LibMetaData instance = null; 16 | private TreeMap metaData; // key = thing name, value = MetaData of thing 17 | 18 | private LibMetaData() { 19 | metaData = new TreeMap<>(); 20 | } 21 | 22 | protected static LibMetaData instance() { 23 | if (instance == null) { 24 | instance = new LibMetaData(); 25 | LibMetaDataHandler.createLibMetaData(instance); 26 | } 27 | return instance; 28 | } 29 | 30 | protected void add(String thingName, MetaData thing) { 31 | metaData.put(thingName, thing); 32 | } 33 | 34 | protected TreeMap getAll() { 35 | return metaData; 36 | } 37 | 38 | protected MetaData get(String thingName) { 39 | return metaData.get(thingName); 40 | } 41 | 42 | protected String describes(Map item) { 43 | ArrayList metaDataNames = new ArrayList<>(); 44 | Iterator it = metaData.keySet().iterator(); 45 | while (it.hasNext()) { 46 | String libItemName = it.next(); 47 | MetaData libItem = metaData.get(libItemName); 48 | if (libItem.describes(item, false)) 49 | metaDataNames.add(libItemName); 50 | } 51 | if (metaDataNames.size() == 0) 52 | System.out.println(" The item doesn't match any library meta data"); 53 | if (metaDataNames.size() == 1) { 54 | System.out.println(" The item matches the library meta data \"" + metaDataNames.get(0) + "\""); 55 | return metaDataNames.get(0); 56 | } 57 | if (metaDataNames.size() > 1) { 58 | System.out.println(" The item is ambiguous, " 59 | + metaDataNames.size() 60 | + " matching descriptions were found: " + metaDataNames); 61 | System.out 62 | .println(" Reasons: Faulty plug-in data or faulty meta data inside the program"); 63 | System.out 64 | .println(" Please contact the Tyrant developers if you're not sure and provide your plug-in file"); 65 | } 66 | return null; 67 | } 68 | 69 | public static boolean isKnownProperty(String property) { 70 | TreeMap metaData = instance().getAll(); 71 | Iterator it = metaData.keySet().iterator(); 72 | while (it.hasNext()) { 73 | String thingName = it.next(); 74 | MetaData meta = metaData.get(thingName); 75 | if (meta.get(property) != null) 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | public static boolean isValidProperty(String property, Object value) { 82 | TreeMap metaData = instance().getAll(); 83 | Iterator it = metaData.keySet().iterator(); 84 | MetaDataEntry med = null; 85 | while (it.hasNext()) { 86 | String thingName = it.next(); 87 | MetaData meta = metaData.get(thingName); 88 | if (meta.get(property) != null) { 89 | System.out.println(meta.getAll().keySet()); 90 | med = meta.get(property); 91 | System.out.println(med.getValue()); 92 | break; 93 | } 94 | } 95 | if (med != null) 96 | return med.describes(value); 97 | System.out.println("No meta data for "+property+" available"); 98 | return false; 99 | } 100 | 101 | public static String getPropertyDescription(String property) { 102 | return LibMetaDataHandler.createPropertyDescriptions().get(property); 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/MetaData.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.util; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | import java.util.Set; 6 | import java.util.Iterator; 7 | 8 | /** 9 | * 10 | * @author Carsten Muessig 11 | */ 12 | 13 | public class MetaData { 14 | 15 | private TreeMap metaDataEntries; // key = property name, value = MetaDataEntry 16 | 17 | protected MetaData() { 18 | metaDataEntries = new TreeMap<>(); 19 | } 20 | 21 | protected MetaData(MetaData parent) { 22 | this(); 23 | if(parent!=null) 24 | metaDataEntries.putAll(parent.getAll()); 25 | } 26 | 27 | protected void add(String propertyName, MetaDataEntry property) { 28 | metaDataEntries.put(propertyName, property); 29 | } 30 | 31 | protected void add(String propertyName, Object value, Object[] validValues, int valueCondition, int propertyCondition) { 32 | add(propertyName, new MetaDataEntry(value, validValues, valueCondition, propertyCondition)); 33 | } 34 | 35 | protected TreeMap getAll() { 36 | return metaDataEntries; 37 | } 38 | 39 | protected MetaDataEntry get(String property) { 40 | return metaDataEntries.get(property); 41 | } 42 | 43 | protected int numberOfMandatoryProperties() { 44 | int number = 0; 45 | Iterator it = metaDataEntries.keySet().iterator(); 46 | while(it.hasNext()) { 47 | MetaDataEntry tmd = metaDataEntries.get(it.next()); 48 | if(tmd.isMandatory()) 49 | number++; 50 | } 51 | return number; 52 | } 53 | 54 | protected boolean describes(Map properties, boolean isMetaData) { 55 | int mandatoryPropertiesChecked = 0; 56 | Set propertyNames = properties.keySet(); 57 | if(metaDataEntries.keySet().containsAll(propertyNames)) { 58 | Iterator it = propertyNames.iterator(); 59 | while(it.hasNext()) { 60 | String propertyName = it.next(); 61 | if(isMetaData) 62 | System.out.println(" Checking meta data property \""+propertyName+"\""); 63 | else 64 | System.out.println(" Checking property \""+propertyName+"\""); 65 | MetaDataEntry mde = metaDataEntries.get(propertyName); 66 | if((mde!=null)&&(mde.describes(properties.get(propertyName)))) { 67 | if(mde.isMandatory()) 68 | mandatoryPropertiesChecked++; 69 | if(isMetaData) 70 | System.out.println(" Meta data property \""+propertyName+"\" successful checked"); 71 | else 72 | System.out.println(" Property \""+propertyName+"\" successful checked"); 73 | } else { 74 | if(isMetaData) 75 | System.out.println(" Meta data property \""+propertyName+"\" not successful checked."); 76 | else 77 | System.out.println(" Property \""+propertyName+"\" not successful checked."); 78 | } 79 | } 80 | } 81 | return mandatoryPropertiesChecked==numberOfMandatoryProperties(); 82 | } 83 | } -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/TyrantException.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.util; 2 | 3 | @SuppressWarnings("serial") 4 | public class TyrantException extends RuntimeException { 5 | public TyrantException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/example_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | my own armour 5 | 50 6 | 70 7 | 340 8 | Items 9 | 1 10 | 1 11 | 1 12 | 20000 13 | 1 14 | 0 15 | 1 16 | 9 17 | 20 18 | 19 | 20 | my own potion 21 | 60 22 | 3 23 | 8 24 | 240 25 | Items 26 | 1 27 | 1 28 | 1 29 | 1 30 | 1 31 | 500 32 | 0 33 | 1 34 | my own potion 35 | 36 | 37 | 2000 38 | 100 39 | Modifier 40 | 100 41 | MoveSpeed 42 | Target 43 | 2000 44 | TemporaryEffect 45 | 46 | 47 | 20 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/tyrantLibraryItems.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tyrant Library Items 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Tyrant 15 | Library Items 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Property 27 | Value 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/mikera/tyrant/util/tyrantLibrarySpecification.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tyrant Library Specification 6 | 7 | 8 | 9 | 10 | 11 | 12 | Tyrant 13 | Library Specification 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1. Property Specification 29 | 30 | 31 | Property 32 | Type 33 | Description 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 2. Item Specification 53 | 54 | Item: 55 | 56 | 57 | Property 58 | Mandatory 59 | Value 60 | Value condition 61 | Valid values 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Property 79 | Mandatory 80 | Value 81 | Value condition 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/main/resources/images/.cvsignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | .xvpics 3 | candidates 4 | -------------------------------------------------------------------------------- /src/main/resources/images/Tyrant-Header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/Tyrant-Header.jpg -------------------------------------------------------------------------------- /src/main/resources/images/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/cancel.png -------------------------------------------------------------------------------- /src/main/resources/images/creature32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/creature32.png -------------------------------------------------------------------------------- /src/main/resources/images/effects32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/effects32.png -------------------------------------------------------------------------------- /src/main/resources/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/images/hero.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/hero.ico -------------------------------------------------------------------------------- /src/main/resources/images/isOverlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/isOverlay.gif -------------------------------------------------------------------------------- /src/main/resources/images/items32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/items32.png -------------------------------------------------------------------------------- /src/main/resources/images/plus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/plus.gif -------------------------------------------------------------------------------- /src/main/resources/images/scenery32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/scenery32.png -------------------------------------------------------------------------------- /src/main/resources/images/texture1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/texture1.png -------------------------------------------------------------------------------- /src/main/resources/images/texture2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/texture2.png -------------------------------------------------------------------------------- /src/main/resources/images/texture3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/texture3.png -------------------------------------------------------------------------------- /src/main/resources/images/tiles32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/tiles32.png -------------------------------------------------------------------------------- /src/main/resources/images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikera/tyrant/641a5915985ce17065dbc3328333257093bf5b72/src/main/resources/images/title.png -------------------------------------------------------------------------------- /src/main/resources/maps/special/firetop.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaaaaaaaaaaaaa 3 | aabbbbbbbbabbbbabbba 4 | aabbbbbbbbabbbbabbba 5 | aabbbbbbbbabbbbabbba 6 | aabbbbbbbbaabaaabbba 7 | aabbbbbbbbabbbbbbbba 8 | aaaaaaaabbabbbbbbbba 9 | abbbbbbabbbbbbbbbaaa 10 | abbbbbbabbabbbbbbacc 11 | aaaaaaaabbaaaaaaaacc 12 | abbabbbabbabbbbbbbcc 13 | abbabbbabbabbbbbbbcc 14 | abbbbbbbbbbbbbbbbbcc 15 | aababbbabbabbbabaacc 16 | abbabbbabbabbaabbaac 17 | abbabbbabbabbabbbbac 18 | abbaabaabbaaaabbbbac 19 | abbadddabbaddaabbaac 20 | aaaaddddbbddddabaadc 21 | aaadddddbbdddddddddc 22 | aaddddddbbddedddddac 23 | aaddddddbbeeedddddcc 24 | aaddddddbbddddddddcd 25 | aadddddddeeddeddddcd 26 | aaaddddefedddddddaca 27 | aaaadeeedddeddedaaca 28 | aaaaedddfeddddedaaca 29 | aaaaddeeffdfededdaca 30 | aaaaddeefddddddddccd 31 | aaadddddfeefdddedced 32 | ddddddeedddddddedcdd 33 | ddddddeeddfdeddddcde 34 | dddddeedddddfffddcdd 35 | dddddddddddddeedfcdd 36 | ddddeddddddeeddddcde 37 | ddddeddddddddddeecee 38 | ddddddeddddefeeeffee 39 | dddddddddeeefeeffffe 40 | ddddddddeefffeeffffe 41 | dddddddeeffffffffffe 42 | dddddddeefffffeffffe 43 | dddddddeffffffeffffe 44 | dddddddeffffffeffffe 45 | eddddddeefffffeffffe 46 | eedddddeeefffeeeefee 47 | eeedddddeefffeeeeeee 48 | eeeedddddeffefeeeeee 49 | eeeeeddddfffffeefffe 50 | eeeeeddddfefffeffffe 51 | eeeeeddddfffffeffffe 52 | eeeeedddeefffeeffffe 53 | eeeeedddeefefeeffeee 54 | eeeeedddeeffffeeeeee 55 | eeeeedddeeffffeeeeed 56 | eeeeddddeeefffeeeeed 57 | eeeedddeeeeffeeeeedd 58 | eeeddddeeeffffeeeedd 59 | eeddddeeeeffffeeeedd 60 | eeddddeeeeffffeeeddd 61 | eedddeeeefffffeedddd 62 | eedddeeeeffffddddddd 63 | eedddeefffffdddddddd 64 | eedddeeffffdddddddde 65 | eedddeeeccddddddddee 66 | eedddeddcccdddddeeee 67 | eedddddddcccddeeeeee 68 | eeddddddddccfeeeeeee 69 | eedddddddeefffeeeeee 70 | eeedddddeeeeffeeeeee 71 | eeeddddeeeeeffeeeeee 72 | eeeddddeeeeeefeeeeee 73 | eeedddddeeeeefeeeeee 74 | eeedddddeeeeffeeeeee 75 | eeeedddddeeeffeeeeee 76 | eeeedddddeefffeeeeee 77 | eeeeeddddfefffeeeeee 78 | eeeeeedddfffffeeeeee 79 | eeeeeeeddfffddeeeeee 80 | eeeeeeeddfffddeeeeee 81 | eeeeeeedddfdddeeeeee 82 | ---Tiles--- 83 | 84 | ---Legend--- 85 | a = metal wall 86 | b = red floor 87 | c = stone floor 88 | d = lava 89 | e = cave wall 90 | f = cave floor 91 | ---Legend--- 92 | 93 | ---Properties--- 94 | Description = Firetop Mountain 95 | FloorTile = 1 96 | Level = 33 97 | MonsterType = IsDragon 98 | WallTile = 10 99 | WanderingRate = 100 100 | ---Properties--- 101 | 102 | ---Things--- 103 | 2x2 red dragon 104 | 9x2 red dragon 105 | 5x3 black dragon 106 | 12x4 golden portcullis 107 | KeyName = brass key 108 | 2x6 secret door 109 | 12x6 black dragon 110 | 1x7 frost dragon 111 | 4x7 red dragon 112 | 5x7 black dragon 113 | 6x7 artifact point 114 | 10x7 trapped black door 115 | KeyName = dull key 116 | 14x7 red dragon 117 | 1x8 artifact point 118 | 2x8 blue dragon 119 | 3x8 blue dragon 120 | 4x8 frost dragon 121 | 5x8 red dragon 122 | 6x8 black dragon 123 | 3x12 trapped black door 124 | KeyName = copper key 125 | 7x12 trapped black door 126 | KeyName = copper key 127 | 10x12 enchanted door 128 | KeyName = iron key 129 | 2x13 trapped black door 130 | KeyName = copper key 131 | 15x13 enchanted door 132 | KeyName = brass key 133 | 1x14 frost dragon 134 | 2x14 frost dragon 135 | 1x15 frost dragon 136 | 2x15 frost dragon 137 | 4x15 red dragon 138 | 1x16 frost dragon 139 | 2x16 frost dragon 140 | 5x16 invincible portcullis 141 | KeyName = skull key 142 | 1x17 frost dragon 143 | 2x17 frost dragon 144 | 8x17 trapped black door 145 | KeyName = iron key 146 | 9x17 trapped black door 147 | KeyName = bronze key 148 | 15x17 red dragon 149 | 15x18 invincible portcullis 150 | KeyName = golden key 151 | 5x22 red dragon 152 | 14x22 red dragon 153 | 18x24 trapped black door 154 | KeyName = golden key 155 | 18x25 red dragon 156 | 18x26 red dragon 157 | 18x27 trapped black door 158 | KeyName = ornate key 159 | 13x28 red dragon 160 | 4x29 red dragon 161 | 14x39 trapped black door 162 | KeyName = golden key 163 | 11x40 red dragon 164 | 17x40 frost dragon 165 | 18x40 frost dragon 166 | 17x41 blue dragon 167 | 16x47 skeletal dragon 168 | 17x47 fearsome skeleton 169 | 18x47 fearsome skeleton 170 | 14x48 secret door 171 | 15x48 skeleton hero 172 | 16x48 skeletal dragon 173 | 17x48 fearsome skeleton 174 | 18x48 artifact point 175 | 15x49 skeleton hero 176 | 16x49 skeletal dragon 177 | 17x49 skeleton lord 178 | 18x49 fearsome skeleton 179 | 15x50 skeleton hero 180 | 16x50 horrendous zombie 181 | 17x50 skeleton lord 182 | 18x50 fearsome skeleton 183 | 15x51 horrendous zombie 184 | 16x51 horrendous zombie 185 | 12x53 blue dragon 186 | 13x58 blue dragon 187 | 9x60 green dragon 188 | 11x61 blue dragon 189 | 12x69 green dragon 190 | 10x79 entrance point 191 | ---Things--- 192 | -------------------------------------------------------------------------------- /src/main/resources/maps/special/woodfort.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaaaaaaaaabbbbaaaaaaaaaa 3 | aaaaaaaaaaaaaaabbbbaaaaaaaaaaa 4 | aaaaaaaaaaaaaaabbbaaaaaaaaaaaa 5 | aaaaaaaaacaaabbbbbaaaaaaaacaaa 6 | acaaaaaaaaaaabbbbbcaaaaaaaaaaa 7 | aaaaaaaaaaaaabbbbbbaaaaaaaaaaa 8 | aaaaaaaaaaaddddbbbbaaaaaaaaaaa 9 | aaaaaacaaaddaaddbbbaaaddddaaaa 10 | aaaaaaaaaadaaaadbbbaacdaadaaaa 11 | aaaaaaaaaadaaaddddddaadaadaaaa 12 | aaaaaaaaaaddaadaaaadaadaddcaaa 13 | aaaaaaaaacaddddaaaadaaaaadaaaa 14 | aaaaaaaaaccaaaddaaddaaaaadddda 15 | aaaaaacaaaaaaaaaaaaaaaaaaaaada 16 | aacaaaaaaaaaaaaaaaaaaaaaadaada 17 | aaaaaaaaaaaaaaddddddacaaadddda 18 | aaaaaaacaaaaaadabbaaaaaaaaaaaa 19 | aaaaaaaaaaaacadabbadaaaaaacaaa 20 | aaaaaaaaaaaddddabbadaaaaaaddda 21 | aacaaaaaaaddaaaabbadaaaaaaaada 22 | aaaaaacaaadaaadddddddddddddada 23 | aaaaaaaaaadaaaadbbaaadaaaaddda 24 | aaaaaaaaaaddaaddbbaaaaaaaaadaa 25 | aacaaaaaaaaddddabbaaadaaaaadaa 26 | caaaaaaaaaaaaaaabaaaadaaaaadaa 27 | aaaaaaaaaaaaaaabbbaaadddddddaa 28 | aaaaaaaaaaaaaaabbbaaaaaaaaaaaa 29 | aaaaaaaaaaaaaabbbbaaaaaaaaaaaa 30 | aaaaaaaaaaaaaabbbaaaaaaaaaaaaa 31 | aaaaaaaaaaaaaabbbaaaaaaaaaaaaa 32 | ---Tiles--- 33 | 34 | ---Legend--- 35 | a = forest floor 36 | b = river 37 | c = tree wall 38 | d = cave wall 39 | ---Legend--- 40 | 41 | ---Properties--- 42 | Description = Unknown Area 43 | FloorTile = 1 44 | HashName = unknown 45 | Level = 1 46 | MonsterType = IsHostile 47 | WallTile = 10 48 | WanderingRate = 100 49 | ---Properties--- 50 | 51 | ---Things--- 52 | 12x7 [IsBandit] 53 | 13x7 [IsBandit] 54 | 11x8 [IsBandit] 55 | 12x8 [IsBandit] 56 | 14x8 [IsBandit] 57 | 23x8 [IsBandit] 58 | 11x9 [IsBandit] 59 | 13x9 [IsBandit] 60 | 20x9 barricade 61 | 21x9 barricade 62 | 24x9 [IsBandit] 63 | 12x10 [IsBandit] 64 | 14x10 secret door 65 | 16x10 [IsBandit] 66 | 18x10 [IsBandit] 67 | 20x10 bandit archer 68 | 21x10 bandit archer 69 | 23x10 locked door 70 | KeyName = copper key 71 | 15x11 [IsBandit] 72 | 17x11 [IsBandit] 73 | 19x11 secret door 74 | 16x12 invincible portcullis 75 | KeyName = iron key 76 | 17x12 invincible portcullis 77 | KeyName = ornate key 78 | 14x13 barricade 79 | 15x13 bandit archer 80 | 25x13 locked door 81 | KeyName = iron key 82 | 14x14 barricade 83 | 15x14 bandit archer 84 | 29x15 barricade 85 | 0x16 entrance point 86 | 15x16 [IsBandit] 87 | 19x16 locked door 88 | KeyName = bronze key 89 | 28x16 barricade 90 | 29x16 bandit archer 91 | 15x17 [IsBandit] 92 | 28x17 barricade 93 | 29x17 bandit archer 94 | 15x18 [IsBandit] 95 | 29x18 barricade 96 | 14x19 locked door 97 | KeyName = brass key 98 | 15x19 [IsBandit] 99 | 26x19 locked door 100 | KeyName = copper key 101 | 12x20 demon snake 102 | 11x21 warning point 103 | 11x21 potion of literacy 104 | 12x21 lesser demon 105 | 13x21 demon snake 106 | 12x22 demon vortex 107 | 13x22 lesser demon 108 | 21x22 strong door 109 | KeyName = iron key 110 | 18x24 bandit archer 111 | 19x26 bandit archer 112 | 18x28 bandit archer 113 | ---Things--- 114 | -------------------------------------------------------------------------------- /src/main/resources/maps/test/testmap.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaaaaaaaaaaaaa 3 | aaaaaaaaaaaaaaaaaaaa 4 | aaabbbaabbaaaaaaaaaa 5 | aabbbbbbbbabaaaaaaaa 6 | aabbbbbbbbccccaaaaaa 7 | aaabbbbbbccddddaaaaa 8 | aaabbbbbbcddbbdaaaaa 9 | aabbbbbbbeebbbdaaaaa 10 | aabbbbbbbcddbbdaaaaa 11 | aabbbbbbbcddbbdaaaaa 12 | aaabbbbbbccddddaaaaa 13 | aaabbbbbbbccccaaaaaa 14 | aaaabbbbbbbbbbaaaaaa 15 | aaaaaaaaaaaaaaaaaaaa 16 | aaaaaaaaaaaaaaaaaaaa 17 | aaaaaaaaaaaaaaaaaaaa 18 | aaaaaaaaaaaaaaaaaaaa 19 | aaaaaaaaaaaaaaaaaaaa 20 | aaaaaaaaaaaaaaaaaaaa 21 | aaaaaaaaaaaaaaaaaaaa 22 | ---Tiles--- 23 | 24 | ---Legend--- 25 | a = cave wall 26 | b = forest floor 27 | c = lava 28 | d = red wall 29 | e = parquet floor 30 | ---Legend--- 31 | 32 | ---Properties--- 33 | Description = Unknown Area 34 | Level = 1 35 | MonsterType = IsHostile 36 | WanderingRate = 100 37 | ---Properties--- 38 | 39 | ---Things--- 40 | 4x4 entrance point 41 | 12x6 [IsHostile] 42 | 11x7 [IsDoor] 43 | 12x7 [IsHostile] 44 | 12x8 [IsHostile] 45 | 4x9 entrance point 46 | 12x9 [IsHostile] 47 | 6x11 entrance point 48 | ---Things--- 49 | -------------------------------------------------------------------------------- /src/main/resources/maps/world/annenvale.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaabaaaaaaaaaaaa 3 | aaabaaabbbaaaaaaaaaa 4 | aabbbbaabbaaaacdddaa 5 | aaaaabbaabbaacddddaa 6 | aabbaaaabbaaccdddaaa 7 | aacccaaabbaaddddedaa 8 | abccbaabbdaacaddddaa 9 | accbaaabdaaaaddddcca 10 | acaaaaeeddaddcacaaaa 11 | acaeeeeedaadaaaacaaa 12 | acceaeeedaddaaacaaaa 13 | aaeeaeedddddaaaacaca 14 | aaeeaaadddbbdaaaacca 15 | aaaeeeddddbbbddaaaca 16 | aacaeedabbbbbbdacaaa 17 | acaaaadddbbeeebddddd 18 | aacddddccceeeeaabbca 19 | accccacaceebeecaccaa 20 | acaaaaaaaceeecaaacaa 21 | aaaaaaaaaaaaaaaaaaaa 22 | ---Tiles--- 23 | 24 | ---Legend--- 25 | a = mountains 26 | b = forests 27 | c = hills 28 | d = plains 29 | e = sea 30 | ---Legend--- 31 | 32 | ---Properties--- 33 | Description = The Annen Vale 34 | FloorTile = 1 35 | IsWorldMap = 1 36 | Level = 10 37 | MonsterType = IsHostile 38 | VisionRange = 4 39 | WallTile = 10 40 | WanderingRate = 0 41 | ---Properties--- 42 | 43 | ---Things--- 44 | 0x0 redistribution point 45 | 0x0 yanthrall temple 46 | 1x0 redistribution point 47 | 1x0 deep dungeon 48 | 2x0 redistribution point 49 | 3x0 redistribution point 50 | 7x0 wilds 51 | 16x4 town 52 | 9x8 dungeon 53 | 7x12 town 54 | 17x12 dungeon 55 | 19x15 karrain 56 | 1x18 grotto 57 | 17x18 mysterious dungeon 58 | ---Things--- 59 | -------------------------------------------------------------------------------- /src/main/resources/maps/world/doom.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaaaaaaaaaaaaa 3 | aaaaaaaaaaaaaaaaaaaa 4 | aaaaaaabbbbaaaaaaaaa 5 | aaaaabbbbbbbbbaaaaaa 6 | aaababbbbbbbabbbaaaa 7 | aaababbabbbbbbbbaaaa 8 | aaabbbbbaaaaabbbbaaa 9 | aaabbaabbaaaabbbbaaa 10 | aabbbaaaabcccbabbaaa 11 | aabbbacaabcacaabbaaa 12 | aabbaacbbbbacaabbbaa 13 | aabbbbcccccccaabbbaa 14 | aabbbaaaaacabbabbbaa 15 | aaabbbaabacaabbbbaaa 16 | aaabbbbabbcaaabbbaaa 17 | aaabbbbbbbcabbbbbbaa 18 | aaaaaabbbbcbbbbbaaaa 19 | aaaaaaabbbcbbbbaaaaa 20 | aaaaaaabbbcbbaaaaaaa 21 | aaaaaaaaaacaaaaaaaaa 22 | ---Tiles--- 23 | 24 | ---Legend--- 25 | a = cave wall 26 | b = lava sea 27 | c = stone floor 28 | ---Legend--- 29 | 30 | ---Properties--- 31 | Description = Inside Mount Doom 32 | FloorTile = 1 33 | IsWorldMap = 1 34 | Level = 20 35 | MonsterType = IsHostile 36 | WallTile = 10 37 | WanderingRate = 0 38 | ---Properties--- 39 | 40 | ---Things--- 41 | 6x9 dungeon 42 | 10x9 dark tower 43 | 10x19 wilds 44 | ---Things--- 45 | -------------------------------------------------------------------------------- /src/main/resources/maps/world/karrain.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaaaaaaabbbccc 3 | adaaaaaaaaaaaabbbbac 4 | adaaaeebeaaaaccbbbac 5 | adddeecbeeacccccbbbc 6 | aaeedcbbeeaccccccbbb 7 | addebbbbbeacccecccbb 8 | aaddebbbbeeeeeeeedbb 9 | aaedebbbbeeeeeeeeedb 10 | aaaeeeebbeceeeeeeaab 11 | aaaaaeeeeeeeeeeddaab 12 | accaaaaaeeeeeebbbbbb 13 | eecaaaeeeebbbbbcbbbb 14 | aeeeeeeeeeeeeecceebb 15 | aaeccaaaeeeeeeeeeebb 16 | aaaaaccccecceeeeeebb 17 | aaaacccccaeceeeeeebb 18 | aaaacccccaaeeeeeeebb 19 | aaaacccccaaceeebebbb 20 | aaaaaccaaaccebbbbbbb 21 | aaaaaaaaaabbbbbbbbbb 22 | ---Tiles--- 23 | 24 | ---Legend--- 25 | a = mountains 26 | b = sea 27 | c = forests 28 | d = hills 29 | e = plains 30 | ---Legend--- 31 | 32 | ---Properties--- 33 | Description = North Karrain Valley 34 | FloorTile = 1 35 | IsWorldMap = 1 36 | Level = 1 37 | MonsterType = IsHostile 38 | VisionRange = 4 39 | WallTile = 10 40 | WanderingRate = 0 41 | ---Properties--- 42 | 43 | ---Things--- 44 | 1x1 dwarftown 45 | 6x2 goblin village 46 | 19x2 town 47 | 13x3 ruin 48 | 13x7 tutorial inn 49 | 3x8 caves 50 | 13x9 town 51 | 0x11 annenvale 52 | 2x13 graveyard 53 | 10x15 town 54 | 6x16 dark forest 55 | 13x17 town 56 | ---Things--- 57 | -------------------------------------------------------------------------------- /src/main/resources/maps/world/wilds.txt: -------------------------------------------------------------------------------- 1 | ---Tiles--- 2 | aaaaaaaaabbbbbbbbbbbbbcbbbbbbbbbbbbbbbbb 3 | abaaaaaaabbbbbbbbbbbbbcbbbbbbbbbbbbbbbbb 4 | aabaaabaabddbbbddbbbbbdbbbbbbbdddbbbbbbb 5 | babaaaaebbdbbbbbddbbbddddbbbbbdbbbbbebbb 6 | aaaaaaaabedeebbbbddbbddbdbbbdddbbbbbbbbb 7 | bbaaabaabeededebbbdddbdbddbdddddbebbbbbb 8 | aaaaabaadbddbdebbbbdddddddddbbddbbbebbbb 9 | aaabaaaadebdbdbbebbbdddddddbbbbbbbbbbbbb 10 | aaaaaababbddddeebbbbdddddbbbbbebbebebbbb 11 | aabaaaaaaeebddebbdbbbbdbbbbdbbbbbebbbbbb 12 | aaaabbbaaaaebbeddddbbbebbddddebebeebbbbb 13 | abbbbbbbbaaabbbddddbbdddddbdbddeebdebbbb 14 | bbbbbbbebbaaaeedddddddddbdddddddbdddbeeb 15 | bbbbbbbbaaaaaadbddeddbebddddbddddddddbbb 16 | bbbbbbfbaaaaaaabddbdddbbbbbbbbbdddddbbbb 17 | bbfffffbbabaaaaabddddddebbbbbbdbdddddbbb 18 | bbffbffffaabbaaaadbdedbbbebbbeddddedbbbb 19 | bbfffffbfbbbaaaaabbdebdebbbbeddbbbebebbb 20 | bbfffbffffbbaaaaaaadbbebbbbbeebbebbbbbbb 21 | bfffffffffbbbaaaaaabfbbbbbbbbbbbbbbbbbbb 22 | bbfffbbffbbbbbafffffdfbbbbbbbbbbbbbbbbbb 23 | bbbfffffbbbbbeffbbfffbfbbbbbbbbbbgbbbbbb 24 | bbbfffbbeebbbefbbfbfdfdbbbbbbbbgggbbbbbb 25 | bbfbfffffbbffeffffffbbbbbbbbggggggbbbbbb 26 | bbbfffbfebdfffbffffdbfbbbbbggbbggbbbbbbb 27 | bbffffffffffffffbfffffbbbdggbbbggbbbbbbb 28 | bbfffffbbeffffffffffdbddddddbbbgbbbbbbbb 29 | bbfffffbbdbffffffffdffddddddddbgbbbbbbbb 30 | bbffbfbeebbfffffffffffddddddddbgbbbbbbbb 31 | bbbfffbbefffdfffffffeddddbdbbdggbbbbbbbb 32 | bbbfbfbbeebdffffbeefbddddbbbbdgbbbbbbbbb 33 | bbbbbbaabebbfffefefffbddddbdfdbbbbbbbbbb 34 | bbfbaaabbeeffebbffbdffddddbdbdbbbbbbbbbb 35 | bfaaaabbbbbbdefbfbbbddbbddddbbbbbbbbbbbb 36 | aaaaddabaabebbdbbbdddddddddbbbbbbbbbbbbb 37 | aaaaadaaaaaabeeebbbbddddddbbbbbbbbbbbbbb 38 | bffaaaaaaaaaaabebbbbbbddbbbbbbbbbbbbbbbb 39 | bbffffaaabfbfbbbbbbbbbddbbbbbbbbbbbbbbbb 40 | bbbbffffffbbbbbbbbbbbbbdbbbbbbbbbbbbbbbb 41 | bbbbbbbbbbbbbbbbbbbbbbbdbbbbbbbbbbbbbbbb 42 | ---Tiles--- 43 | 44 | ---Legend--- 45 | a = sea 46 | b = mountains 47 | c = stone floor 48 | d = plains 49 | e = hills 50 | f = forests 51 | g = lava sea 52 | ---Legend--- 53 | 54 | ---Properties--- 55 | Description = The Northern Wilds 56 | FloorTile = 1 57 | IsWorldMap = 1 58 | Level = 15 59 | MonsterType = IsHostile 60 | WallTile = 10 61 | WanderingRate = 0 62 | ---Properties--- 63 | 64 | ---Things--- 65 | 0x0 redistribution point 66 | 1x0 redistribution point 67 | 2x0 redistribution point 68 | 3x0 redistribution point 69 | 4x0 redistribution point 70 | 5x0 redistribution point 71 | 6x0 redistribution point 72 | 22x0 doom 73 | 34x21 firetop 74 | 23x39 annenvale 75 | ---Things--- 76 | -------------------------------------------------------------------------------- /src/main/resources/version.txt: -------------------------------------------------------------------------------- 1 | version=1.0.0 -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/CreateLib.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.RPG; 5 | 6 | 7 | public class CreateLib implements IWork { 8 | public void run() { 9 | Lib.instance(); 10 | } 11 | 12 | public void setUp() { 13 | RPG.setRandSeed(0); 14 | Lib.clear(); 15 | } 16 | 17 | public String getMessage() { 18 | return ""; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/IThingsInspector.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import mikera.tyrant.engine.Thing; 4 | 5 | 6 | public interface IThingsInspector { 7 | void inspect(Thing thing); 8 | void printResults(); 9 | void setup(String[] args); 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/IWork.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | 4 | public interface IWork extends Runnable { 5 | void setUp(); 6 | String getMessage(); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/KillAllBaddies.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import mikera.engine.BaseObject; 4 | import mikera.tyrant.Action; 5 | import mikera.tyrant.Game; 6 | import mikera.tyrant.GameScreen; 7 | import mikera.tyrant.Hero; 8 | import mikera.tyrant.QuestApp; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.RPG; 12 | import mikera.tyrant.engine.Thing; 13 | import mikera.tyrant.test.MapHelper; 14 | import mikera.tyrant.test.NullHandler; 15 | import mikera.tyrant.test.TyrantTestCase; 16 | 17 | 18 | public class KillAllBaddies implements IWork { 19 | private Thing hero; 20 | private Map map; 21 | private GameScreen gameScreen; 22 | 23 | public KillAllBaddies() { 24 | // empty 25 | } 26 | 27 | public void run() { 28 | boolean originalGetSet = BaseObject.GET_SET_DEBUG; 29 | // int ticks = -1; 30 | try { 31 | while (monstersAreLeft(map)) { 32 | // ticks++; 33 | // if(ticks % 10 == 0) { 34 | // System.err.println(map); 35 | // } 36 | // BaseObject.GET_SET_DEBUG = true; 37 | Action direction = hero.x == map.getWidth() - 2 ? Action.MOVE_W : Action.MOVE_E; 38 | gameScreen.tryTick(hero, direction, false); 39 | BaseObject.GET_SET_DEBUG = false; 40 | } 41 | } finally { 42 | BaseObject.GET_SET_DEBUG = originalGetSet; 43 | } 44 | // System.out.println("ticks " + ticks); 45 | // LibInspector libInspector = new LibInspector(); 46 | // libInspector.go(new String[] {"IsHostile"}); 47 | // libInspector.go(new String[] {"IsMobile"}); 48 | } 49 | 50 | public void setUp() { 51 | RPG.setRandSeed(0); 52 | Lib.clear(); 53 | hero = Hero.createHero("bob", "human", "fighter"); 54 | TyrantTestCase.setTestHero(hero); 55 | NullHandler.installNullMessageHandler(); 56 | Game.setUserinterface(null); 57 | 58 | String mapString = 59 | "################################" + "\n" + 60 | "#@.............................#" + "\n" + 61 | "################################"; 62 | 63 | map = new MapHelper().createMap(mapString); 64 | for (int x = hero.x; x < map.getWidth(); x++) { 65 | if (!map.isBlocked(x, 1)) map.addThing(Lib.create("[IsMonster]"), x, 1); 66 | } 67 | hero.set("IsImmortal", true); 68 | gameScreen = new GameScreen(new QuestApp()); 69 | gameScreen.map = map; 70 | } 71 | 72 | private boolean monstersAreLeft(mikera.tyrant.engine.Map map) { 73 | for (int i = 0; i < map.getThings().length; i++) { 74 | Thing thing = map.getThings()[i]; 75 | if(thing.getFlag("IsHostile")) return true; 76 | } 77 | return false; 78 | } 79 | 80 | public String getMessage() { 81 | return ""; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/Lib_Perf.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | 5 | public class Lib_Perf extends Perf { 6 | public Lib_Perf() { 7 | //empty 8 | } 9 | 10 | public static void main(String[] args) { 11 | new Lib_Perf().go(args); 12 | } 13 | 14 | public void go(String[] args) { 15 | if(args.length != 2) { 16 | printUsage(); 17 | return; 18 | } 19 | if(args.length == 0) { 20 | args = new String[] {KillAllBaddies.class.getName(), "10"}; 21 | } 22 | IWork work = findWork(args[0]); 23 | int iterations = Integer.parseInt(args[1]); 24 | WorkDone[] workFinished = timeToRun(work, iterations); 25 | oneLineSummary(shortName(work.getClass()), work.getMessage(), workFinished); 26 | } 27 | 28 | private String shortName(Class extends IWork> aClass) { 29 | String name = aClass.getName(); 30 | int lastDot = name.lastIndexOf('.'); 31 | return name.substring(lastDot + 1); 32 | } 33 | 34 | private void printUsage() { 35 | System.out.println("Usage java " + Lib_Perf.class.getName() + " 'name of work' iterations"); 36 | System.out.println("Example: " + Lib_Perf.class.getName() + " " + KillAllBaddies.class.getName() + " 10"); 37 | System.out.println("This will execute KillAllBaddies 10 times."); 38 | } 39 | 40 | private IWork findWork(String className) { 41 | try { 42 | return (IWork) Class.forName(className).getConstructor().newInstance(); 43 | } catch(ClassNotFoundException cnfe) { 44 | Class theClass = KillAllBaddies.class; 45 | System.out.println("Class " + className + " not found, using " + theClass.getName() + " instead."); 46 | try { 47 | return theClass.getConstructor().newInstance(); 48 | } catch (Exception e1) { 49 | e1.printStackTrace(); 50 | } 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | return null; 55 | } 56 | 57 | protected Runnable createLib() { 58 | Runnable work = new Runnable() { 59 | public void run() { 60 | Lib.clear(); 61 | Lib.instance(); 62 | } 63 | }; 64 | return work; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/MoreKilling.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import mikera.engine.BaseObject; 4 | import mikera.tyrant.Action; 5 | import mikera.tyrant.Game; 6 | import mikera.tyrant.GameScreen; 7 | import mikera.tyrant.Hero; 8 | import mikera.tyrant.QuestApp; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.RPG; 12 | import mikera.tyrant.engine.Thing; 13 | import mikera.tyrant.test.MapHelper; 14 | import mikera.tyrant.test.NullHandler; 15 | import mikera.tyrant.test.TyrantTestCase; 16 | 17 | 18 | public class MoreKilling implements IWork { 19 | private Thing hero; 20 | private Map map; 21 | private GameScreen gameScreen; 22 | 23 | public MoreKilling() { 24 | // empty constructor 25 | } 26 | 27 | public void run() { 28 | boolean originalGetSet = BaseObject.GET_SET_DEBUG; 29 | try { 30 | while (hero.x < (map.getWidth() - 2)) { 31 | // BaseObject.GET_SET_DEBUG = true; 32 | gameScreen.tryTick(hero, Action.MOVE_E, false); 33 | // BaseObject.GET_SET_DEBUG = false; 34 | } 35 | } finally { 36 | BaseObject.GET_SET_DEBUG = originalGetSet; 37 | } 38 | } 39 | 40 | public void setUp() { 41 | RPG.setRandSeed(0); 42 | Lib.clear(); 43 | hero = Hero.createHero("bob", "human", "fighter"); 44 | TyrantTestCase.setTestHero(hero); 45 | NullHandler.installNullMessageHandler(); 46 | Game.setUserinterface(null); 47 | 48 | String mapString = 49 | "################################" + "\n" + 50 | "#@.............................#" + "\n" + 51 | "##.............................#" + "\n" + 52 | "#..............................#" + "\n" + 53 | "################################"; 54 | 55 | map = new MapHelper().createMap(mapString); 56 | for (int x = hero.x; x < map.getWidth(); x++) { 57 | if (!map.isBlocked(x, 1)) { 58 | map.addThing(Lib.create("[IsMonster]"), x, 1); 59 | map.addThing(Lib.create("[IsItem]"), x, 1); 60 | map.addThing(Lib.create("menhir"), x, 2); 61 | map.addThing(Lib.create("[IsMonster]"), x, 3); 62 | map.addThing(Lib.create("[IsItem]"), x, 3); 63 | } 64 | } 65 | hero.set("IsImmortal", true); 66 | gameScreen = new GameScreen(new QuestApp()); 67 | gameScreen.map = map; 68 | } 69 | 70 | public String getMessage() { 71 | return ""; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/Perf.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import java.text.NumberFormat; 4 | 5 | import mikera.engine.BaseObject; 6 | import mikera.tyrant.util.PrintfFormat; 7 | 8 | public class Perf { 9 | 10 | public Perf() { 11 | numberFormat = NumberFormat.getNumberInstance(); 12 | numberFormat.setGroupingUsed(false); 13 | } 14 | 15 | protected NumberFormat numberFormat; 16 | 17 | protected void oneLineSummary(String className, String message, WorkDone[] workFinished) { 18 | long sum = 0; 19 | long sumOfSquares = 0; 20 | for (int i = 0; i < workFinished.length; i++) { 21 | WorkDone done = workFinished[i]; 22 | sum += done.elapsed(); 23 | sumOfSquares += done.elapsed() * done.elapsed(); 24 | } 25 | double standardDeviation = Math.sqrt(((float) workFinished.length * sumOfSquares - sum * sum) / (workFinished.length * workFinished.length)); 26 | PrintfFormat printf = new PrintfFormat("%-15s %-15s Runs: %5d Avg: %5.2fms Std: %5.2fms Optimize: %s"); 27 | float average = sum / workFinished.length; 28 | System.out.println(printf.sprintf(new Object[] {className, message, workFinished.length, 29 | average, standardDeviation, Boolean.valueOf(BaseObject.OPTIMIZE)})); 30 | } 31 | 32 | protected WorkDone[] timeToRun(IWork work, int iterations) { 33 | WorkDone[] done = new WorkDone[iterations]; 34 | for (int i = 0; i < done.length; i++) { 35 | work.setUp(); 36 | WorkDone timed = new WorkDone(); 37 | done[i] = timed; 38 | timed.execute(work); 39 | // System.out.println(timed.elapsed() + "ms"); 40 | } 41 | return done; 42 | } 43 | 44 | public class WorkDone { 45 | private long start; 46 | private long end; 47 | private long elapsed = -1; 48 | 49 | public long elapsed() { 50 | if (elapsed == -1) elapsed = end - start; 51 | return elapsed; 52 | } 53 | 54 | void execute(Runnable work) { 55 | start = System.currentTimeMillis(); 56 | try { 57 | work.run(); 58 | } finally { 59 | end = System.currentTimeMillis(); 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/perf/SizeOfLib.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.perf; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.ObjectOutputStream; 5 | 6 | import mikera.tyrant.engine.Lib; 7 | import mikera.tyrant.engine.RPG; 8 | 9 | 10 | public class SizeOfLib implements IWork { 11 | private int size; 12 | 13 | public void run() { 14 | Lib.instance(); 15 | try { 16 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 17 | ObjectOutputStream objectOut = new ObjectOutputStream(out); 18 | objectOut.writeObject(Lib.instance().getAll()); 19 | size = out.size(); 20 | } catch (Exception e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | 25 | public void setUp() { 26 | RPG.setRandSeed(0); 27 | Lib.clear(); 28 | } 29 | 30 | public String getMessage() { 31 | return "" + size + " bytes"; 32 | } 33 | } -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/NullHandler.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import java.awt.Color; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import mikera.tyrant.Game; 8 | import mikera.tyrant.IMessageHandler; 9 | import mikera.tyrant.TPanel; 10 | 11 | 12 | public class NullHandler implements IMessageHandler { 13 | public List messages; 14 | public void clear() { 15 | messages.clear(); 16 | } 17 | 18 | public void add(String s) { 19 | messages.add(s); 20 | } 21 | 22 | public void add(String s, Color c) { 23 | add(s); 24 | } 25 | 26 | public TPanel getPanel() { 27 | return null; 28 | } 29 | 30 | public static List installNullMessageHandler() { 31 | List messages=new ArrayList<>(); 32 | installNullMessageHandler(messages); 33 | return messages; 34 | } 35 | 36 | public static void installNullMessageHandler(List messages) { 37 | NullHandler aMessageHandler = new NullHandler(); 38 | aMessageHandler.messages = messages; 39 | Game.messagepanel = aMessageHandler; 40 | Game.instance().getMessageList().clear(); 41 | } 42 | } -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestAction.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.io.ByteArrayInputStream; 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutputStream; 9 | 10 | import org.junit.Test; 11 | 12 | import mikera.tyrant.Action; 13 | 14 | public class TestAction { 15 | @Test 16 | public void testSerialization() throws Exception { 17 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 18 | ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream); 19 | 20 | out.writeObject(Action.MOVE_N); 21 | out.flush(); 22 | 23 | ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); 24 | ObjectInputStream in = new ObjectInputStream(byteArrayInputStream); 25 | 26 | assertSame(Action.MOVE_N, in.readObject()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestActionMapping.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | import mikera.tyrant.Action; 8 | import mikera.tyrant.ActionMapping; 9 | 10 | 11 | public class TestActionMapping { 12 | 13 | @Test 14 | public void testAction() throws Exception { 15 | ActionMapping map = new ActionMapping(); 16 | map.addDefaultMappings(); 17 | assertEquals(Action.MOVE_N, map.convertKeyToAction('8')); 18 | assertEquals(Action.MOVE_E, map.convertKeyToAction('6')); 19 | assertEquals(Action.MOVE_NOWHERE, map.convertKeyToAction('5')); 20 | assertEquals(Action.WAIT, map.convertKeyToAction('.')); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestAnimal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 05-Jan-2005 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import static org.junit.Assert.assertNull; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Thing; 11 | 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Mike 16 | * 17 | * To change the template for this generated type comment go to 18 | * Window - Preferences - Java - Code Generation - Code and Comments 19 | */ 20 | public class TestAnimal { 21 | 22 | @Test 23 | public void testButterfly() { 24 | Thing t=Lib.create("butterfly"); 25 | 26 | assertNull(t.get("DeathDecoration")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestArtifact.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.Thing; 5 | 6 | public class TestArtifact extends TyrantTestCase { 7 | public void testUniqueCreation() { 8 | Thing a=Lib.create("Yanthrall's Sword"); 9 | Thing b=Lib.create("Yanthrall's Sword"); 10 | assertNotNull(a); 11 | assertEquals(a,b); 12 | 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestBeing.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 06-Jan-2005 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import mikera.tyrant.Being; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.Thing; 12 | 13 | /** 14 | * @author Mike 15 | * 16 | * To change the template for this generated type comment go to 17 | * Window - Preferences - Java - Code Generation - Code and Comments 18 | */ 19 | public class TestBeing extends TyrantTestCase { 20 | public void testItemHandling() { 21 | String mapString = 22 | "####" + "\n" + 23 | "#@.#" + "\n" + 24 | "####"; 25 | Map m=new MapHelper().createMap(mapString); 26 | 27 | Thing h=getTestHero(); 28 | 29 | Thing rock=Lib.create("rock"); 30 | m.addThing(rock,1,1); 31 | 32 | Being.tryPickup(h,rock); 33 | assertSame(rock.place, h); 34 | 35 | Being.tryDrop(h,rock); 36 | assertNotSame(rock.place, h); 37 | assertSame(rock.place, m); 38 | assertEquals(rock.x, h.x); 39 | assertEquals(rock.y, h.y); 40 | 41 | try { 42 | Being.tryDrop(h,rock); 43 | fail("Should throw exception trying to drop Thing not in inventory"); 44 | } catch (Throwable t) { 45 | // OK 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestCoin.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import java.util.StringTokenizer; 4 | 5 | import mikera.tyrant.Coin; 6 | import mikera.tyrant.engine.Lib; 7 | import mikera.tyrant.engine.Thing; 8 | 9 | /** 10 | * @author Chris Grindstaff chris@gstaff.org 11 | */ 12 | 13 | @SuppressWarnings("unused") 14 | public class TestCoin extends TyrantTestCase { 15 | 16 | public void testCreate_cooper() { 17 | Thing coins = Coin.createRoundedMoney(9); 18 | } 19 | 20 | public void testCreate_silver() { 21 | Thing coins = Coin.createRoundedMoney(123); 22 | } 23 | 24 | public void testCreate_gold() { 25 | Thing coins = Coin.createRoundedMoney(9999); 26 | } 27 | 28 | public void testCreate_gold2() { 29 | Thing coins = Coin.createRoundedMoney(999999); 30 | } 31 | 32 | /** 33 | * @see http://sourceforge.net/tracker/index.php?func=detail&aid=994528&group_id=16696&atid=116696 34 | */ 35 | public void testRemove() { 36 | person.addThing(Lib.create("8 gold coin")); 37 | Coin.removeMoney(person, 2); 38 | assertTrue(weightOf("7 gold, 9 silver, 8 copper")<= person.getInventoryWeight()); 39 | assertTrue(Coin.getMoney(person)>=798); 40 | } 41 | 42 | public void testRemove_negative() { 43 | int initialWeight=person.getInventoryWeight(); 44 | Coin.removeMoney(person, -2); 45 | assertEquals(initialWeight+weightOf("2 copper"), person.getInventoryWeight()); 46 | assertEquals(2, Coin.getMoney(person)); 47 | 48 | } 49 | 50 | public void testAdd_negative() { 51 | Thing rabbit=Lib.create("rabbit"); 52 | Coin.addMoney(rabbit, 10); 53 | int wt = rabbit.getInventoryWeight(); 54 | Coin.addMoney(rabbit, -10); 55 | assertTrue(rabbit.getInventoryWeight() < wt); 56 | assertEquals(0, Coin.getMoney(rabbit)); 57 | } 58 | 59 | private int weightOf(String toParse) { 60 | int total = 0; 61 | StringTokenizer tokenizer = new StringTokenizer(toParse, ","); 62 | while (tokenizer.hasMoreTokens()) { 63 | String name = tokenizer.nextToken().trim(); 64 | name += name.endsWith(Coin.SOVEREIGN) ? "" : " coin"; 65 | Thing money = Lib.create(name); 66 | total += money.getWeight(); 67 | } 68 | return total; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestCombat.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.Combat; 4 | import mikera.tyrant.Game; 5 | 6 | 7 | public class TestCombat extends TyrantTestCase { 8 | /* 9 | * See defect http://sourceforge.net/tracker/index.php?func=detail&aid=1059445&group_id=16696&atid=116696 10 | */ 11 | 12 | public void testKick() { 13 | String mapString = 14 | // 0123456789 15 | "----------" + "\n" + 16 | "|..%@~...|" + "\n" + 17 | "|...|....|" + "\n" + 18 | "|........|" + "\n" + 19 | "|........|" + "\n" + 20 | "----------"; 21 | 22 | // hack to ensure we have right actor 23 | Game.actor=hero; 24 | 25 | new MapHelper().createMap(mapString); 26 | 27 | Combat.kick(hero, -1, 1); //thin air 28 | assertEquals("You kick thin air", lastMessage()); 29 | Game.messagepanel.clear(); 30 | 31 | Combat.kick(hero, -1, 0); //food 32 | assertTrue(lastMessage().startsWith("You kick the beefcake")); 33 | Game.messagepanel.clear(); 34 | 35 | Combat.kick(hero, 1, 0); //river 36 | assertEquals("Your attempt to kick the water only succeeds in getting you wet!", lastMessage()); 37 | Game.messagepanel.clear(); 38 | 39 | Combat.kick(hero, 0, 1); //wall 40 | assertEquals("You kick the wall - ouch!", lastMessage()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestDamage.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.Damage; 4 | import mikera.tyrant.Game; 5 | import mikera.tyrant.engine.Lib; 6 | import mikera.tyrant.engine.RPG; 7 | import mikera.tyrant.engine.Thing; 8 | 9 | public class TestDamage extends TyrantTestCase { 10 | public void testInventoryDamage() throws Exception { 11 | Thing rabbit = Lib.create("rabbit"); 12 | Thing carrots = Lib.create("10 carrot"); 13 | Thing parsnips = Lib.create("parsnip"); 14 | rabbit.addThing(carrots); 15 | rabbit.addThing(parsnips); 16 | assertEquals(10, rabbit.inv()[0].getNumber()); 17 | Damage.damageInventory(rabbit, 100000, RPG.DT_DISINTEGRATE, 100); 18 | assertEquals(0, rabbit.invCount()); 19 | } 20 | public void testInventoryDamage_bagProtection() throws Exception { 21 | Game.create(); 22 | 23 | Thing hero = Lib.create("rat"); 24 | Thing carrots = Lib.create("10 carrot"); 25 | Thing scroll = Lib.create("scroll of total identification"); 26 | Thing bagScroll = Lib.create("invulnerable scroll case"); 27 | 28 | int startInventory=hero.invCount(); 29 | hero.addThing(carrots); 30 | hero.addThing(scroll); 31 | hero.addThing(bagScroll); 32 | hero.wield(bagScroll); 33 | assertEquals(startInventory+3, hero.invCount()); 34 | Damage.damageInventory(hero, 100000, RPG.DT_DISINTEGRATE, 100); 35 | assertEquals(startInventory+1, hero.invCount()); 36 | } 37 | public void testInventoryDamage_bagProtectionFire() throws Exception { 38 | Thing hero = Lib.create("rat"); 39 | Thing carrots = Lib.create("10 carrot"); 40 | Thing bagFood = Lib.create("waterproof food sack"); 41 | Thing scroll = Lib.create("scroll of total identification"); 42 | Thing bagScroll = Lib.create("fireproof scroll case"); 43 | 44 | 45 | int startInventory=hero.invCount(); 46 | hero.addThing(carrots); 47 | hero.addThing(scroll); 48 | hero.addThing(bagFood); 49 | hero.addThing(bagScroll); 50 | hero.wield(bagScroll); 51 | hero.wield(bagFood); 52 | assertEquals(startInventory+4, hero.invCount()); 53 | Damage.damageInventory(hero, 900, RPG.DT_FIRE, 100); 54 | assertEquals(startInventory+1, hero.invCount()); 55 | } 56 | public void testInventoryDamage_itemWithSeveral() throws Exception { 57 | Thing rabbit = Lib.create("rabbit"); 58 | Thing carrots = Lib.create("10 carrot"); 59 | Thing parsnips = Lib.create("10 parsnip"); 60 | carrots.set("HPS", 4); 61 | carrots.set("HPSMAX", 4); 62 | parsnips.set("HPS", 2); 63 | parsnips.set("HPSMAX", 2); 64 | rabbit.addThing(carrots); 65 | rabbit.addThing(parsnips); 66 | Damage.damageInventory(rabbit, 8, RPG.DT_DISINTEGRATE, 100); 67 | assertEquals(8, carrots.getNumber()); 68 | assertEquals(6, parsnips.getNumber()); 69 | } 70 | 71 | public void testDestructible() { 72 | // smash a carrot 73 | Thing carrot=Lib.create("carrot"); 74 | assertTrue(0 howHungry); 20 | hero.set(RPG.ST_HUNGER, howHungry); 21 | Food.eat(hero, salmon); 22 | assertEquals(0, hero.getStat(RPG.ST_HUNGER)); 23 | assertEquals(1, hero.getItem("large salmon").getNumber()); 24 | assertEquals(nutritionalValue - howHungry, salmon.getStat("FoodValue")); 25 | } 26 | 27 | public void testEatingSalmon_withEffect() throws Exception { 28 | Thing salmon = Lib.create("large salmon"); 29 | salmon.set("IsBlessed", true); 30 | hero.addThing(salmon); 31 | final Count timesCalled = new Count(); 32 | salmon.addHandler("OnEaten", new EventHandler() { 33 | public boolean handle(Thing t, Event e) { 34 | timesCalled.increment(); 35 | return false; 36 | } 37 | }); 38 | hero.addThing(salmon); 39 | Food.eat(hero, salmon); 40 | assertEquals(1, timesCalled.value); 41 | Food.eat(hero, salmon); 42 | assertEquals(1, timesCalled.value); 43 | } 44 | 45 | public void testEating_andRemoving() throws Exception { 46 | Thing apple = Lib.create("apple"); 47 | hero.addThing(apple); 48 | int howHungry = hero.getStat(RPG.ST_HUNGERTHRESHOLD) * 3; 49 | int nutritionalValue = Food.nutritionValue(apple, hero); 50 | assertTrue(nutritionalValue < howHungry); 51 | hero.set(RPG.ST_HUNGER, howHungry); 52 | Food.eat(hero, apple); 53 | assertEquals(howHungry - nutritionalValue, hero.getStat(RPG.ST_HUNGER)); 54 | assertFalse(hero.hasItem("apple")); 55 | } 56 | 57 | public void testEating_effectCalledOnlyOnce() throws Exception { 58 | Thing apple = Lib.create("apple"); 59 | final Count timesCalled = new Count(); 60 | apple.addHandler("OnEaten", new EventHandler() { 61 | public boolean handle(Thing t, Event e) { 62 | timesCalled.increment(); 63 | return false; 64 | } 65 | }); 66 | hero.addThing(apple); 67 | Food.eat(hero, apple); 68 | assertEquals(1, timesCalled.value); 69 | Food.eat(hero, apple); 70 | assertEquals(1, timesCalled.value); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestGame.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import java.awt.event.KeyEvent; 4 | import java.util.ArrayList; 5 | import java.io.*; 6 | 7 | import mikera.tyrant.*; 8 | import mikera.tyrant.engine.Thing; 9 | 10 | 11 | /** 12 | * @author Chris Grindstaff chris@gstaff.org 13 | */ 14 | public class TestGame extends TyrantTestCase { 15 | private ArrayList theMessages; 16 | 17 | protected void setUp() throws Exception { 18 | super.setUp(); 19 | theMessages = new ArrayList<>(); 20 | NullHandler.installNullMessageHandler(theMessages); 21 | } 22 | 23 | public void testMessage_single() { 24 | Game.message("bob"); 25 | assertEquals(1, theMessages.size()); 26 | assertEquals("Bob\n", theMessages.get(0)); 27 | assertEquals("Bob", Game.instance().getMessageList().get(0)); 28 | } 29 | 30 | public void testSave() { 31 | assertTrue(Game.instance()!=null); 32 | 33 | ByteArrayOutputStream bos=new ByteArrayOutputStream(); 34 | try { 35 | Thing h=Game.hero(); 36 | 37 | assertTrue(Game.save(new ObjectOutputStream(bos))); 38 | 39 | ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray()); 40 | 41 | assertTrue(Game.restore(new ObjectInputStream(bis))); 42 | 43 | assertTrue(Game.hero()!=h); 44 | } catch (IOException t) { 45 | fail("IO Excepion"); 46 | } 47 | 48 | 49 | } 50 | 51 | public void testMessage_multiple() { 52 | Game.message("bob"); 53 | Game.message("bob"); 54 | Game.message("bob"); 55 | assertEquals(3, theMessages.size()); 56 | assertEquals("Bob\n", theMessages.get(0)); 57 | assertEquals("Bob (x3)", Game.instance().getMessageList().get(0)); 58 | } 59 | 60 | public void testCreate() { 61 | Game.create(); 62 | Game.setDebug(true); 63 | assertTrue(Game.isDebug()); 64 | Game.create(); 65 | assertFalse(Game.isDebug()); 66 | } 67 | 68 | public void testRollover() { 69 | for (int i = 0; i < 100; i++) { 70 | Game.message("" + i); 71 | } 72 | assertEquals(100, Game.instance().getMessageList().size()); 73 | assertEquals("0", Game.instance().getMessageList().get(0)); 74 | 75 | Game.message("rollover"); 76 | assertEquals(100, Game.instance().getMessageList().size()); 77 | assertEquals("1", Game.instance().getMessageList().get(0)); 78 | } 79 | 80 | public void testOption() throws Exception { 81 | answerGetInputWithChar('p'); 82 | assertEquals('p', Game.getOption("pr")); 83 | 84 | answerGetInputWith(KeyEvent.VK_ESCAPE); 85 | assertEquals('q', Game.getOption("yn")); 86 | 87 | answerGetInputWith(KeyEvent.VK_ENTER); 88 | assertEquals('e', Game.getOption("yn")); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestHero.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.*; 4 | import mikera.tyrant.engine.Lib; 5 | import mikera.tyrant.engine.RPG; 6 | import mikera.tyrant.engine.Thing; 7 | 8 | public class TestHero extends TyrantTestCase { 9 | public void testIsHero() { 10 | assertEquals(hero, Game.hero()); 11 | assertTrue(hero.isHero()); 12 | } 13 | 14 | public void testExperience() { 15 | Thing hero = Hero.createHero("bob", "human", "fighter"); 16 | assertEquals(1, hero.getLevel()); 17 | assertEquals(0, hero.getStat(RPG.ST_EXP)); 18 | Hero.gainExperience(1000); 19 | assertEquals(8, hero.getLevel()); 20 | } 21 | 22 | public void testKill() { 23 | Thing hero = Hero.createHero("bob", "human", "fighter"); 24 | Thing goblin=Lib.create("goblin"); 25 | 26 | assertTrue(hero.getStat(RPG.ST_EXP)==0); 27 | 28 | assertEquals(0,Hero.getKillCount(Lib.create("goblin"))); 29 | 30 | // kill 1 31 | Hero.gainKillExperience(hero,goblin); 32 | assertEquals(1,Hero.getKillCount(Lib.create("goblin"))); 33 | 34 | // kill 2 35 | Hero.gainKillExperience(hero,goblin); 36 | assertEquals(2,Hero.getKillCount(Lib.create("goblin"))); 37 | 38 | assertTrue(hero.getStat(RPG.ST_EXP)>0); 39 | } 40 | 41 | public void testHeroChoices() { 42 | String[] races=Hero.heroRaces(); 43 | for (int i=0; i map) { 94 | HashMap expected = new HashMap<>(); 95 | String[] splits = toMap.split("="); 96 | for (int i = 0; i < splits.length; i+=2) { 97 | String string = splits[i]; 98 | expected.put(string.trim(), splits[i + 1].trim()); 99 | } 100 | assertEquals(expected, map); 101 | } 102 | 103 | public void testMake() throws Exception { 104 | String mapText = 105 | "---Tiles---\r\n" + 106 | "abcd\r\n" + 107 | "---Tiles---\r\n" + 108 | "\r\n" + 109 | "---Legend---\r\n" + 110 | "a = grass\r\n" + 111 | "b = wall\r\n" + 112 | "c = stone floor\r\n" + 113 | "d = posh floor\r\n" + 114 | "Width = 4\r\n" + 115 | "Height = 1\r\n" + 116 | "EntranceX = 1\r\n" + 117 | "EntranceY = 1\r\n" + 118 | "---Legend---"; 119 | Map map = mapMaker.create(mapText, true); 120 | assertEquals(Tile.GRASS, map.getTile(0, 0)); 121 | assertEquals(Tile.WALL, map.getTile(1, 0)); 122 | assertEquals(Tile.STONEFLOOR, map.getTile(2, 0)); 123 | assertEquals(Tile.POSHFLOOR, map.getTile(3, 0)); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestMonster.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.AI; 4 | import mikera.tyrant.Monster; 5 | import mikera.tyrant.engine.Lib; 6 | import mikera.tyrant.engine.Map; 7 | import mikera.tyrant.engine.RPG; 8 | import mikera.tyrant.engine.Thing; 9 | 10 | 11 | public class TestMonster extends TyrantTestCase { 12 | 13 | public void testTakeTheMoneyAndRun() { 14 | String mapString = 15 | // 01234 16 | "-----" + "\n" + 17 | "|L@.|" + "\n" + 18 | "-----"; 19 | 20 | Map map = new MapHelper().createMap(mapString); 21 | Thing[] money = hero.getFlaggedContents("IsMoney"); 22 | for (int i = 0; i < money.length; i++) { 23 | Thing coin = money[i]; 24 | coin.remove(); 25 | } 26 | assertEquals(0, hero.getFlaggedContents("IsMoney").length); 27 | Thing coins = Lib.create("6 silver coin"); 28 | hero.addThing(coins); 29 | hero.set(RPG.ST_SK, 1); // make it easy for the monster to hit 30 | Thing leprechaun = map.getThings(1, 1)[0]; 31 | assertEquals("leprechaun", leprechaun.getName()); 32 | // Make sure he doesn't start out with any silver 33 | assertNull(leprechaun.getItem(coins.name())); 34 | // Let him bang away until he gets it right. 35 | while ((lastMessage() == null) || 36 | lastMessage().equals("The leprechaun hits you but fails to do any damage") || 37 | lastMessage().equals("The leprechaun misses you")) { 38 | AI.doAction(leprechaun); 39 | } 40 | assertEquals("The leprechaun vanishes in a puff of smoke!", lastMessage()); 41 | // There's only one square to teleport to. 42 | Thing movedMonster = map.getThings(3,1)[0]; 43 | assertEquals(leprechaun, movedMonster); 44 | // Make sure he got some of our silver 45 | assertEquals(coins, movedMonster.getItem(coins.name())); 46 | } 47 | 48 | public void testSpecialHit_teleporting() throws Exception { 49 | String mapString = 50 | "-----" + "\n" + 51 | "|r.##" + "\n" + 52 | "-----"; 53 | Map map = new MapHelper().createMap(mapString); 54 | Thing rabbit = map.getThings(1, 1)[0]; 55 | Monster.SpecialHit specialHit = new Monster.SpecialHit(Monster.TAKE_THE_MONEY_AND_RUN, 100); 56 | assertTrue(specialHit.teleportAway(rabbit)); 57 | assertLocation(rabbit, 2, 1); 58 | } 59 | 60 | public void testStealingMoney() throws Exception { 61 | Monster.SpecialHit specialHit = new Monster.SpecialHit(Monster.TAKE_THE_MONEY_AND_RUN, 100); 62 | person.addThing(Lib.create("6 silver coin")); 63 | Thing bunny = Lib.create("rabbit"); 64 | assertTrue(specialHit.stealSomething(person, bunny, "IsMoney")); 65 | assertEquals(0, person.getFlaggedContents("IsMoney").length); 66 | assertEquals(1, bunny.getFlaggedContents("IsMoney").length); 67 | } 68 | 69 | public void testStealingMagic() throws Exception { 70 | Monster.SpecialHit specialHit = new Monster.SpecialHit(Monster.TAKE_THE_MAGIC_AND_RUN, 100); 71 | person.addThing(Lib.create("[IsScroll]")); 72 | Thing bunny = Lib.create("rabbit"); 73 | assertTrue(specialHit.stealSomething(person, bunny, "IsMagicItem")); 74 | assertEquals(1, bunny.getFlaggedContents("IsMagicItem").length); 75 | } 76 | 77 | public void testStealingMultipleThings() throws Exception { 78 | Monster.SpecialHit specialHit = new Monster.SpecialHit(Monster.TAKE_THE_MAGIC_AND_RUN, 100); 79 | person.addThing(Lib.create("[IsScroll]")); 80 | person.addThing(Lib.create("[IsPotion]")); 81 | Thing bunny = Lib.create("rabbit"); 82 | assertTrue(specialHit.stealSomething(person, bunny, "IsMagicItem",2)); 83 | assertEquals(0, person.getFlaggedContents("IsMagicItem").length); 84 | assertTrue(bunny.getFlaggedContents("IsMagicItem").length >= 2); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestNullHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 18-Dec-2004 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import mikera.tyrant.Game; 9 | 10 | /** 11 | * @author Mike 12 | */ 13 | public class TestNullHandler extends TyrantTestCase { 14 | 15 | public void testMessages() { 16 | Game.instance().clearMessageList(); 17 | 18 | assertEquals(null, lastMessage()); 19 | Game.message("Message One"); 20 | assertEquals("Message One", lastMessage()); 21 | Game.message("Message Two"); 22 | assertEquals("Message Two", lastMessage()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestPortal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 12-Jun-2005 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import mikera.tyrant.*; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.Thing; 12 | 13 | /** 14 | * @author Mike 15 | * 16 | * To change the template for this generated type comment go to 17 | * Window - Preferences - Java - Code Generation - Code and Comments 18 | */ 19 | public class TestPortal extends TyrantTestCase { 20 | public void testTravel() { 21 | Map map = new Map(4, 4); 22 | Thing p=Lib.create("dungeon"); 23 | 24 | map.addThing(p,1,1); 25 | 26 | Thing rock=Lib.create("rock"); 27 | 28 | map.addThing(rock,1,1); 29 | 30 | Map dmap=Portal.getTargetMap(p); 31 | assertNotNull(dmap); 32 | assertTrue(dmap!=map); 33 | 34 | Portal.travel(p,rock); 35 | assertTrue(Portal.getTargetMap(p)==dmap); 36 | assertTrue(rock.getMap()==dmap); 37 | } 38 | 39 | 40 | public void testSetDestination() { 41 | Map map = new Map(4, 4); 42 | Thing p=Lib.create("dungeon"); 43 | map.addThing(p,1,1); 44 | Thing rock=Lib.create("rock"); 45 | Portal.setDestination(p,map,2,3); 46 | 47 | Portal.travel(p,rock); 48 | assertEquals(2,rock.getMapX()); 49 | assertEquals(3,rock.getMapY()); 50 | assertTrue(rock.getMap()==map); 51 | } 52 | 53 | public void testPitTraps() { 54 | for (int i=0; i<100; i++) { 55 | Map map = new Map(4, 4); 56 | Thing pit=Lib.create("pit trap"); 57 | map.addThing(pit,1,1); 58 | 59 | Trap.trigger(pit); 60 | 61 | // check that the pit trap has become a pit 62 | assertEquals("pit",pit.name()); 63 | 64 | Map dmap=Portal.getTargetMap(pit); 65 | int tx=pit.getStat("PortalTargetX"); 66 | int ty=pit.getStat("PortalTargetY"); 67 | 68 | Thing ent=dmap.getEntrance(); 69 | assertNotNull(ent); 70 | assertEquals(ent.getMap(),dmap); 71 | int ex=ent.getMapX(); 72 | int ey=ent.getMapY(); 73 | assertTrue(ex>=0); 74 | assertTrue(ey>=0); 75 | assertTrue(ex=0); 80 | assertTrue(ty>=0); 81 | assertTrue(txst); 50 | } 51 | 52 | public void testPotionOfRepair() { 53 | Thing rock = Lib.create("rock"); 54 | rock.set("HPS",1); 55 | 56 | Thing pot=Lib.create("potion of perfect repair"); 57 | Potion.dip(null,rock,pot); 58 | 59 | assertEquals(rock.getStat("HPSMAX"), rock.getStat("HPS")); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestProperties.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.engine.Lib; 4 | import mikera.tyrant.engine.Thing; 5 | 6 | public class TestProperties extends TyrantTestCase { 7 | public void testPut() throws Exception { 8 | Thing carrot = Lib.create("carrot"); 9 | int originalBaseSize = carrot.getInherited().size(); 10 | 11 | Object valueInCarrot = carrot.get("HPS"); 12 | carrot.set("HPS", valueInCarrot); 13 | assertEquals(originalBaseSize, carrot.getInherited().size()); 14 | } 15 | 16 | public void testDefault() { 17 | Thing thing = new Thing(); 18 | assertEquals(0, thing.getStat("A")); 19 | assertNull(thing.get("B")); 20 | } 21 | 22 | public void testFlattening() { 23 | Thing thing = new Thing(); 24 | thing.set("A",1); 25 | 26 | Thing nt=new Thing(thing); 27 | 28 | assertEquals(1,nt.getStat("A")); 29 | 30 | // change in base object should propagate 31 | thing.set("A",2); 32 | assertEquals(2,nt.getStat("A")); 33 | 34 | nt.flattenProperties(); 35 | 36 | // change in base object should not propagate 37 | // since we have now performed flattening 38 | thing.set("A",3); 39 | assertEquals(2,nt.getStat("A")); 40 | 41 | } 42 | 43 | 44 | public void testSet() { 45 | Thing parent = new Thing(); 46 | 47 | parent.set("A", 1); 48 | assertEquals(1, parent.getStat("A")); 49 | 50 | Thing child = new Thing(parent); 51 | 52 | // change parent while child is still referencing it 53 | assertEquals(1, parent.getStat("A")); 54 | parent.set("A",2); 55 | assertEquals(2, child.getStat("A")); 56 | parent.set("A",1); 57 | assertEquals(1, child.getStat("A")); 58 | 59 | // set q to lower value 60 | parent.set("A",2); 61 | child.set("A",1); 62 | assertEquals(2, parent.getStat("A")); 63 | assertEquals(1, child.getStat("A")); 64 | 65 | // set q to same value as p 66 | child.set("A",2); 67 | assertEquals(2, child.getStat("A")); 68 | 69 | // should now be overriding p 70 | parent.set("A",5); 71 | assertEquals(2, child.getStat("A")); 72 | } 73 | 74 | public void testChain() { 75 | Thing a=new Thing(); 76 | Thing b=new Thing(a); 77 | Thing c=new Thing(b); 78 | 79 | b.set("A",1); 80 | assertEquals(1, c.getStat("A")); 81 | 82 | a.set("A",2); 83 | assertEquals(1, c.getStat("A")); 84 | 85 | // test setting c to parent values 86 | c.set("A",3); 87 | assertEquals(3, c.getStat("A")); 88 | 89 | c.set("A",2); 90 | assertEquals(2, c.getStat("A")); 91 | 92 | c.set("A",1); 93 | assertEquals(1, c.getStat("A")); 94 | 95 | c.set("A",0); 96 | assertEquals(0, c.getStat("A")); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestQuest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 02-Apr-2005 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import mikera.tyrant.*; 9 | import mikera.tyrant.engine.Lib; 10 | import mikera.tyrant.engine.Map; 11 | import mikera.tyrant.engine.RPG; 12 | import mikera.tyrant.engine.Thing; 13 | 14 | /** 15 | * @author Mike 16 | * 17 | * To change the template for this generated type comment go to 18 | * Window - Preferences - Java - Code Generation - Code and Comments 19 | */ 20 | public class TestQuest extends TyrantTestCase { 21 | public void testVisitMap() { 22 | Map map=new Map(1,1); 23 | Thing q=Quest.createVisitMapQuest("Visit the map",map); 24 | 25 | // check set-up 26 | assertNotNull(q.get("TargetMap")); 27 | assertEquals(map,q.get("TargetMap")); 28 | 29 | Thing h=Game.hero(); 30 | Quest.addQuest(h,q); 31 | 32 | map.addThing(h,0,0); 33 | 34 | assertFalse(q.getFlag("IsComplete")); 35 | Time.advance(0); 36 | assertTrue(q.getFlag("IsComplete")); 37 | } 38 | 39 | public void testKillQuest() { 40 | Thing rat=Lib.create("rat"); 41 | Thing q=Quest.createKillQuest("Kill the rat",rat); 42 | 43 | Thing h=Game.hero(); 44 | Quest.addQuest(h,q); 45 | 46 | assertFalse(rat.isDead()); 47 | assertFalse(q.getFlag("IsComplete")); 48 | assertTrue(q.getFlag("IsActive")); 49 | 50 | Damage.inflict(rat,1000,RPG.DT_SPECIAL); 51 | 52 | assertTrue(rat.isDead()); 53 | assertTrue(q.getFlag("IsComplete")); 54 | assertFalse(q.getFlag("IsActive")); 55 | } 56 | 57 | public void testKillNumberQuest() { 58 | Thing q1=Quest.createKillNumberQuest("Kill the goblins","goblin",2); 59 | Thing q2=Quest.createKillNumberQuest("Kill the goblinoids","[IsGoblinoid]",2); 60 | 61 | assertEquals("IsGoblinoid",q2.getString("TargetType")); 62 | assertEquals("goblin",q1.getString("TargetName")); 63 | 64 | Thing h=Game.hero(); 65 | Quest.addQuest(h,q1); 66 | Quest.addQuest(h,q2); 67 | 68 | // kill irrelevant stuff 69 | Being.registerKill(h,Lib.create("rat")); 70 | Being.registerKill(h,Lib.create("field mouse")); 71 | 72 | assertFalse(q1.getFlag("IsComplete")); 73 | assertFalse(q2.getFlag("IsComplete")); 74 | 75 | // kill one goblin 76 | Being.registerKill(h,Lib.create("goblin")); 77 | 78 | assertFalse(q1.getFlag("IsComplete")); 79 | assertFalse(q2.getFlag("IsComplete")); 80 | 81 | // kill a different goblinoid 82 | Being.registerKill(h,Lib.create("orc")); 83 | 84 | assertFalse(q1.getFlag("IsComplete")); 85 | assertTrue(q2.getFlag("IsComplete")); 86 | 87 | // kill a second goblin 88 | Being.registerKill(h,Lib.create("goblin")); 89 | 90 | assertTrue(q1.getFlag("IsComplete")); 91 | assertTrue(q2.getFlag("IsComplete")); 92 | } 93 | 94 | public void testMeetQuest() { 95 | Map map=new Map(3,3); 96 | 97 | Thing rat=Lib.create("rat"); 98 | Thing q=Quest.createMeetQuest("Met the rat",rat); 99 | 100 | Thing h=Game.hero(); 101 | Quest.addQuest(h,q); 102 | 103 | map.addThing(Game.hero(),0,0); 104 | map.addThing(rat,2,2); 105 | 106 | Time.advance(0); 107 | 108 | assertFalse(q.getFlag("IsComplete")); 109 | assertTrue(q.getFlag("IsActive")); 110 | 111 | map.addThing(Game.hero(),1,1); 112 | Time.advance(0); 113 | 114 | assertTrue(q.getFlag("IsComplete")); 115 | assertFalse(q.getFlag("IsActive")); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestScenery.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.Event; 4 | import mikera.tyrant.Scripts; 5 | import mikera.tyrant.engine.Lib; 6 | import mikera.tyrant.engine.Map; 7 | import mikera.tyrant.engine.Thing; 8 | 9 | public class TestScenery extends TyrantTestCase { 10 | 11 | public void testGenerateInPlaceScript() { 12 | String mapString = 13 | // 0123 14 | "----" + "\n" + 15 | "|.@|" + "\n" + 16 | "----"; 17 | final Thing patch = Lib.create("carrot"); 18 | patch.addHandler("OnAction",Scripts.generatorInPlace("raspberry",100)); 19 | Map map = new MapHelper().createMap(mapString); 20 | map.addThing(patch,1,1); 21 | Thing[] things = map.getThings(1,1); 22 | assertEquals(1,things.length); // our carrot 23 | // wait long enough to ensure the time * generation rate >= 1000000 24 | patch.handle(Event.createActionEvent(10000)); 25 | things = map.getThings(1,1); 26 | assertEquals(2,things.length); // a carrot and a raspberry 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestScripts.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.Food; 4 | import mikera.tyrant.engine.Lib; 5 | import mikera.tyrant.engine.Thing; 6 | 7 | public class TestScripts extends TyrantTestCase { 8 | 9 | public void testHealScript() { 10 | final Thing orange1 = Lib.create("orange"); 11 | final Thing orange2 = Lib.create("orange"); 12 | int hps = hero.getStat("HPS"); 13 | hero.incStat("HPS", -1); 14 | assertEquals(hps - 1,hero.getStat("HPS")); 15 | Food.eat(hero,orange1); 16 | assertEquals(hps,hero.getStat("HPS")); 17 | Food.eat(hero,orange2); // don't go past maxhp 18 | assertEquals(hps,hero.getStat("HPS")); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestSpell.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.*; 4 | import mikera.tyrant.engine.Lib; 5 | import mikera.tyrant.engine.Thing; 6 | 7 | public class TestSpell extends TyrantTestCase { 8 | public void testCreate() { 9 | // valid spell 10 | Thing t=Spell.create("Fireball"); 11 | 12 | assertNotNull(t); 13 | 14 | // invlaid spell 15 | try { 16 | t=Spell.create("Not A Valid Spell Name"); 17 | fail("Invalid spell created?!?"); 18 | } catch (Throwable x) { 19 | // 20 | } 21 | } 22 | 23 | public void testAddSpell() { 24 | Thing b=Lib.create("human"); 25 | Thing s=Lib.create("Fireball"); 26 | b.addThing(s); 27 | 28 | assertTrue(Spell.maxCharges(b,s)>0); 29 | assertTrue(Spell.canCast(b,s)); 30 | assertTrue(Spell.castTime(b)==200); 31 | 32 | s.set("Charges",0); 33 | 34 | assertFalse(Spell.canCast(b,s)); 35 | 36 | Spell.rechargeSpells(b,10000); 37 | // assertTrue(Spell.canCast(b,s)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestText.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.util.Text; 4 | 5 | public class TestText extends TyrantTestCase { 6 | 7 | public void testCamelizeString() { 8 | assertEquals("DeanOfAdmissions",Text.camelizeString("dean of admissions")); 9 | assertEquals("Dean",Text.camelizeString("dean")); 10 | assertEquals("123Four",Text.camelizeString("123 four")); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestThingMaker.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import junit.framework.TestCase; 4 | import mikera.tyrant.author.Designer; 5 | import mikera.tyrant.author.ThingMaker; 6 | import mikera.tyrant.engine.Lib; 7 | import mikera.tyrant.engine.Map; 8 | import mikera.tyrant.engine.Thing; 9 | 10 | public class TestThingMaker extends TestCase { 11 | private ThingMaker thingMaker; 12 | private StringBuffer actual; 13 | 14 | protected void setUp() throws Exception { 15 | thingMaker = new ThingMaker(); 16 | actual = new StringBuffer(); 17 | } 18 | 19 | public void testStoring() throws Exception { 20 | Map map = new Map(3, 3); 21 | map.addThing("carrot", 0, 0); 22 | map.addThing("parsnip", 1, 0); 23 | map.addThing("beefcake", 1, 0); 24 | String expected = 25 | "\r\n---Things---\r\n" + 26 | "0x0 carrot\r\n" + 27 | "1x0 beefcake\r\n" + 28 | "1x0 parsnip\r\n" + 29 | "---Things---\r\n" + 30 | ""; 31 | thingMaker.storeThings(map, actual); 32 | assertEquals(expected, actual.toString()); 33 | } 34 | 35 | public void testStoringIs() throws Exception { 36 | Map map = new Map(3, 3); 37 | map.addThing(Designer.getFlagged("IsFood"), 0, 0); 38 | String expected = 39 | "\r\n---Things---\r\n" + 40 | "0x0 [IsFood]\r\n" + 41 | "---Things---\r\n" + 42 | ""; 43 | thingMaker.storeThings(map, actual); 44 | assertEquals(expected, actual.toString()); 45 | } 46 | 47 | public void testThings_modififed() throws Exception { 48 | Map map = new Map(3, 3); 49 | Thing carrot = Lib.create("carrot"); 50 | carrot.set("Number", "6"); 51 | carrot.set("Level", "16"); 52 | map.addThing(carrot, 0, 0); 53 | map.addThing("parsnip", 1, 0); 54 | map.addThing("beefcake", 1, 0); 55 | String expected = 56 | "\r\n---Things---\r\n" + 57 | "0x0 carrot\r\n" + 58 | ThingMaker.SPACES_3 + "Level = 16\r\n" + 59 | ThingMaker.SPACES_3 + "Number = 6\r\n" + 60 | "1x0 beefcake\r\n" + 61 | "1x0 parsnip\r\n" + 62 | "---Things---\r\n"; 63 | thingMaker.storeThings(map, actual); 64 | assertEquals(expected, actual.toString()); 65 | } 66 | 67 | 68 | public void testThings_create() throws Exception { 69 | String mapText = "" + 70 | "---Legend---\r\n" + 71 | "Width = 3 \r\n" + 72 | "Height = 3\r\n" + 73 | "EntranceX = 3 \r\n" + 74 | "EntranceY = 3\r\n" + 75 | "---Legend---\r\n" + 76 | "---Things---\r\n" + 77 | "0x0 carrot\r\n" + 78 | "2x2 carrot\r\n" + 79 | "2x2 parsnip\r\n" + 80 | "---Things---"; 81 | Map map = new Map(3, 3); 82 | thingMaker.addThingsToMap(map, mapText); 83 | assertEquals("carrot", map.getThings(0, 0)[0].name()); 84 | assertEquals("parsnip", map.getThings(2, 2)[0].name()); 85 | assertEquals("carrot", map.getThings(2, 2)[1].name()); 86 | } 87 | 88 | public void testThings_createWithAttributes() throws Exception { 89 | String mapText = "" + 90 | "---Things---\r\n" + 91 | "0x0 carrot\r\n" + 92 | ThingMaker.SPACES_3 + "Level = 16\r\n" + 93 | ThingMaker.SPACES_3 + "Number = 6\r\n" + 94 | "2x2 carrot\r\n" + 95 | "2x2 parsnip\r\n" + 96 | "---Things---"; 97 | Map map = new Map(3, 3); 98 | thingMaker.addThingsToMap(map, mapText); 99 | Thing carrot = map.getThings(0, 0)[0]; 100 | assertEquals("carrot", carrot.name()); 101 | assertEquals(16, carrot.getStat("Level")); 102 | assertEquals(6, carrot.getStat("Number")); 103 | assertEquals("parsnip", map.getThings(2, 2)[0].name()); 104 | assertEquals("carrot", map.getThings(2, 2)[1].name()); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestTown.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import mikera.tyrant.Town; 4 | import mikera.tyrant.engine.Map; 5 | 6 | public class TestTown extends TyrantTestCase { 7 | public void testTownBuilding() throws Exception { 8 | String mapString = 9 | "----------------" + "\n" + 10 | "|..............|" + "\n" + 11 | "|..............|" + "\n" + 12 | "|..............|" + "\n" + 13 | "|..............|" + "\n" + 14 | "|..............|" + "\n" + 15 | "|..............|" + "\n" + 16 | "|..............|" + "\n" + 17 | "|..............|" + "\n" + 18 | "----------------"; 19 | Map map = new MapHelper().createMap(mapString); 20 | Town.addStandardRoom(map, 1, 1, 5, 5, 3, 5); 21 | //TODO Finish this testcase 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TestWorldMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on 04-Jan-2005 3 | * 4 | * By Mike Anderson 5 | */ 6 | package mikera.tyrant.test; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.Iterator; 11 | 12 | import mikera.tyrant.Event; 13 | import mikera.tyrant.Game; 14 | import mikera.tyrant.Portal; 15 | import mikera.tyrant.engine.Lib; 16 | import mikera.tyrant.engine.Map; 17 | import mikera.tyrant.engine.Thing; 18 | 19 | /** 20 | * This test case generates the enitire Tyrant world and then 21 | * recursively tests each map for correctness 22 | * 23 | * @author Mike 24 | * 25 | * To change the template for this generated type comment go to 26 | * Window - Preferences - Java - Code Generation - Code and Comments 27 | */ 28 | public class TestWorldMap extends TyrantTestCase { 29 | private HashMap hm; 30 | private int mapCount; 31 | 32 | public void testWorld() { 33 | hm=new HashMap<>(); 34 | mapCount=0; 35 | 36 | // create things to add to maps 37 | Thing t=Lib.create("carrot"); 38 | Game.instance().addMapObject(t,"dark tower:10"); 39 | Thing t2=Lib.create("invincible portcullis"); 40 | Game.instance().addMapObject(t2,"tutorial inn:1",1,2); 41 | 42 | // Create the world 43 | Map m=Game.instance().createWorld(); 44 | 45 | // test compression 46 | Game.instance().compressAllData(); 47 | 48 | mapTest(m); 49 | 50 | // check that we got all the way to The Tyrant's Lair 51 | Map darktower=Game.instance().getMapStore().get("dark tower:10"); 52 | assertTrue(darktower!=null); 53 | assertEquals(darktower,t.place); 54 | 55 | // check that we got all the way to The Tyrant's Lair 56 | Map inn=Game.instance().getMapStore().get("tutorial inn:1"); 57 | assertTrue(inn!=null); 58 | assertEquals(inn,t2.place); 59 | assertEquals(1,t2.x); 60 | assertEquals(2,t2.y); 61 | } 62 | 63 | /** 64 | * Test all properties of the map 65 | * 66 | * @param m The map to test 67 | */ 68 | private void mapPropertyTest(Map m) { 69 | // test all map properties here 70 | assertTrue(m!=null); 71 | assertTrue("Map ["+m.name()+"] has Level<=0",m.getLevel()>=1); 72 | assertTrue("Map ["+m.name()+"] has Level>50",m.getLevel()<=50); 73 | assertTrue("Map ["+m.name()+"] has no Description!",m.getString("Description")!=null); 74 | } 75 | 76 | /** 77 | * Test all Things on the map 78 | * 79 | * @param m The map to test 80 | */ 81 | private void mapThingTest(Map m) { 82 | 83 | Thing[] ts=m.getThings(); 84 | 85 | assertTrue("Map.getThings() is null!!",ts!=null); 86 | for (int i=0; i1000) { 116 | throw new Error("Too many maps at ["+m.name()+"]"); 117 | } 118 | 119 | hm.put(m.name(),m); 120 | 121 | mapPropertyTest(m); 122 | mapThingTest(m); 123 | mapTimeTest(m); 124 | 125 | ArrayList al=m.getAllPortals(); 126 | 127 | for (Iterator it=al.iterator(); it.hasNext();) { 128 | Thing p=it.next(); 129 | 130 | Map newMap; 131 | 132 | try { 133 | newMap=Portal.getTargetMap(p); 134 | } catch (Throwable t) { 135 | throw new Error("Error creating map for ["+p.name()+"] on ["+m.name()+"]" ,t); 136 | } 137 | 138 | assertTrue("Portal ["+p.name()+"] has null getTargetMap()",newMap!=null); 139 | mapTest(newMap); 140 | 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/test/java/mikera/tyrant/test/TyrantTestCase.java: -------------------------------------------------------------------------------- 1 | package mikera.tyrant.test; 2 | 3 | import java.awt.event.KeyEvent; 4 | import java.util.List; 5 | 6 | import javax.swing.JButton; 7 | 8 | import org.junit.BeforeClass; 9 | 10 | import junit.framework.TestCase; 11 | import mikera.tyrant.Game; 12 | import mikera.tyrant.Hero; 13 | import mikera.tyrant.Interface; 14 | import mikera.tyrant.engine.Lib; 15 | import mikera.tyrant.engine.RPG; 16 | import mikera.tyrant.engine.Thing; 17 | 18 | /** 19 | * The sole purpose of this is to consistently seed the random # generator. 20 | * @author Chris Grindstaff chris@gstaff.org 21 | */ 22 | public class TyrantTestCase extends TestCase { 23 | private class ChainedInterface extends Interface { 24 | private final char aChar; 25 | private Interface next; 26 | private int keyEvent; 27 | 28 | 29 | private ChainedInterface(Interface next, int keyEventConstant) { 30 | this(keyEventConstant, '0'); 31 | this.next = next; 32 | } 33 | 34 | private ChainedInterface(Interface next, char aChar) { 35 | this(KeyEvent.VK_P, aChar); 36 | this.next = next; 37 | } 38 | 39 | private ChainedInterface(int keyEvent, char aChar) { 40 | this.aChar = aChar; 41 | this.keyEvent = keyEvent; 42 | } 43 | 44 | public void getInput() { 45 | keyevent = new KeyEvent(new JButton(), 0, 0, 0, keyEvent, aChar); 46 | if(next != null) next.getInput(); 47 | } 48 | } 49 | 50 | protected Thing person; 51 | protected List messages; 52 | protected static Thing hero; 53 | 54 | /** 55 | * Return the last message 56 | * 57 | * @return 58 | */ 59 | protected String lastMessage() { 60 | int messageCount=messages.size(); 61 | if (messageCount==0) return null; 62 | return messages.get(messageCount-1).trim(); 63 | } 64 | 65 | public static Thing getTestHero() { 66 | return hero; 67 | } 68 | 69 | public static void setTestHero(Thing h) { 70 | hero = h; 71 | Game.instance().setHero(h); 72 | } 73 | 74 | @BeforeClass 75 | protected void setUp() throws Exception { 76 | RPG.setRandSeed(0); 77 | setTestHero(Hero.createHero("bob", "human", "fighter")); 78 | RPG.setRandSeed(0); 79 | messages = NullHandler.installNullMessageHandler(); 80 | Game.setUserinterface(null); 81 | person = Lib.create("human"); 82 | person.removeAllItems(); 83 | } 84 | 85 | 86 | 87 | 88 | public void testNothing() { 89 | /* 90 | * to appease JUnit, otherwise it will create a warning for this class. 91 | * Unfortunately this causes this test to be inherited by all my children. 92 | */ 93 | assertTrue(true); 94 | } 95 | 96 | protected void assertLocation(Thing thing, int expectedX, int expectedY) { 97 | assertEquals(expectedX, thing.getMapX()); 98 | assertEquals(expectedY, thing.getMapY()); 99 | } 100 | 101 | protected void answerGetInputWithChar(final char aChar) { 102 | Interface current = Game.getUserinterface(); 103 | if(current instanceof ChainedInterface) { 104 | Game.setUserinterface(new ChainedInterface(current, aChar)); 105 | } else 106 | Game.setUserinterface(new ChainedInterface(KeyEvent.VK_P, aChar)); 107 | } 108 | 109 | protected void answerGetInputWith(int keyEventConstant) { 110 | Interface current = Game.getUserinterface(); 111 | if(current instanceof ChainedInterface) { 112 | Game.setUserinterface(new ChainedInterface(current, keyEventConstant)); 113 | } else 114 | Game.setUserinterface(new ChainedInterface(keyEventConstant, '0')); 115 | } 116 | } 117 | --------------------------------------------------------------------------------