Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Forgot the source\! Ha\!

  • Loading branch information...
commit 39dd1fe9a2fe02680d8e9b3bb22dc350661e4c2f 1 parent 37aad0a
@Miserlou Miserlou authored
Showing with 5,574 additions and 0 deletions.
  1. BIN  res/bossdeath.wav
  2. BIN  res/craft.wav
  3. BIN  res/death.wav
  4. BIN  res/icons.png
  5. BIN  res/icons2.png
  6. BIN  res/monsterhurt.wav
  7. BIN  res/pickup.wav
  8. BIN  res/playerhurt.wav
  9. BIN  res/test.wav
  10. +354 −0 src/com/mojang/ld22/Game.java
  11. +23 −0 src/com/mojang/ld22/GameApplet.java
  12. +98 −0 src/com/mojang/ld22/InputHandler.java
  13. +69 −0 src/com/mojang/ld22/crafting/Crafting.java
  14. +22 −0 src/com/mojang/ld22/crafting/FurnitureRecipe.java
  15. +60 −0 src/com/mojang/ld22/crafting/Recipe.java
  16. +21 −0 src/com/mojang/ld22/crafting/ResourceRecipe.java
  17. +20 −0 src/com/mojang/ld22/crafting/ToolRecipe.java
  18. +158 −0 src/com/mojang/ld22/entity/AirWizard.java
  19. +20 −0 src/com/mojang/ld22/entity/Anvil.java
  20. +19 −0 src/com/mojang/ld22/entity/Chest.java
  21. +134 −0 src/com/mojang/ld22/entity/Entity.java
  22. +20 −0 src/com/mojang/ld22/entity/Furnace.java
  23. +58 −0 src/com/mojang/ld22/entity/Furniture.java
  24. +69 −0 src/com/mojang/ld22/entity/Inventory.java
  25. +87 −0 src/com/mojang/ld22/entity/ItemEntity.java
  26. +17 −0 src/com/mojang/ld22/entity/Lantern.java
  27. +140 −0 src/com/mojang/ld22/entity/Mob.java
  28. +20 −0 src/com/mojang/ld22/entity/Oven.java
  29. +395 −0 src/com/mojang/ld22/entity/Player.java
  30. +97 −0 src/com/mojang/ld22/entity/Slime.java
  31. +62 −0 src/com/mojang/ld22/entity/Spark.java
  32. +20 −0 src/com/mojang/ld22/entity/Workbench.java
  33. +103 −0 src/com/mojang/ld22/entity/Zombie.java
  34. +11 −0 src/com/mojang/ld22/entity/particle/Particle.java
  35. +31 −0 src/com/mojang/ld22/entity/particle/SmashParticle.java
  36. +53 −0 src/com/mojang/ld22/entity/particle/TextParticle.java
  37. +17 −0 src/com/mojang/ld22/gfx/Color.java
  38. +46 −0 src/com/mojang/ld22/gfx/Font.java
  39. +122 −0 src/com/mojang/ld22/gfx/Screen.java
  40. +16 −0 src/com/mojang/ld22/gfx/Sprite.java
  41. +17 −0 src/com/mojang/ld22/gfx/SpriteSheet.java
  42. +62 −0 src/com/mojang/ld22/item/FurnitureItem.java
  43. +56 −0 src/com/mojang/ld22/item/Item.java
  44. +40 −0 src/com/mojang/ld22/item/PowerGloveItem.java
  45. +64 −0 src/com/mojang/ld22/item/ResourceItem.java
  46. +82 −0 src/com/mojang/ld22/item/ToolItem.java
  47. +17 −0 src/com/mojang/ld22/item/ToolType.java
  48. +24 −0 src/com/mojang/ld22/item/resource/FoodResource.java
  49. +31 −0 src/com/mojang/ld22/item/resource/PlantableResource.java
  50. +47 −0 src/com/mojang/ld22/item/resource/Resource.java
  51. +309 −0 src/com/mojang/ld22/level/Level.java
  52. +437 −0 src/com/mojang/ld22/level/levelgen/LevelGen.java
  53. +55 −0 src/com/mojang/ld22/level/tile/CactusTile.java
  54. +70 −0 src/com/mojang/ld22/level/tile/CloudCactusTile.java
  55. +90 −0 src/com/mojang/ld22/level/tile/CloudTile.java
  56. +49 −0 src/com/mojang/ld22/level/tile/DirtTile.java
  57. +48 −0 src/com/mojang/ld22/level/tile/FarmTile.java
  58. +57 −0 src/com/mojang/ld22/level/tile/FlowerTile.java
  59. +94 −0 src/com/mojang/ld22/level/tile/GrassTile.java
  60. +113 −0 src/com/mojang/ld22/level/tile/HardRockTile.java
  61. +55 −0 src/com/mojang/ld22/level/tile/HoleTile.java
  62. +23 −0 src/com/mojang/ld22/level/tile/InfiniteFallTile.java
  63. +76 −0 src/com/mojang/ld22/level/tile/LavaTile.java
  64. +78 −0 src/com/mojang/ld22/level/tile/OreTile.java
  65. +113 −0 src/com/mojang/ld22/level/tile/RockTile.java
  66. +84 −0 src/com/mojang/ld22/level/tile/SandTile.java
  67. +40 −0 src/com/mojang/ld22/level/tile/SaplingTile.java
  68. +24 −0 src/com/mojang/ld22/level/tile/StairsTile.java
  69. +27 −0 src/com/mojang/ld22/level/tile/StoneTile.java
  70. +89 −0 src/com/mojang/ld22/level/tile/Tile.java
  71. +110 −0 src/com/mojang/ld22/level/tile/TreeTile.java
  72. +72 −0 src/com/mojang/ld22/level/tile/WaterTile.java
  73. +90 −0 src/com/mojang/ld22/level/tile/WheatTile.java
  74. +32 −0 src/com/mojang/ld22/screen/AboutMenu.java
  75. +67 −0 src/com/mojang/ld22/screen/ContainerMenu.java
  76. +98 −0 src/com/mojang/ld22/screen/CraftingMenu.java
  77. +43 −0 src/com/mojang/ld22/screen/DeadMenu.java
  78. +36 −0 src/com/mojang/ld22/screen/InstructionsMenu.java
  79. +43 −0 src/com/mojang/ld22/screen/InventoryMenu.java
  80. +32 −0 src/com/mojang/ld22/screen/LevelTransitionMenu.java
  81. +7 −0 src/com/mojang/ld22/screen/ListItem.java
  82. +51 −0 src/com/mojang/ld22/screen/Menu.java
  83. +61 −0 src/com/mojang/ld22/screen/TitleMenu.java
  84. +43 −0 src/com/mojang/ld22/screen/WonMenu.java
  85. +36 −0 src/com/mojang/ld22/sound/Sound.java
