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 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 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 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(); } }