View
BIN  res/bossdeath.wav
Binary file not shown
View
BIN  res/craft.wav
Binary file not shown
View
BIN  res/death.wav
Binary file not shown
View
BIN  res/icons.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  res/icons2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  res/monsterhurt.wav
Binary file not shown
View
BIN  res/pickup.wav
Binary file not shown
View
BIN  res/playerhurt.wav
Binary file not shown
View
BIN  res/test.wav
Binary file not shown
View
354 src/com/mojang/ld22/Game.java
@@ -0,0 +1,354 @@
+package com.mojang.ld22;
+
+import java.awt.BorderLayout;
+import java.awt.Canvas;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.io.IOException;
+import java.util.Random;
+
+import javax.imageio.ImageIO;
+import javax.swing.JFrame;
+
+import com.mojang.ld22.entity.Player;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Font;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.gfx.SpriteSheet;
+import com.mojang.ld22.level.Level;
+import com.mojang.ld22.level.tile.Tile;
+import com.mojang.ld22.screen.DeadMenu;
+import com.mojang.ld22.screen.LevelTransitionMenu;
+import com.mojang.ld22.screen.Menu;
+import com.mojang.ld22.screen.TitleMenu;
+import com.mojang.ld22.screen.WonMenu;
+
+public class Game extends Canvas implements Runnable {
+ private static final long serialVersionUID = 1L;
+ private Random random = new Random();
+ public static final String NAME = "Minicraft";
+ public static final int HEIGHT = 120;
+ public static final int WIDTH = 160;
+ private static final int SCALE = 3;
+
+ private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
+ private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
+ private boolean running = false;
+ private Screen screen;
+ private Screen lightScreen;
+ private InputHandler input = new InputHandler(this);
+
+ private int[] colors = new int[256];
+ private int tickCount = 0;
+ public int gameTime = 0;
+
+ private Level level;
+ private Level[] levels = new Level[5];
+ private int currentLevel = 3;
+ public Player player;
+
+ public Menu menu;
+ private int playerDeadTime;
+ private int pendingLevelChange;
+ private int wonTimer = 0;
+ public boolean hasWon = false;
+
+ public void setMenu(Menu menu) {
+ this.menu = menu;
+ if (menu != null) menu.init(this, input);
+ }
+
+ public void start() {
+ running = true;
+ new Thread(this).start();
+ }
+
+ public void stop() {
+ running = false;
+ }
+
+ public void resetGame() {
+ playerDeadTime = 0;
+ wonTimer = 0;
+ gameTime = 0;
+ hasWon = false;
+
+ levels = new Level[5];
+ currentLevel = 3;
+
+ levels[4] = new Level(128, 128, 1, null);
+ levels[3] = new Level(128, 128, 0, levels[4]);
+ levels[2] = new Level(128, 128, -1, levels[3]);
+ levels[1] = new Level(128, 128, -2, levels[2]);
+ levels[0] = new Level(128, 128, -3, levels[1]);
+
+ level = levels[currentLevel];
+ player = new Player(this, input);
+ player.findStartPos(level);
+
+ level.add(player);
+
+ for (int i = 0; i < 5; i++) {
+ levels[i].trySpawn(5000);
+ }
+ }
+
+ private void init() {
+ int pp = 0;
+ for (int r = 0; r < 6; r++) {
+ for (int g = 0; g < 6; g++) {
+ for (int b = 0; b < 6; b++) {
+ int rr = (r * 255 / 5);
+ int gg = (g * 255 / 5);
+ int bb = (b * 255 / 5);
+ int mid = (rr * 30 + gg * 59 + bb * 11) / 100;
+
+ int r1 = ((rr + mid * 1) / 2) * 230 / 255 + 10;
+ int g1 = ((gg + mid * 1) / 2) * 230 / 255 + 10;
+ int b1 = ((bb + mid * 1) / 2) * 230 / 255 + 10;
+ colors[pp++] = r1 << 16 | g1 << 8 | b1;
+
+ }
+ }
+ }
+ try {
+ screen = new Screen(WIDTH, HEIGHT, new SpriteSheet(ImageIO.read(Game.class.getResourceAsStream("/icons.png"))));
+ lightScreen = new Screen(WIDTH, HEIGHT, new SpriteSheet(ImageIO.read(Game.class.getResourceAsStream("/icons.png"))));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ resetGame();
+ setMenu(new TitleMenu());
+ }
+
+ public void run() {
+ long lastTime = System.nanoTime();
+ double unprocessed = 0;
+ double nsPerTick = 1000000000.0 / 60;
+ int frames = 0;
+ int ticks = 0;
+ long lastTimer1 = System.currentTimeMillis();
+
+ init();
+
+ while (running) {
+ long now = System.nanoTime();
+ unprocessed += (now - lastTime) / nsPerTick;
+ lastTime = now;
+ boolean shouldRender = true;
+ while (unprocessed >= 1) {
+ ticks++;
+ tick();
+ unprocessed -= 1;
+ shouldRender = true;
+ }
+
+ try {
+ Thread.sleep(2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ if (shouldRender) {
+ frames++;
+ render();
+ }
+
+ if (System.currentTimeMillis() - lastTimer1 > 1000) {
+ lastTimer1 += 1000;
+ System.out.println(ticks + " ticks, " + frames + " fps");
+ frames = 0;
+ ticks = 0;
+ }
+ }
+ }
+
+ public void tick() {
+ tickCount++;
+ if (!hasFocus()) {
+ input.releaseAll();
+ } else {
+ if (!player.removed && !hasWon) gameTime++;
+
+ input.tick();
+ if (menu != null) {
+ menu.tick();
+ } else {
+ if (player.removed) {
+ playerDeadTime++;
+ if (playerDeadTime > 60) {
+ setMenu(new DeadMenu());
+ }
+ } else {
+ if (pendingLevelChange != 0) {
+ setMenu(new LevelTransitionMenu(pendingLevelChange));
+ pendingLevelChange = 0;
+ }
+ }
+ if (wonTimer > 0) {
+ if (--wonTimer == 0) {
+ setMenu(new WonMenu());
+ }
+ }
+ level.tick();
+ Tile.tickCount++;
+ }
+ }
+ }
+
+ public void changeLevel(int dir) {
+ level.remove(player);
+ currentLevel += dir;
+ level = levels[currentLevel];
+ player.x = (player.x >> 4) * 16 + 8;
+ player.y = (player.y >> 4) * 16 + 8;
+ level.add(player);
+
+ }
+
+ public void render() {
+ BufferStrategy bs = getBufferStrategy();
+ if (bs == null) {
+ createBufferStrategy(3);
+ requestFocus();
+ return;
+ }
+
+ int xScroll = player.x - screen.w / 2;
+ int yScroll = player.y - (screen.h - 8) / 2;
+ if (xScroll < 16) xScroll = 16;
+ if (yScroll < 16) yScroll = 16;
+ if (xScroll > level.w * 16 - screen.w - 16) xScroll = level.w * 16 - screen.w - 16;
+ if (yScroll > level.h * 16 - screen.h - 16) yScroll = level.h * 16 - screen.h - 16;
+ if (currentLevel > 3) {
+ int col = Color.get(20, 20, 121, 121);
+ for (int y = 0; y < 14; y++)
+ for (int x = 0; x < 24; x++) {
+ screen.render(x * 8 - ((xScroll / 4) & 7), y * 8 - ((yScroll / 4) & 7), 0, col, 0);
+ }
+ }
+
+ level.renderBackground(screen, xScroll, yScroll);
+ level.renderSprites(screen, xScroll, yScroll);
+
+ if (currentLevel < 3) {
+ lightScreen.clear(0);
+ level.renderLight(lightScreen, xScroll, yScroll);
+ screen.overlay(lightScreen, xScroll, yScroll);
+ }
+
+ renderGui();
+
+ if (!hasFocus()) renderFocusNagger();
+
+ for (int y = 0; y < screen.h; y++) {
+ for (int x = 0; x < screen.w; x++) {
+ int cc = screen.pixels[x + y * screen.w];
+ if (cc < 255) pixels[x + y * WIDTH] = colors[cc];
+ }
+ }
+
+ Graphics g = bs.getDrawGraphics();
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ int ww = WIDTH * 3;
+ int hh = HEIGHT * 3;
+ int xo = (getWidth() - ww) / 2;
+ int yo = (getHeight() - hh) / 2;
+ g.drawImage(image, xo, yo, ww, hh, null);
+ g.dispose();
+ bs.show();
+ }
+
+ private void renderGui() {
+ for (int y = 0; y < 2; y++) {
+ for (int x = 0; x < 20; x++) {
+ screen.render(x * 8, screen.h - 16 + y * 8, 0 + 12 * 32, Color.get(000, 000, 000, 000), 0);
+ }
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if (i < player.health)
+ screen.render(i * 8, screen.h - 16, 0 + 12 * 32, Color.get(000, 200, 500, 533), 0);
+ else
+ screen.render(i * 8, screen.h - 16, 0 + 12 * 32, Color.get(000, 100, 000, 000), 0);
+
+ if (player.staminaRechargeDelay > 0) {
+ if (player.staminaRechargeDelay / 4 % 2 == 0)
+ screen.render(i * 8, screen.h - 8, 1 + 12 * 32, Color.get(000, 555, 000, 000), 0);
+ else
+ screen.render(i * 8, screen.h - 8, 1 + 12 * 32, Color.get(000, 110, 000, 000), 0);
+ } else {
+ if (i < player.stamina)
+ screen.render(i * 8, screen.h - 8, 1 + 12 * 32, Color.get(000, 220, 550, 553), 0);
+ else
+ screen.render(i * 8, screen.h - 8, 1 + 12 * 32, Color.get(000, 110, 000, 000), 0);
+ }
+ }
+ if (player.activeItem != null) {
+ player.activeItem.renderInventory(screen, 10 * 8, screen.h - 16);
+ }
+
+ if (menu != null) {
+ menu.render(screen);
+ }
+ }
+
+ private void renderFocusNagger() {
+ String msg = "Click to focus!";
+ int xx = (WIDTH - msg.length() * 8) / 2;
+ int yy = (HEIGHT - 8) / 2;
+ int w = msg.length();
+ int h = 1;
+
+ screen.render(xx - 8, yy - 8, 0 + 13 * 32, Color.get(-1, 1, 5, 445), 0);
+ screen.render(xx + w * 8, yy - 8, 0 + 13 * 32, Color.get(-1, 1, 5, 445), 1);
+ screen.render(xx - 8, yy + 8, 0 + 13 * 32, Color.get(-1, 1, 5, 445), 2);
+ screen.render(xx + w * 8, yy + 8, 0 + 13 * 32, Color.get(-1, 1, 5, 445), 3);
+ for (int x = 0; x < w; x++) {
+ screen.render(xx + x * 8, yy - 8, 1 + 13 * 32, Color.get(-1, 1, 5, 445), 0);
+ screen.render(xx + x * 8, yy + 8, 1 + 13 * 32, Color.get(-1, 1, 5, 445), 2);
+ }
+ for (int y = 0; y < h; y++) {
+ screen.render(xx - 8, yy + y * 8, 2 + 13 * 32, Color.get(-1, 1, 5, 445), 0);
+ screen.render(xx + w * 8, yy + y * 8, 2 + 13 * 32, Color.get(-1, 1, 5, 445), 1);
+ }
+
+ if ((tickCount / 20) % 2 == 0) {
+ Font.draw(msg, screen, xx, yy, Color.get(5, 333, 333, 333));
+ } else {
+ Font.draw(msg, screen, xx, yy, Color.get(5, 555, 555, 555));
+ }
+ }
+
+ public void scheduleLevelChange(int dir) {
+ pendingLevelChange = dir;
+ }
+
+ public static void main(String[] args) {
+ Game game = new Game();
+ game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
+ game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
+ game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
+
+ JFrame frame = new JFrame(Game.NAME);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setLayout(new BorderLayout());
+ frame.add(game, BorderLayout.CENTER);
+ frame.pack();
+ frame.setResizable(false);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ game.start();
+ }
+
+ public void won() {
+ wonTimer = 60 * 3;
+ hasWon = true;
+ }
+}
View
23 src/com/mojang/ld22/GameApplet.java
@@ -0,0 +1,23 @@
+package com.mojang.ld22;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+
+public class GameApplet extends Applet {
+ private static final long serialVersionUID = 1L;
+
+ private Game game = new Game();
+
+ public void init() {
+ setLayout(new BorderLayout());
+ add(game, BorderLayout.CENTER);
+ }
+
+ public void start() {
+ game.start();
+ }
+
+ public void stop() {
+ game.stop();
+ }
+}
View
98 src/com/mojang/ld22/InputHandler.java
@@ -0,0 +1,98 @@
+package com.mojang.ld22;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.ArrayList;
+import java.util.List;
+
+public class InputHandler implements KeyListener {
+ public class Key {
+ public int presses, absorbs;
+ public boolean down, clicked;
+
+ public Key() {
+ keys.add(this);
+ }
+
+ public void toggle(boolean pressed) {
+ if (pressed != down) {
+ down = pressed;
+ }
+ if (pressed) {
+ presses++;
+ }
+ }
+
+ public void tick() {
+ if (absorbs < presses) {
+ absorbs++;
+ clicked = true;
+ } else {
+ clicked = false;
+ }
+ }
+ }
+
+ public List<Key> keys = new ArrayList<Key>();
+
+ public Key up = new Key();
+ public Key down = new Key();
+ public Key left = new Key();
+ public Key right = new Key();
+ public Key attack = new Key();
+ public Key menu = new Key();
+
+ public void releaseAll() {
+ for (int i = 0; i < keys.size(); i++) {
+ keys.get(i).down = false;
+ }
+ }
+
+ public void tick() {
+ for (int i = 0; i < keys.size(); i++) {
+ keys.get(i).tick();
+ }
+ }
+
+ public InputHandler(Game game) {
+ game.addKeyListener(this);
+ }
+
+ public void keyPressed(KeyEvent ke) {
+ toggle(ke, true);
+ }
+
+ public void keyReleased(KeyEvent ke) {
+ toggle(ke, false);
+ }
+
+ private void toggle(KeyEvent ke, boolean pressed) {
+ if (ke.getKeyCode() == KeyEvent.VK_NUMPAD8) up.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_NUMPAD2) down.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_NUMPAD4) left.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_NUMPAD6) right.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_W) up.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_S) down.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_A) left.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_D) right.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_UP) up.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_DOWN) down.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_LEFT) left.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_RIGHT) right.toggle(pressed);
+
+ if (ke.getKeyCode() == KeyEvent.VK_TAB) menu.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_ALT) menu.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_ALT_GRAPH) menu.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_SPACE) attack.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_CONTROL) attack.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_NUMPAD0) attack.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_INSERT) attack.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_ENTER) menu.toggle(pressed);
+
+ if (ke.getKeyCode() == KeyEvent.VK_X) menu.toggle(pressed);
+ if (ke.getKeyCode() == KeyEvent.VK_C) attack.toggle(pressed);
+ }
+
+ public void keyTyped(KeyEvent ke) {
+ }
+}
View
69 src/com/mojang/ld22/crafting/Crafting.java
@@ -0,0 +1,69 @@
+package com.mojang.ld22.crafting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mojang.ld22.entity.Anvil;
+import com.mojang.ld22.entity.Chest;
+import com.mojang.ld22.entity.Furnace;
+import com.mojang.ld22.entity.Oven;
+import com.mojang.ld22.entity.Lantern;
+import com.mojang.ld22.entity.Workbench;
+import com.mojang.ld22.item.ToolType;
+import com.mojang.ld22.item.resource.Resource;
+
+public class Crafting {
+ public static final List<Recipe> anvilRecipes = new ArrayList<Recipe>();
+ public static final List<Recipe> ovenRecipes = new ArrayList<Recipe>();
+ public static final List<Recipe> furnaceRecipes = new ArrayList<Recipe>();
+ public static final List<Recipe> workbenchRecipes = new ArrayList<Recipe>();
+
+ static {
+ try {
+ workbenchRecipes.add(new FurnitureRecipe(Lantern.class).addCost(Resource.wood, 5).addCost(Resource.slime, 10).addCost(Resource.glass, 4));
+
+ workbenchRecipes.add(new FurnitureRecipe(Oven.class).addCost(Resource.stone, 15));
+ workbenchRecipes.add(new FurnitureRecipe(Furnace.class).addCost(Resource.stone, 20));
+ workbenchRecipes.add(new FurnitureRecipe(Workbench.class).addCost(Resource.wood, 20));
+ workbenchRecipes.add(new FurnitureRecipe(Chest.class).addCost(Resource.wood, 20));
+ workbenchRecipes.add(new FurnitureRecipe(Anvil.class).addCost(Resource.ironIngot, 5));
+
+ workbenchRecipes.add(new ToolRecipe(ToolType.sword, 0).addCost(Resource.wood, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.axe, 0).addCost(Resource.wood, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.hoe, 0).addCost(Resource.wood, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.pickaxe, 0).addCost(Resource.wood, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.shovel, 0).addCost(Resource.wood, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.sword, 1).addCost(Resource.wood, 5).addCost(Resource.stone, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.axe, 1).addCost(Resource.wood, 5).addCost(Resource.stone, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.hoe, 1).addCost(Resource.wood, 5).addCost(Resource.stone, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.pickaxe, 1).addCost(Resource.wood, 5).addCost(Resource.stone, 5));
+ workbenchRecipes.add(new ToolRecipe(ToolType.shovel, 1).addCost(Resource.wood, 5).addCost(Resource.stone, 5));
+
+ anvilRecipes.add(new ToolRecipe(ToolType.sword, 2).addCost(Resource.wood, 5).addCost(Resource.ironIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.axe, 2).addCost(Resource.wood, 5).addCost(Resource.ironIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.hoe, 2).addCost(Resource.wood, 5).addCost(Resource.ironIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.pickaxe, 2).addCost(Resource.wood, 5).addCost(Resource.ironIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.shovel, 2).addCost(Resource.wood, 5).addCost(Resource.ironIngot, 5));
+
+ anvilRecipes.add(new ToolRecipe(ToolType.sword, 3).addCost(Resource.wood, 5).addCost(Resource.goldIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.axe, 3).addCost(Resource.wood, 5).addCost(Resource.goldIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.hoe, 3).addCost(Resource.wood, 5).addCost(Resource.goldIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.pickaxe, 3).addCost(Resource.wood, 5).addCost(Resource.goldIngot, 5));
+ anvilRecipes.add(new ToolRecipe(ToolType.shovel, 3).addCost(Resource.wood, 5).addCost(Resource.goldIngot, 5));
+
+ anvilRecipes.add(new ToolRecipe(ToolType.sword, 4).addCost(Resource.wood, 5).addCost(Resource.gem, 50));
+ anvilRecipes.add(new ToolRecipe(ToolType.axe, 4).addCost(Resource.wood, 5).addCost(Resource.gem, 50));
+ anvilRecipes.add(new ToolRecipe(ToolType.hoe, 4).addCost(Resource.wood, 5).addCost(Resource.gem, 50));
+ anvilRecipes.add(new ToolRecipe(ToolType.pickaxe, 4).addCost(Resource.wood, 5).addCost(Resource.gem, 50));
+ anvilRecipes.add(new ToolRecipe(ToolType.shovel, 4).addCost(Resource.wood, 5).addCost(Resource.gem, 50));
+
+ furnaceRecipes.add(new ResourceRecipe(Resource.ironIngot).addCost(Resource.ironOre, 4).addCost(Resource.coal, 1));
+ furnaceRecipes.add(new ResourceRecipe(Resource.goldIngot).addCost(Resource.goldOre, 4).addCost(Resource.coal, 1));
+ furnaceRecipes.add(new ResourceRecipe(Resource.glass).addCost(Resource.sand, 4).addCost(Resource.coal, 1));
+
+ ovenRecipes.add(new ResourceRecipe(Resource.bread).addCost(Resource.wheat, 4));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
View
22 src/com/mojang/ld22/crafting/FurnitureRecipe.java
@@ -0,0 +1,22 @@
+package com.mojang.ld22.crafting;
+
+import com.mojang.ld22.entity.Furniture;
+import com.mojang.ld22.entity.Player;
+import com.mojang.ld22.item.FurnitureItem;
+
+public class FurnitureRecipe extends Recipe {
+ private Class<? extends Furniture> clazz;
+
+ public FurnitureRecipe(Class<? extends Furniture> clazz) throws InstantiationException, IllegalAccessException {
+ super(new FurnitureItem(clazz.newInstance()));
+ this.clazz = clazz;
+ }
+
+ public void craft(Player player) {
+ try {
+ player.inventory.add(0, new FurnitureItem(clazz.newInstance()));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
View
60 src/com/mojang/ld22/crafting/Recipe.java
@@ -0,0 +1,60 @@
+package com.mojang.ld22.crafting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mojang.ld22.entity.Player;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Font;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.Item;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+import com.mojang.ld22.screen.ListItem;
+
+public abstract class Recipe implements ListItem {
+ public List<Item> costs = new ArrayList<Item>();
+ public boolean canCraft = false;
+ public Item resultTemplate;
+
+ public Recipe(Item resultTemplate) {
+ this.resultTemplate = resultTemplate;
+ }
+
+ public Recipe addCost(Resource resource, int count) {
+ costs.add(new ResourceItem(resource, count));
+ return this;
+ }
+
+ public void checkCanCraft(Player player) {
+ for (int i = 0; i < costs.size(); i++) {
+ Item item = costs.get(i);
+ if (item instanceof ResourceItem) {
+ ResourceItem ri = (ResourceItem) item;
+ if (!player.inventory.hasResources(ri.resource, ri.count)) {
+ canCraft = false;
+ return;
+ }
+ }
+ }
+ canCraft = true;
+ }
+
+ public void renderInventory(Screen screen, int x, int y) {
+ screen.render(x, y, resultTemplate.getSprite(), resultTemplate.getColor(), 0);
+ int textColor = canCraft ? Color.get(-1, 555, 555, 555) : Color.get(-1, 222, 222, 222);
+ Font.draw(resultTemplate.getName(), screen, x + 8, y, textColor);
+ }
+
+ public abstract void craft(Player player);
+
+ public void deductCost(Player player) {
+ for (int i = 0; i < costs.size(); i++) {
+ Item item = costs.get(i);
+ if (item instanceof ResourceItem) {
+ ResourceItem ri = (ResourceItem) item;
+ player.inventory.removeResource(ri.resource, ri.count);
+ }
+ }
+ }
+}
View
21 src/com/mojang/ld22/crafting/ResourceRecipe.java
@@ -0,0 +1,21 @@
+package com.mojang.ld22.crafting;
+
+import com.mojang.ld22.entity.Player;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Font;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+
+public class ResourceRecipe extends Recipe {
+ private Resource resource;
+
+ public ResourceRecipe(Resource resource) {
+ super(new ResourceItem(resource, 1));
+ this.resource = resource;
+ }
+
+ public void craft(Player player) {
+ player.inventory.add(0, new ResourceItem(resource, 1));
+ }
+}
View
20 src/com/mojang/ld22/crafting/ToolRecipe.java
@@ -0,0 +1,20 @@
+package com.mojang.ld22.crafting;
+
+import com.mojang.ld22.entity.Player;
+import com.mojang.ld22.item.ToolItem;
+import com.mojang.ld22.item.ToolType;
+
+public class ToolRecipe extends Recipe {
+ private ToolType type;
+ private int level;
+
+ public ToolRecipe(ToolType type, int level) {
+ super(new ToolItem(type, level));
+ this.type = type;
+ this.level = level;
+ }
+
+ public void craft(Player player) {
+ player.inventory.add(0, new ToolItem(type, level));
+ }
+}
View
158 src/com/mojang/ld22/entity/AirWizard.java
@@ -0,0 +1,158 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+import com.mojang.ld22.sound.Sound;
+
+public class AirWizard extends Mob {
+ private int xa, ya;
+ private int randomWalkTime = 0;
+ private int attackDelay = 0;
+ private int attackTime = 0;
+ private int attackType = 0;
+
+ public AirWizard() {
+ x = random.nextInt(64 * 16);
+ y = random.nextInt(64 * 16);
+ health = maxHealth = 2000;
+ }
+
+ public void tick() {
+ super.tick();
+
+ if (attackDelay > 0) {
+ dir = (attackDelay - 45) / 4 % 4;
+ dir = (dir * 2 % 4) + (dir / 2);
+ if (attackDelay < 45) {
+ dir = 0;
+ }
+ attackDelay--;
+ if (attackDelay == 0) {
+ attackType = 0;
+ if (health < 1000) attackType = 1;
+ if (health < 200) attackType = 2;
+ attackTime = 60 * 2;
+ }
+ return;
+ }
+
+ if (attackTime > 0) {
+ attackTime--;
+ double dir = attackTime * 0.25 * (attackTime % 2 * 2 - 1);
+ double speed = (0.7) + attackType * 0.2;
+ level.add(new Spark(this, Math.cos(dir) * speed, Math.sin(dir) * speed));
+ return;
+ }
+
+ if (level.player != null && randomWalkTime == 0) {
+ int xd = level.player.x - x;
+ int yd = level.player.y - y;
+ if (xd * xd + yd * yd < 32 * 32) {
+ xa = 0;
+ ya = 0;
+ if (xd < 0) xa = +1;
+ if (xd > 0) xa = -1;
+ if (yd < 0) ya = +1;
+ if (yd > 0) ya = -1;
+ } else if (xd * xd + yd * yd > 80 * 80) {
+ xa = 0;
+ ya = 0;
+ if (xd < 0) xa = -1;
+ if (xd > 0) xa = +1;
+ if (yd < 0) ya = -1;
+ if (yd > 0) ya = +1;
+ }
+ }
+
+ int speed = (tickTime % 4) == 0 ? 0 : 1;
+ if (!move(xa * speed, ya * speed) || random.nextInt(100) == 0) {
+ randomWalkTime = 30;
+ xa = (random.nextInt(3) - 1);
+ ya = (random.nextInt(3) - 1);
+ }
+ if (randomWalkTime > 0) {
+ randomWalkTime--;
+ if (level.player != null && randomWalkTime == 0) {
+ int xd = level.player.x - x;
+ int yd = level.player.y - y;
+ if (random.nextInt(4) == 0 && xd * xd + yd * yd < 50 * 50) {
+ if (attackDelay == 0 && attackTime == 0) {
+ attackDelay = 60 * 2;
+ }
+ }
+ }
+ }
+ }
+
+ protected void doHurt(int damage, int attackDir) {
+ super.doHurt(damage, attackDir);
+ if (attackDelay == 0 && attackTime == 0) {
+ attackDelay = 60 * 2;
+ }
+ }
+
+ public void render(Screen screen) {
+ int xt = 8;
+ int yt = 14;
+
+ int flip1 = (walkDist >> 3) & 1;
+ int flip2 = (walkDist >> 3) & 1;
+
+ if (dir == 1) {
+ xt += 2;
+ }
+ if (dir > 1) {
+
+ flip1 = 0;
+ flip2 = ((walkDist >> 4) & 1);
+ if (dir == 2) {
+ flip1 = 1;
+ }
+ xt += 4 + ((walkDist >> 3) & 1) * 2;
+ }
+
+ int xo = x - 8;
+ int yo = y - 11;
+
+ int col1 = Color.get(-1, 100, 500, 555);
+ int col2 = Color.get(-1, 100, 500, 532);
+ if (health < 200) {
+ if (tickTime / 3 % 2 == 0) {
+ col1 = Color.get(-1, 500, 100, 555);
+ col2 = Color.get(-1, 500, 100, 532);
+ }
+ } else if (health < 1000) {
+ if (tickTime / 5 % 4 == 0) {
+ col1 = Color.get(-1, 500, 100, 555);
+ col2 = Color.get(-1, 500, 100, 532);
+ }
+ }
+ if (hurtTime > 0) {
+ col1 = Color.get(-1, 555, 555, 555);
+ col2 = Color.get(-1, 555, 555, 555);
+ }
+
+ screen.render(xo + 8 * flip1, yo + 0, xt + yt * 32, col1, flip1);
+ screen.render(xo + 8 - 8 * flip1, yo + 0, xt + 1 + yt * 32, col1, flip1);
+ screen.render(xo + 8 * flip2, yo + 8, xt + (yt + 1) * 32, col2, flip2);
+ screen.render(xo + 8 - 8 * flip2, yo + 8, xt + 1 + (yt + 1) * 32, col2, flip2);
+ }
+
+ protected void touchedBy(Entity entity) {
+ if (entity instanceof Player) {
+ entity.hurt(this, 3, dir);
+ }
+ }
+
+ protected void die() {
+ super.die();
+ if (level.player != null) {
+ level.player.score += 1000;
+ level.player.gameWon();
+ }
+ Sound.bossdeath.play();
+ }
+
+}
View
20 src/com/mojang/ld22/entity/Anvil.java
@@ -0,0 +1,20 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.crafting.Crafting;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.screen.CraftingMenu;
+
+public class Anvil extends Furniture {
+ public Anvil() {
+ super("Anvil");
+ col = Color.get(-1, 000, 111, 222);
+ sprite = 0;
+ xr = 3;
+ yr = 2;
+ }
+
+ public boolean use(Player player, int attackDir) {
+ player.game.setMenu(new CraftingMenu(Crafting.anvilRecipes, player));
+ return true;
+ }
+}
View
19 src/com/mojang/ld22/entity/Chest.java
@@ -0,0 +1,19 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.screen.ContainerMenu;
+
+public class Chest extends Furniture {
+ public Inventory inventory = new Inventory();
+
+ public Chest() {
+ super("Chest");
+ col = Color.get(-1, 110, 331, 552);
+ sprite = 1;
+ }
+
+ public boolean use(Player player, int attackDir) {
+ player.game.setMenu(new ContainerMenu(player, "Chest", inventory));
+ return true;
+ }
+}
View
134 src/com/mojang/ld22/entity/Entity.java
@@ -0,0 +1,134 @@
+package com.mojang.ld22.entity;
+
+import java.util.List;
+import java.util.Random;
+
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.Item;
+import com.mojang.ld22.level.Level;
+import com.mojang.ld22.level.tile.Tile;
+
+public class Entity {
+ protected final Random random = new Random();
+ public int x, y;
+ public int xr = 6;
+ public int yr = 6;
+ public boolean removed;
+ public Level level;
+
+ public void render(Screen screen) {
+ }
+
+ public void tick() {
+ }
+
+ public void remove() {
+ removed = true;
+ }
+
+ public final void init(Level level) {
+ this.level = level;
+ }
+
+ public boolean intersects(int x0, int y0, int x1, int y1) {
+ return !(x + xr < x0 || y + yr < y0 || x - xr > x1 || y - yr > y1);
+ }
+
+ public boolean blocks(Entity e) {
+ return false;
+ }
+
+ public void hurt(Mob mob, int dmg, int attackDir) {
+ }
+
+ public void hurt(Tile tile, int x, int y, int dmg) {
+ }
+
+ public boolean move(int xa, int ya) {
+ if (xa != 0 || ya != 0) {
+ boolean stopped = true;
+ if (xa != 0 && move2(xa, 0)) stopped = false;
+ if (ya != 0 && move2(0, ya)) stopped = false;
+ if (!stopped) {
+ int xt = x >> 4;
+ int yt = y >> 4;
+ level.getTile(xt, yt).steppedOn(level, xt, yt, this);
+ }
+ return !stopped;
+ }
+ return true;
+ }
+
+ protected boolean move2(int xa, int ya) {
+ if (xa != 0 && ya != 0) throw new IllegalArgumentException("Move2 can only move along one axis at a time!");
+
+ int xto0 = ((x) - xr) >> 4;
+ int yto0 = ((y) - yr) >> 4;
+ int xto1 = ((x) + xr) >> 4;
+ int yto1 = ((y) + yr) >> 4;
+
+ int xt0 = ((x + xa) - xr) >> 4;
+ int yt0 = ((y + ya) - yr) >> 4;
+ int xt1 = ((x + xa) + xr) >> 4;
+ int yt1 = ((y + ya) + yr) >> 4;
+ boolean blocked = false;
+ for (int yt = yt0; yt <= yt1; yt++)
+ for (int xt = xt0; xt <= xt1; xt++) {
+ if (xt >= xto0 && xt <= xto1 && yt >= yto0 && yt <= yto1) continue;
+ level.getTile(xt, yt).bumpedInto(level, xt, yt, this);
+ if (!level.getTile(xt, yt).mayPass(level, xt, yt, this)) {
+ blocked = true;
+ return false;
+ }
+ }
+ if (blocked) return false;
+
+ List<Entity> wasInside = level.getEntities(x - xr, y - yr, x + xr, y + yr);
+ List<Entity> isInside = level.getEntities(x + xa - xr, y + ya - yr, x + xa + xr, y + ya + yr);
+ for (int i = 0; i < isInside.size(); i++) {
+ Entity e = isInside.get(i);
+ if (e == this) continue;
+
+ e.touchedBy(this);
+ }
+ isInside.removeAll(wasInside);
+ for (int i = 0; i < isInside.size(); i++) {
+ Entity e = isInside.get(i);
+ if (e == this) continue;
+
+ if (e.blocks(this)) {
+ return false;
+ }
+ }
+
+ x += xa;
+ y += ya;
+ return true;
+ }
+
+ protected void touchedBy(Entity entity) {
+ }
+
+ public boolean isBlockableBy(Mob mob) {
+ return true;
+ }
+
+ public void touchItem(ItemEntity itemEntity) {
+ }
+
+ public boolean canSwim() {
+ return false;
+ }
+
+ public boolean interact(Player player, Item item, int attackDir) {
+ return item.interact(player, this, attackDir);
+ }
+
+ public boolean use(Player player, int attackDir) {
+ return false;
+ }
+
+ public int getLightRadius() {
+ return 0;
+ }
+}
View
20 src/com/mojang/ld22/entity/Furnace.java
@@ -0,0 +1,20 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.crafting.Crafting;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.screen.CraftingMenu;
+
+public class Furnace extends Furniture {
+ public Furnace() {
+ super("Furnace");
+ col = Color.get(-1, 000, 222, 333);
+ sprite = 3;
+ xr = 3;
+ yr = 2;
+ }
+
+ public boolean use(Player player, int attackDir) {
+ player.game.setMenu(new CraftingMenu(Crafting.furnaceRecipes, player));
+ return true;
+ }
+}
View
58 src/com/mojang/ld22/entity/Furniture.java
@@ -0,0 +1,58 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.FurnitureItem;
+import com.mojang.ld22.item.PowerGloveItem;
+
+public class Furniture extends Entity {
+ private int pushTime = 0;
+ private int pushDir = -1;
+ public int col, sprite;
+ public String name;
+ private Player shouldTake;
+
+ public Furniture(String name) {
+ this.name = name;
+ xr = 3;
+ yr = 3;
+ }
+
+ public void tick() {
+ if (shouldTake != null) {
+ if (shouldTake.activeItem instanceof PowerGloveItem) {
+ remove();
+ shouldTake.inventory.add(0, shouldTake.activeItem);
+ shouldTake.activeItem = new FurnitureItem(this);
+ }
+ shouldTake = null;
+ }
+ if (pushDir == 0) move(0, +1);
+ if (pushDir == 1) move(0, -1);
+ if (pushDir == 2) move(-1, 0);
+ if (pushDir == 3) move(+1, 0);
+ pushDir = -1;
+ if (pushTime > 0) pushTime--;
+ }
+
+ public void render(Screen screen) {
+ screen.render(x - 8, y - 8 - 4, sprite * 2 + 8 * 32, col, 0);
+ screen.render(x - 0, y - 8 - 4, sprite * 2 + 8 * 32 + 1, col, 0);
+ screen.render(x - 8, y - 0 - 4, sprite * 2 + 8 * 32 + 32, col, 0);
+ screen.render(x - 0, y - 0 - 4, sprite * 2 + 8 * 32 + 33, col, 0);
+ }
+
+ public boolean blocks(Entity e) {
+ return true;
+ }
+
+ protected void touchedBy(Entity entity) {
+ if (entity instanceof Player && pushTime == 0) {
+ pushDir = ((Player) entity).dir;
+ pushTime = 10;
+ }
+ }
+
+ public void take(Player player) {
+ shouldTake = player;
+ }
+}
View
69 src/com/mojang/ld22/entity/Inventory.java
@@ -0,0 +1,69 @@
+package com.mojang.ld22.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mojang.ld22.item.Item;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+
+public class Inventory {
+ public List<Item> items = new ArrayList<Item>();
+
+ public void add(Item item) {
+ add(items.size(), item);
+ }
+
+ public void add(int slot, Item item) {
+ if (item instanceof ResourceItem) {
+ ResourceItem toTake = (ResourceItem) item;
+ ResourceItem has = findResource(toTake.resource);
+ if (has == null) {
+ items.add(slot, toTake);
+ } else {
+ has.count += toTake.count;
+ }
+ } else {
+ items.add(slot, item);
+ }
+ }
+
+ private ResourceItem findResource(Resource resource) {
+ for (int i = 0; i < items.size(); i++) {
+ if (items.get(i) instanceof ResourceItem) {
+ ResourceItem has = (ResourceItem) items.get(i);
+ if (has.resource == resource) return has;
+ }
+ }
+ return null;
+ }
+
+ public boolean hasResources(Resource r, int count) {
+ ResourceItem ri = findResource(r);
+ if (ri == null) return false;
+ return ri.count >= count;
+ }
+
+ public boolean removeResource(Resource r, int count) {
+ ResourceItem ri = findResource(r);
+ if (ri == null) return false;
+ if (ri.count < count) return false;
+ ri.count -= count;
+ if (ri.count <= 0) items.remove(ri);
+ return true;
+ }
+
+ public int count(Item item) {
+ if (item instanceof ResourceItem) {
+ ResourceItem ri = findResource(((ResourceItem)item).resource);
+ if (ri!=null) return ri.count;
+ } else {
+ int count = 0;
+ for (int i=0; i<items.size(); i++) {
+ if (items.get(i).matches(item)) count++;
+ }
+ return count;
+ }
+ return 0;
+ }
+}
View
87 src/com/mojang/ld22/entity/ItemEntity.java
@@ -0,0 +1,87 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.Item;
+import com.mojang.ld22.sound.Sound;
+
+public class ItemEntity extends Entity {
+ private int lifeTime;
+ protected int walkDist = 0;
+ protected int dir = 0;
+ public int hurtTime = 0;
+ protected int xKnockback, yKnockback;
+ public double xa, ya, za;
+ public double xx, yy, zz;
+ public Item item;
+ private int time = 0;
+
+ public ItemEntity(Item item, int x, int y) {
+ this.item = item;
+ xx = this.x = x;
+ yy = this.y = y;
+ xr = 3;
+ yr = 3;
+
+ zz = 2;
+ xa = random.nextGaussian() * 0.3;
+ ya = random.nextGaussian() * 0.2;
+ za = random.nextFloat() * 0.7 + 1;
+
+ lifeTime = 60 * 10 + random.nextInt(60);
+ }
+
+ public void tick() {
+ time++;
+ if (time >= lifeTime) {
+ remove();
+ return;
+ }
+ xx += xa;
+ yy += ya;
+ zz += za;
+ if (zz < 0) {
+ zz = 0;
+ za *= -0.5;
+ xa *= 0.6;
+ ya *= 0.6;
+ }
+ za -= 0.15;
+ int ox = x;
+ int oy = y;
+ int nx = (int) xx;
+ int ny = (int) yy;
+ int expectedx = nx - x;
+ int expectedy = ny - y;
+ move(nx - x, ny - y);
+ int gotx = x - ox;
+ int goty = y - oy;
+ xx += gotx - expectedx;
+ yy += goty - expectedy;
+
+ if (hurtTime > 0) hurtTime--;
+ }
+
+ public boolean isBlockableBy(Mob mob) {
+ return false;
+ }
+
+ public void render(Screen screen) {
+ if (time >= lifeTime - 6 * 20) {
+ if (time / 6 % 2 == 0) return;
+ }
+ screen.render(x - 4, y - 4, item.getSprite(), Color.get(-1, 0, 0, 0), 0);
+ screen.render(x - 4, y - 4 - (int) (zz), item.getSprite(), item.getColor(), 0);
+ }
+
+ protected void touchedBy(Entity entity) {
+ if (time > 30) entity.touchItem(this);
+ }
+
+ public void take(Player player) {
+ Sound.pickup.play();
+ player.score++;
+ item.onTake(this);
+ remove();
+ }
+}
View
17 src/com/mojang/ld22/entity/Lantern.java
@@ -0,0 +1,17 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+
+public class Lantern extends Furniture {
+ public Lantern() {
+ super("Lantern");
+ col = Color.get(-1, 000, 111, 555);
+ sprite = 5;
+ xr = 3;
+ yr = 2;
+ }
+
+ public int getLightRadius() {
+ return 8;
+ }
+}
View
140 src/com/mojang/ld22/entity/Mob.java
@@ -0,0 +1,140 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.entity.particle.TextParticle;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.level.Level;
+import com.mojang.ld22.level.tile.Tile;
+import com.mojang.ld22.sound.Sound;
+
+public class Mob extends Entity {
+ protected int walkDist = 0;
+ protected int dir = 0;
+ public int hurtTime = 0;
+ protected int xKnockback, yKnockback;
+ public int maxHealth = 10;
+ public int health = maxHealth;
+ public int swimTimer = 0;
+ public int tickTime = 0;
+
+ public Mob() {
+ x = y = 8;
+ xr = 4;
+ yr = 3;
+ }
+
+ public void tick() {
+ tickTime++;
+ if (level.getTile(x >> 4, y >> 4) == Tile.lava) {
+ hurt(this, 4, dir ^ 1);
+ }
+
+ if (health <= 0) {
+ die();
+ }
+ if (hurtTime > 0) hurtTime--;
+ }
+
+ protected void die() {
+ remove();
+ }
+
+ public boolean move(int xa, int ya) {
+ if (isSwimming()) {
+ if (swimTimer++ % 2 == 0) return true;
+ }
+ if (xKnockback < 0) {
+ move2(-1, 0);
+ xKnockback++;
+ }
+ if (xKnockback > 0) {
+ move2(1, 0);
+ xKnockback--;
+ }
+ if (yKnockback < 0) {
+ move2(0, -1);
+ yKnockback++;
+ }
+ if (yKnockback > 0) {
+ move2(0, 1);
+ yKnockback--;
+ }
+ if (hurtTime > 0) return true;
+ if (xa != 0 || ya != 0) {
+ walkDist++;
+ if (xa < 0) dir = 2;
+ if (xa > 0) dir = 3;
+ if (ya < 0) dir = 1;
+ if (ya > 0) dir = 0;
+ }
+ return super.move(xa, ya);
+ }
+
+ protected boolean isSwimming() {
+ Tile tile = level.getTile(x >> 4, y >> 4);
+ return tile == Tile.water || tile == Tile.lava;
+ }
+
+ public boolean blocks(Entity e) {
+ return e.isBlockableBy(this);
+ }
+
+ public void hurt(Tile tile, int x, int y, int damage) {
+ int attackDir = dir ^ 1;
+ doHurt(damage, attackDir);
+ }
+
+ public void hurt(Mob mob, int damage, int attackDir) {
+ doHurt(damage, attackDir);
+ }
+
+ public void heal(int heal) {
+ if (hurtTime > 0) return;
+
+ level.add(new TextParticle("" + heal, x, y, Color.get(-1, 50, 50, 50)));
+ health += heal;
+ if (health > maxHealth) health = maxHealth;
+ }
+
+ protected void doHurt(int damage, int attackDir) {
+ if (hurtTime > 0) return;
+
+ if (level.player != null) {
+ int xd = level.player.x - x;
+ int yd = level.player.y - y;
+ if (xd * xd + yd * yd < 80 * 80) {
+ Sound.monsterHurt.play();
+ }
+ }
+ level.add(new TextParticle("" + damage, x, y, Color.get(-1, 500, 500, 500)));
+ health -= damage;
+ if (attackDir == 0) yKnockback = +6;
+ if (attackDir == 1) yKnockback = -6;
+ if (attackDir == 2) xKnockback = -6;
+ if (attackDir == 3) xKnockback = +6;
+ hurtTime = 10;
+ }
+
+ public boolean findStartPos(Level level) {
+ int x = random.nextInt(level.w);
+ int y = random.nextInt(level.h);
+ int xx = x * 16 + 8;
+ int yy = y * 16 + 8;
+
+ if (level.player != null) {
+ int xd = level.player.x - xx;
+ int yd = level.player.y - yy;
+ if (xd * xd + yd * yd < 80 * 80) return false;
+ }
+
+ int r = level.monsterDensity * 16;
+ if (level.getEntities(xx - r, yy - r, xx + r, yy + r).size() > 0) return false;
+
+ if (level.getTile(x, y).mayPass(level, x, y, this)) {
+ this.x = xx;
+ this.y = yy;
+ return true;
+ }
+
+ return false;
+ }
+}
View
20 src/com/mojang/ld22/entity/Oven.java
@@ -0,0 +1,20 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.crafting.Crafting;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.screen.CraftingMenu;
+
+public class Oven extends Furniture {
+ public Oven() {
+ super("Oven");
+ col = Color.get(-1, 000, 332, 442);
+ sprite = 2;
+ xr = 3;
+ yr = 2;
+ }
+
+ public boolean use(Player player, int attackDir) {
+ player.game.setMenu(new CraftingMenu(Crafting.ovenRecipes, player));
+ return true;
+ }
+}
View
395 src/com/mojang/ld22/entity/Player.java
@@ -0,0 +1,395 @@
+package com.mojang.ld22.entity;
+
+import java.util.List;
+
+import com.mojang.ld22.Game;
+import com.mojang.ld22.InputHandler;
+import com.mojang.ld22.entity.particle.TextParticle;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.FurnitureItem;
+import com.mojang.ld22.item.Item;
+import com.mojang.ld22.item.PowerGloveItem;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.ToolItem;
+import com.mojang.ld22.item.ToolType;
+import com.mojang.ld22.item.resource.Resource;
+import com.mojang.ld22.level.Level;
+import com.mojang.ld22.level.tile.Tile;
+import com.mojang.ld22.screen.InventoryMenu;
+import com.mojang.ld22.sound.Sound;
+
+public class Player extends Mob {
+ private InputHandler input;
+ private int attackTime, attackDir;
+
+ public Game game;
+ public Inventory inventory = new Inventory();
+ public Item attackItem;
+ public Item activeItem;
+ public int stamina;
+ public int staminaRecharge;
+ public int staminaRechargeDelay;
+ public int score;
+ public int maxStamina = 10;
+ private int onStairDelay;
+ public int invulnerableTime = 0;
+
+ public Player(Game game, InputHandler input) {
+ this.game = game;
+ this.input = input;
+ x = 24;
+ y = 24;
+ stamina = maxStamina;
+
+ inventory.add(new FurnitureItem(new Workbench()));
+ inventory.add(new PowerGloveItem());
+ }
+
+ public void tick() {
+ super.tick();
+
+ if (invulnerableTime > 0) invulnerableTime--;
+ Tile onTile = level.getTile(x >> 4, y >> 4);
+ if (onTile == Tile.stairsDown || onTile == Tile.stairsUp) {
+ if (onStairDelay == 0) {
+ changeLevel((onTile == Tile.stairsUp) ? 1 : -1);
+ onStairDelay = 10;
+ return;
+ }
+ onStairDelay = 10;
+ } else {
+ if (onStairDelay > 0) onStairDelay--;
+ }
+
+ if (stamina <= 0 && staminaRechargeDelay == 0 && staminaRecharge == 0) {
+ staminaRechargeDelay = 40;
+ }
+
+ if (staminaRechargeDelay > 0) {
+ staminaRechargeDelay--;
+ }
+
+ if (staminaRechargeDelay == 0) {
+ staminaRecharge++;
+ if (isSwimming()) {
+ staminaRecharge = 0;
+ }
+ while (staminaRecharge > 10) {
+ staminaRecharge -= 10;
+ if (stamina < maxStamina) stamina++;
+ }
+ }
+
+ int xa = 0;
+ int ya = 0;
+ if (input.up.down) ya--;
+ if (input.down.down) ya++;
+ if (input.left.down) xa--;
+ if (input.right.down) xa++;
+ if (isSwimming() && tickTime % 60 == 0) {
+ if (stamina > 0) {
+ stamina--;
+ } else {
+ hurt(this, 1, dir ^ 1);
+ }
+ }
+
+ if (staminaRechargeDelay % 2 == 0) {
+ move(xa, ya);
+ }
+
+ if (input.attack.clicked) {
+ if (stamina == 0) {
+
+ } else {
+ stamina--;
+ staminaRecharge = 0;
+ attack();
+ }
+ }
+ if (input.menu.clicked) {
+ if (!use()) {
+ game.setMenu(new InventoryMenu(this));
+ }
+ }
+ if (attackTime > 0) attackTime--;
+
+ }
+
+ private boolean use() {
+ int yo = -2;
+ if (dir == 0 && use(x - 8, y + 4 + yo, x + 8, y + 12 + yo)) return true;
+ if (dir == 1 && use(x - 8, y - 12 + yo, x + 8, y - 4 + yo)) return true;
+ if (dir == 3 && use(x + 4, y - 8 + yo, x + 12, y + 8 + yo)) return true;
+ if (dir == 2 && use(x - 12, y - 8 + yo, x - 4, y + 8 + yo)) return true;
+
+ int xt = x >> 4;
+ int yt = (y + yo) >> 4;
+ int r = 12;
+ if (attackDir == 0) yt = (y + r + yo) >> 4;
+ if (attackDir == 1) yt = (y - r + yo) >> 4;
+ if (attackDir == 2) xt = (x - r) >> 4;
+ if (attackDir == 3) xt = (x + r) >> 4;
+
+ if (xt >= 0 && yt >= 0 && xt < level.w && yt < level.h) {
+ if (level.getTile(xt, yt).use(level, xt, yt, this, attackDir)) return true;
+ }
+
+ return false;
+ }
+
+ private void attack() {
+ walkDist += 8;
+ attackDir = dir;
+ attackItem = activeItem;
+ boolean done = false;
+
+ if (activeItem != null) {
+ attackTime = 10;
+ int yo = -2;
+ int range = 12;
+ if (dir == 0 && interact(x - 8, y + 4 + yo, x + 8, y + range + yo)) done = true;
+ if (dir == 1 && interact(x - 8, y - range + yo, x + 8, y - 4 + yo)) done = true;
+ if (dir == 3 && interact(x + 4, y - 8 + yo, x + range, y + 8 + yo)) done = true;
+ if (dir == 2 && interact(x - range, y - 8 + yo, x - 4, y + 8 + yo)) done = true;
+ if (done) return;
+
+ int xt = x >> 4;
+ int yt = (y + yo) >> 4;
+ int r = 12;
+ if (attackDir == 0) yt = (y + r + yo) >> 4;
+ if (attackDir == 1) yt = (y - r + yo) >> 4;
+ if (attackDir == 2) xt = (x - r) >> 4;
+ if (attackDir == 3) xt = (x + r) >> 4;
+
+ if (xt >= 0 && yt >= 0 && xt < level.w && yt < level.h) {
+ if (activeItem.interactOn(level.getTile(xt, yt), level, xt, yt, this, attackDir)) {
+ done = true;
+ } else {
+ if (level.getTile(xt, yt).interact(level, xt, yt, this, activeItem, attackDir)) {
+ done = true;
+ }
+ }
+ if (activeItem.isDepleted()) {
+ activeItem = null;
+ }
+ }
+ }
+
+ if (done) return;
+
+ if (activeItem == null || activeItem.canAttack()) {
+ attackTime = 5;
+ int yo = -2;
+ int range = 20;
+ if (dir == 0) hurt(x - 8, y + 4 + yo, x + 8, y + range + yo);
+ if (dir == 1) hurt(x - 8, y - range + yo, x + 8, y - 4 + yo);
+ if (dir == 3) hurt(x + 4, y - 8 + yo, x + range, y + 8 + yo);
+ if (dir == 2) hurt(x - range, y - 8 + yo, x - 4, y + 8 + yo);
+
+ int xt = x >> 4;
+ int yt = (y + yo) >> 4;
+ int r = 12;
+ if (attackDir == 0) yt = (y + r + yo) >> 4;
+ if (attackDir == 1) yt = (y - r + yo) >> 4;
+ if (attackDir == 2) xt = (x - r) >> 4;
+ if (attackDir == 3) xt = (x + r) >> 4;
+
+ if (xt >= 0 && yt >= 0 && xt < level.w && yt < level.h) {
+ level.getTile(xt, yt).hurt(level, xt, yt, this, random.nextInt(3) + 1, attackDir);
+ }
+ }
+
+ }
+
+ private boolean use(int x0, int y0, int x1, int y1) {
+ List<Entity> entities = level.getEntities(x0, y0, x1, y1);
+ for (int i = 0; i < entities.size(); i++) {
+ Entity e = entities.get(i);
+ if (e != this) if (e.use(this, attackDir)) return true;
+ }
+ return false;
+ }
+
+ private boolean interact(int x0, int y0, int x1, int y1) {
+ List<Entity> entities = level.getEntities(x0, y0, x1, y1);
+ for (int i = 0; i < entities.size(); i++) {
+ Entity e = entities.get(i);
+ if (e != this) if (e.interact(this, activeItem, attackDir)) return true;
+ }
+ return false;
+ }
+
+ private void hurt(int x0, int y0, int x1, int y1) {
+ List<Entity> entities = level.getEntities(x0, y0, x1, y1);
+ for (int i = 0; i < entities.size(); i++) {
+ Entity e = entities.get(i);
+ if (e != this) e.hurt(this, getAttackDamage(e), attackDir);
+ }
+ }
+
+ private int getAttackDamage(Entity e) {
+ int dmg = random.nextInt(3) + 1;
+ if (attackItem != null) {
+ dmg += attackItem.getAttackDamageBonus(e);
+ }
+ return dmg;
+ }
+
+ public void render(Screen screen) {
+ int xt = 0;
+ int yt = 14;
+
+ int flip1 = (walkDist >> 3) & 1;
+ int flip2 = (walkDist >> 3) & 1;
+
+ if (dir == 1) {
+ xt += 2;
+ }
+ if (dir > 1) {
+ flip1 = 0;
+ flip2 = ((walkDist >> 4) & 1);
+ if (dir == 2) {
+ flip1 = 1;
+ }
+ xt += 4 + ((walkDist >> 3) & 1) * 2;
+ }
+
+ int xo = x - 8;
+ int yo = y - 11;
+ if (isSwimming()) {
+ yo += 4;
+ int waterColor = Color.get(-1, -1, 115, 335);
+ if (tickTime / 8 % 2 == 0) {
+ waterColor = Color.get(-1, 335, 5, 115);
+ }
+ screen.render(xo + 0, yo + 3, 5 + 13 * 32, waterColor, 0);
+ screen.render(xo + 8, yo + 3, 5 + 13 * 32, waterColor, 1);
+ }
+
+ if (attackTime > 0 && attackDir == 1) {
+ screen.render(xo + 0, yo - 4, 6 + 13 * 32, Color.get(-1, 555, 555, 555), 0);
+ screen.render(xo + 8, yo - 4, 6 + 13 * 32, Color.get(-1, 555, 555, 555), 1);
+ if (attackItem != null) {
+ attackItem.renderIcon(screen, xo + 4, yo - 4);
+ }
+ }
+ int col = Color.get(-1, 100, 220, 532);
+ if (hurtTime > 0) {
+ col = Color.get(-1, 555, 555, 555);
+ }
+
+ if (activeItem instanceof FurnitureItem) {
+ yt += 2;
+ }
+ screen.render(xo + 8 * flip1, yo + 0, xt + yt * 32, col, flip1);
+ screen.render(xo + 8 - 8 * flip1, yo + 0, xt + 1 + yt * 32, col, flip1);
+ if (!isSwimming()) {
+ screen.render(xo + 8 * flip2, yo + 8, xt + (yt + 1) * 32, col, flip2);
+ screen.render(xo + 8 - 8 * flip2, yo + 8, xt + 1 + (yt + 1) * 32, col, flip2);
+ }
+
+ if (attackTime > 0 && attackDir == 2) {
+ screen.render(xo - 4, yo, 7 + 13 * 32, Color.get(-1, 555, 555, 555), 1);
+ screen.render(xo - 4, yo + 8, 7 + 13 * 32, Color.get(-1, 555, 555, 555), 3);
+ if (attackItem != null) {
+ attackItem.renderIcon(screen, xo - 4, yo + 4);
+ }
+ }
+ if (attackTime > 0 && attackDir == 3) {
+ screen.render(xo + 8 + 4, yo, 7 + 13 * 32, Color.get(-1, 555, 555, 555), 0);
+ screen.render(xo + 8 + 4, yo + 8, 7 + 13 * 32, Color.get(-1, 555, 555, 555), 2);
+ if (attackItem != null) {
+ attackItem.renderIcon(screen, xo + 8 + 4, yo + 4);
+ }
+ }
+ if (attackTime > 0 && attackDir == 0) {
+ screen.render(xo + 0, yo + 8 + 4, 6 + 13 * 32, Color.get(-1, 555, 555, 555), 2);
+ screen.render(xo + 8, yo + 8 + 4, 6 + 13 * 32, Color.get(-1, 555, 555, 555), 3);
+ if (attackItem != null) {
+ attackItem.renderIcon(screen, xo + 4, yo + 8 + 4);
+ }
+ }
+
+ if (activeItem instanceof FurnitureItem) {
+ Furniture furniture = ((FurnitureItem) activeItem).furniture;
+ furniture.x = x;
+ furniture.y = yo;
+ furniture.render(screen);
+
+ }
+ }
+
+ public void touchItem(ItemEntity itemEntity) {
+ itemEntity.take(this);
+ inventory.add(itemEntity.item);
+ }
+
+ public boolean canSwim() {
+ return true;
+ }
+
+ public boolean findStartPos(Level level) {
+ while (true) {
+ int x = random.nextInt(level.w);
+ int y = random.nextInt(level.h);
+ if (level.getTile(x, y) == Tile.grass) {
+ this.x = x * 16 + 8;
+ this.y = y * 16 + 8;
+ return true;
+ }
+ }
+ }
+
+ public boolean payStamina(int cost) {
+ if (cost > stamina) return false;
+ stamina -= cost;
+ return true;
+ }
+
+ public void changeLevel(int dir) {
+ game.scheduleLevelChange(dir);
+ }
+
+ public int getLightRadius() {
+ int r = 2;
+ if (activeItem != null) {
+ if (activeItem instanceof FurnitureItem) {
+ int rr = ((FurnitureItem) activeItem).furniture.getLightRadius();
+ if (rr > r) r = rr;
+ }
+ }
+ return r;
+ }
+
+ protected void die() {
+ super.die();
+ Sound.playerDeath.play();
+ }
+
+ protected void touchedBy(Entity entity) {
+ if (!(entity instanceof Player)) {
+ entity.touchedBy(this);
+ }
+ }
+
+ protected void doHurt(int damage, int attackDir) {
+ if (hurtTime > 0 || invulnerableTime > 0) return;
+
+ Sound.playerHurt.play();
+ level.add(new TextParticle("" + damage, x, y, Color.get(-1, 504, 504, 504)));
+ health -= damage;
+ if (attackDir == 0) yKnockback = +6;
+ if (attackDir == 1) yKnockback = -6;
+ if (attackDir == 2) xKnockback = -6;
+ if (attackDir == 3) xKnockback = +6;
+ hurtTime = 10;
+ invulnerableTime = 30;
+ }
+
+ public void gameWon() {
+ level.player.invulnerableTime = 60 * 5;
+ game.won();
+ }
+}
View
97 src/com/mojang/ld22/entity/Slime.java
@@ -0,0 +1,97 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+
+public class Slime extends Mob {
+ private int xa, ya;
+ private int jumpTime = 0;
+ private int lvl;
+
+ public Slime(int lvl) {
+ this.lvl = lvl;
+ x = random.nextInt(64 * 16);
+ y = random.nextInt(64 * 16);
+ health = maxHealth = lvl * lvl * 5;
+ }
+
+ public void tick() {
+ super.tick();
+
+ int speed = 1;
+ if (!move(xa * speed, ya * speed) || random.nextInt(40) == 0) {
+ if (jumpTime <= -10) {
+ xa = (random.nextInt(3) - 1);
+ ya = (random.nextInt(3) - 1);
+
+ if (level.player != null) {
+ int xd = level.player.x - x;
+ int yd = level.player.y - y;
+ if (xd * xd + yd * yd < 50 * 50) {
+ if (xd < 0) xa = -1;
+ if (xd > 0) xa = +1;
+ if (yd < 0) ya = -1;
+ if (yd > 0) ya = +1;
+ }
+
+ }
+
+ if (xa != 0 || ya != 0) jumpTime = 10;
+ }
+ }
+
+ jumpTime--;
+ if (jumpTime == 0) {
+ xa = ya = 0;
+ }
+ }
+
+ protected void die() {
+ super.die();
+
+ int count = random.nextInt(2) + 1;
+ for (int i = 0; i < count; i++) {
+ level.add(new ItemEntity(new ResourceItem(Resource.slime), x + random.nextInt(11) - 5, y + random.nextInt(11) - 5));
+ }
+
+ if (level.player != null) {
+ level.player.score += 25*lvl;
+ }
+
+ }
+
+ public void render(Screen screen) {
+ int xt = 0;
+ int yt = 18;
+
+ int xo = x - 8;
+ int yo = y - 11;
+
+ if (jumpTime > 0) {
+ xt += 2;
+ yo -= 4;
+ }
+
+ int col = Color.get(-1, 10, 252, 555);
+ if (lvl == 2) col = Color.get(-1, 100, 522, 555);
+ if (lvl == 3) col = Color.get(-1, 111, 444, 555);
+ if (lvl == 4) col = Color.get(-1, 000, 111, 224);
+
+ if (hurtTime > 0) {
+ col = Color.get(-1, 555, 555, 555);
+ }
+
+ screen.render(xo + 0, yo + 0, xt + yt * 32, col, 0);
+ screen.render(xo + 8, yo + 0, xt + 1 + yt * 32, col, 0);
+ screen.render(xo + 0, yo + 8, xt + (yt + 1) * 32, col, 0);
+ screen.render(xo + 8, yo + 8, xt + 1 + (yt + 1) * 32, col, 0);
+ }
+
+ protected void touchedBy(Entity entity) {
+ if (entity instanceof Player) {
+ entity.hurt(this, lvl, dir);
+ }
+ }
+}
View
62 src/com/mojang/ld22/entity/Spark.java
@@ -0,0 +1,62 @@
+package com.mojang.ld22.entity;
+
+import java.util.List;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+
+public class Spark extends Entity {
+ private int lifeTime;
+ public double xa, ya;
+ public double xx, yy;
+ private int time;
+ private AirWizard owner;
+
+ public Spark(AirWizard owner, double xa, double ya) {
+ this.owner = owner;
+ xx = this.x = owner.x;
+ yy = this.y = owner.y;
+ xr = 0;
+ yr = 0;
+
+ this.xa = xa;
+ this.ya = ya;
+
+ lifeTime = 60 * 10 + random.nextInt(30);
+ }
+
+ public void tick() {
+ time++;
+ if (time >= lifeTime) {
+ remove();
+ return;
+ }
+ xx += xa;
+ yy += ya;
+ x = (int) xx;
+ y = (int) yy;
+ List<Entity> toHit = level.getEntities(x, y, x, y);
+ for (int i = 0; i < toHit.size(); i++) {
+ Entity e = toHit.get(i);
+ if (e instanceof Mob && !(e instanceof AirWizard)) {
+ e.hurt(owner, 1, ((Mob) e).dir ^ 1);
+ }
+ }
+ }
+
+ public boolean isBlockableBy(Mob mob) {
+ return false;
+ }
+
+ public void render(Screen screen) {
+ if (time >= lifeTime - 6 * 20) {
+ if (time / 6 % 2 == 0) return;
+ }
+
+ int xt = 8;
+ int yt = 13;
+
+ screen.render(x - 4, y - 4 - 2, xt + yt * 32, Color.get(-1, 555, 555, 555), random.nextInt(4));
+ screen.render(x - 4, y - 4 + 2, xt + yt * 32, Color.get(-1, 000, 000, 000), random.nextInt(4));
+ }
+}
View
20 src/com/mojang/ld22/entity/Workbench.java
@@ -0,0 +1,20 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.crafting.Crafting;
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.screen.CraftingMenu;
+
+public class Workbench extends Furniture {
+ public Workbench() {
+ super("Workbench");
+ col = Color.get(-1, 100, 321, 431);
+ sprite = 4;
+ xr = 3;
+ yr = 2;
+ }
+
+ public boolean use(Player player, int attackDir) {
+ player.game.setMenu(new CraftingMenu(Crafting.workbenchRecipes, player));
+ return true;
+ }
+}
View
103 src/com/mojang/ld22/entity/Zombie.java
@@ -0,0 +1,103 @@
+package com.mojang.ld22.entity;
+
+import com.mojang.ld22.gfx.Color;
+import com.mojang.ld22.gfx.Screen;
+import com.mojang.ld22.item.ResourceItem;
+import com.mojang.ld22.item.resource.Resource;
+
+public class Zombie extends Mob {
+ private int xa, ya;
+ private int lvl;
+ private int randomWalkTime = 0;
+
+ public Zombie(int lvl) {
+ this.lvl = lvl;
+ x = random.nextInt(64 * 16);
+ y = random.nextInt(64 * 16);
+ health = maxHealth = lvl * lvl * 10;
+
+ }
+
+ public void tick() {
+ super.tick();
+
+ if (level.player != null && randomWalkTime == 0) {
+ int xd = level.player.x - x;
+ int yd = level.player.y - y;
+ if (xd * xd + yd * yd < 50 * 50) {
+ xa = 0;
+ ya = 0;
+ if (xd < 0) xa = -1;
+ if (xd > 0) xa = +1;
+ if (yd < 0) ya = -1;
+ if (yd > 0) ya = +1;
+ }
+ }
+
+ int speed = tickTime & 1;
+ if (!move(xa * speed, ya * speed) || random.nextInt(200) == 0) {
+ randomWalkTime = 60;
+ xa = (random.nextInt(3) - 1) * random.nextInt(2);
+ ya = (random.nextInt(3) - 1) * random.nextInt(2);
+ }
+ if (randomWalkTime > 0) randomWalkTime--;
+ }
+
+ public void render(Screen screen) {
+ int xt = 0;
+ int yt = 14;
+
+ int flip1 = (walkDist >> 3) & 1;
+ int flip2 = (walkDist >> 3) & 1;
+
+ if (dir == 1) {
+ xt += 2;
+ }
+ if (dir > 1) {
+
+ flip1 = 0;
+ flip2 = ((walkDist >> 4) & 1);
+ if (dir == 2) {
+ flip1 = 1;
+ }
+ xt += 4 + ((walkDist >> 3) & 1) * 2;