From bb1374427cc62b53744a412d52859d407dab679d Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:48:03 +0800 Subject: [PATCH 01/14] Tidy up some keymaps --- src/client/java/minicraft/core/Renderer.java | 6 ++-- .../java/minicraft/core/io/InputHandler.java | 28 ++++++++++--------- .../java/minicraft/entity/mob/Player.java | 25 ++++++++--------- .../java/minicraft/screen/PauseDisplay.java | 3 +- .../screen/TutorialDisplayHandler.java | 6 ++-- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/client/java/minicraft/core/Renderer.java b/src/client/java/minicraft/core/Renderer.java index 01e024f4e..c3fdecb81 100644 --- a/src/client/java/minicraft/core/Renderer.java +++ b/src/client/java/minicraft/core/Renderer.java @@ -325,19 +325,19 @@ private static void renderGui() { } // This renders the potions overlay - if (player.showpotioneffects && player.potioneffects.size() > 0) { + if (player.showPotionEffects && player.potioneffects.size() > 0) { @SuppressWarnings("unchecked") Map.Entry[] effects = player.potioneffects.entrySet().toArray(new Map.Entry[0]); // The key is potion type, value is remaining potion duration. - if (!player.simpPotionEffects) { + if (!player.simplifyPotionEffects) { for (int i = 0; i < effects.length; i++) { PotionType pType = effects[i].getKey(); int pTime = effects[i].getValue() / Updater.normSpeed; int minutes = pTime / 60; int seconds = pTime % 60; - Font.drawBackground(Localization.getLocalized("minicraft.display.gui.potion_effects.hide_hint", input.getMapping("potionEffects")), screen, 180, 9); + Font.drawBackground(Localization.getLocalized("minicraft.display.gui.potion_effects.hide_hint", input.getMapping("POTION-EFFECTS")), screen, 180, 9); Font.drawBackground(Localization.getLocalized("minicraft.display.gui.potion_effects.potion_dur", pType, minutes, seconds), screen, 180, 17 + i * Font.textHeight() + potionRenderOffset, pType.dispColor); } } else { diff --git a/src/client/java/minicraft/core/io/InputHandler.java b/src/client/java/minicraft/core/io/InputHandler.java index d24b53c37..3279141b6 100644 --- a/src/client/java/minicraft/core/io/InputHandler.java +++ b/src/client/java/minicraft/core/io/InputHandler.java @@ -134,10 +134,11 @@ private void initKeyMap() { keymap.put("SELECT", "ENTER"); keymap.put("EXIT", "ESCAPE"); - keymap.put("QUICKSAVE", "R"); // Saves the game while still playing + keymap.put("QUICK-SAVE", "R"); // Saves the game while still playing - keymap.put("ATTACK", "C|SPACE|ENTER"); // Attack action references "C" key - keymap.put("MENU", "X|E"); // And so on... menu does various things. + keymap.put("ATTACK", "C|SPACE"); // Attack/destroy action references "C" key + keymap.put("INTERACT", "X|ENTER"); // Interact action references "X" key (formerly "menu") + keymap.put("INVENTORY", "E"); // Open/close player inventory menu and exit action of some displays. keymap.put("CRAFT", "Z|SHIFT-E"); // Open/close personal crafting window. keymap.put("PICKUP", "V|P"); // Pickup torches / furniture; this replaces the power glove. keymap.put("DROP-ONE", "Q"); // Drops the item in your hand, or selected in your inventory, by ones; it won't drop an entire stack @@ -152,12 +153,11 @@ private void initKeyMap() { keymap.put("PAUSE", "ESCAPE"); // Pause the Game. - keymap.put("POTIONEFFECTS", "P"); // Toggle potion effect display - keymap.put("SIMPPOTIONEFFECTS", "O"); // Whether to simplify the potion effect display - keymap.put("EXPANDQUESTDISPLAY", "L"); // Expands the quest display - keymap.put("TOGGLEHUD", "F1"); // Toggle HUD + keymap.put("POTION-EFFECTS", "P"); // Toggle potion effect display + keymap.put("SIMPLIFY-POTION-EFFECTS", "O"); // Whether to simplify the potion effect display + keymap.put("EXPAND-QUEST-DISPLAY", "L"); // Expands the quest display + keymap.put("TOGGLE-HUD", "F1"); // Toggle HUD keymap.put("SCREENSHOT", "F2"); // To make screenshot - keymap.put("INFO", "SHIFT-I"); // Toggle player stats display keymap.put("FULLSCREEN", "F11"); } @@ -179,16 +179,18 @@ private void initButtonMap() { buttonMap.put("EXIT", ControllerButton.B); buttonMap.put("ATTACK", ControllerButton.A); - buttonMap.put("MENU", ControllerButton.X); - buttonMap.put("CRAFT", ControllerButton.Y); - buttonMap.put("PICKUP", ControllerButton.LEFTBUMPER); + buttonMap.put("INTERACT", ControllerButton.B); + buttonMap.put("MENU", ControllerButton.Y); + buttonMap.put("CRAFT", ControllerButton.X); + buttonMap.put("PICKUP", ControllerButton.LEFTSTICK); + buttonMap.put("INVENTORY", ControllerButton.RIGHTSTICK); buttonMap.put("SEARCHER-BAR", ControllerButton.START); buttonMap.put("PAUSE", ControllerButton.START); - buttonMap.put("DROP-ONE", ControllerButton.RIGHTBUMPER); - buttonMap.put("DROP-STACK", ControllerButton.RIGHTSTICK); + buttonMap.put("DROP-ONE", ControllerButton.LEFTBUMPER); + buttonMap.put("DROP-STACK", ControllerButton.RIGHTBUMPER); } public void resetKeyBindings() { diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index a669d05ce..302bdea4e 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -47,7 +47,6 @@ import minicraft.saveload.Save; import minicraft.screen.AchievementsDisplay; import minicraft.screen.CraftingDisplay; -import minicraft.screen.InfoDisplay; import minicraft.screen.LoadingDisplay; import minicraft.screen.PauseDisplay; import minicraft.screen.PlayerInvDisplay; @@ -120,8 +119,8 @@ public class Player extends Mob implements ItemHolder, ClientTickable { private int hungerStarveDelay; // The delay between each time the hunger bar decreases your health public HashMap potioneffects; // The potion effects currently applied to the player - public boolean showpotioneffects; // Whether to display the current potion effects on screen - public boolean simpPotionEffects; + public boolean showPotionEffects; // Whether to display the current potion effects on screen + public boolean simplifyPotionEffects; public boolean renderGUI; public int questExpanding; // Lets the display keeps expanded. private int cooldowninfo; // Prevents you from toggling the info pane on and off super fast. @@ -186,8 +185,8 @@ public void updateInv(String items) { }; potioneffects = new HashMap<>(); - showpotioneffects = true; - simpPotionEffects = false; + showPotionEffects = true; + simplifyPotionEffects = false; renderGUI = true; cooldowninfo = 0; @@ -307,20 +306,20 @@ public void tick() { if (cooldowninfo > 0) cooldowninfo--; if (questExpanding > 0) questExpanding--; - if (input.inputPressed("potionEffects") && cooldowninfo == 0) { + if (input.inputPressed("POTION-EFFECTS") && cooldowninfo == 0) { cooldowninfo = 10; - showpotioneffects = !showpotioneffects; + showPotionEffects = !showPotionEffects; } - if (input.inputPressed("simpPotionEffects")) { - simpPotionEffects = !simpPotionEffects; + if (input.inputPressed("SIMPLIFY-POTION-EFFECTS")) { + simplifyPotionEffects = !simplifyPotionEffects; } - if (input.inputPressed("toggleHUD")) { + if (input.inputPressed("TOGGLE-HUD")) { renderGUI = !renderGUI; } - if (input.inputPressed("expandQuestDisplay")) { + if (input.inputPressed("EXPAND-QUEST-DISPLAY")) { questExpanding = 30; } @@ -527,9 +526,7 @@ public void tick() { if (input.inputPressed("craft") && !use()) Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); - if (input.inputDown("info")) Game.setDisplay(new InfoDisplay()); - - if (input.inputDown("quicksave") && !Updater.saving) { + if (input.inputPressed("QUICK-SAVE") && !Updater.saving) { Updater.saving = true; LoadingDisplay.setPercentage(0); new Save(WorldSelectDisplay.getWorldName()); diff --git a/src/client/java/minicraft/screen/PauseDisplay.java b/src/client/java/minicraft/screen/PauseDisplay.java index 34a158d33..ef92731e1 100644 --- a/src/client/java/minicraft/screen/PauseDisplay.java +++ b/src/client/java/minicraft/screen/PauseDisplay.java @@ -24,7 +24,8 @@ public PauseDisplay() { new BlankEntry(), new SelectEntry("minicraft.displays.pause.return", () -> Game.setDisplay(null)), new SelectEntry("minicraft.display.options_display", () -> Game.setDisplay(new OptionsWorldDisplay())), - new SelectEntry("minicraft.displays.achievements", () -> Game.setDisplay(new AchievementsDisplay())) + new SelectEntry("minicraft.displays.achievements", () -> Game.setDisplay(new AchievementsDisplay())), + new SelectEntry("minicraft.displays.info.title", () -> Game.setDisplay(new InfoDisplay())) )); if (TutorialDisplayHandler.inQuests()) diff --git a/src/client/java/minicraft/screen/TutorialDisplayHandler.java b/src/client/java/minicraft/screen/TutorialDisplayHandler.java index 06be9c594..184a5fabd 100644 --- a/src/client/java/minicraft/screen/TutorialDisplayHandler.java +++ b/src/client/java/minicraft/screen/TutorialDisplayHandler.java @@ -171,7 +171,7 @@ private static void turnOffGuides() { public static void tick(InputHandler input) { if (currentGuide != null) { if (ControlGuide.animation > 0) ControlGuide.animation--; - if (input.getKey("expandQuestDisplay").clicked) { + if (input.getKey("EXPAND-QUEST-DISPLAY").clicked) { Logging.TUTORIAL.debug("Force-completed the guides."); turnOffGuides(); return; @@ -192,7 +192,7 @@ public static void tick(InputHandler input) { } if (currentOngoingElement != null) { - if (input.getKey("expandQuestDisplay").clicked && Game.getDisplay() == null) { + if (input.getKey("EXPAND-QUEST-DISPLAY").clicked && Game.getDisplay() == null) { Game.setDisplay(new PopupDisplay(new PopupDisplay.PopupConfig(currentOngoingElement.key, null, 4), currentOngoingElement.description)); } @@ -244,7 +244,7 @@ public static void render(Screen screen) { menu.render(screen); Rectangle bounds = menu.getBounds(); String text = Localization.getLocalized("minicraft.displays.tutorial_display_handler.display.element_examine_help", - Game.input.getMapping("expandQuestDisplay")); + Game.input.getMapping("EXPAND-QUEST-DISPLAY")); String[] lines = Font.getLines(text, Screen.w*2/3, Screen.h, 0); for (int i = 0; i < lines.length; i++) Font.draw(lines[i], screen, bounds.getRight() - Font.textWidth(lines[i]), bounds.getBottom() + 8 * (1+i), Color.GRAY); From f34a165598dc6cb009c1b9eef90014cd3b8a3a96 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 4 Aug 2023 16:15:43 +0800 Subject: [PATCH 02/14] Separate player attack and resolve some items --- .../java/minicraft/core/io/InputHandler.java | 5 +- src/client/java/minicraft/entity/Entity.java | 4 +- .../java/minicraft/entity/furniture/Bed.java | 2 +- .../minicraft/entity/furniture/Chest.java | 8 +- .../minicraft/entity/furniture/Crafter.java | 2 +- .../entity/furniture/DeathChest.java | 2 +- .../entity/furniture/DungeonChest.java | 10 +- .../minicraft/entity/furniture/Furniture.java | 6 +- .../entity/furniture/KnightStatue.java | 2 +- .../minicraft/entity/furniture/Spawner.java | 6 +- .../java/minicraft/entity/furniture/Tnt.java | 2 +- .../java/minicraft/entity/mob/Player.java | 123 +++++++++++------- .../java/minicraft/entity/mob/Sheep.java | 2 +- .../java/minicraft/item/FishingRodItem.java | 5 +- .../java/minicraft/item/FurnitureItem.java | 7 +- src/client/java/minicraft/item/Item.java | 10 +- src/client/java/minicraft/item/ToolItem.java | 27 +++- .../minicraft/level/tile/BossDoorTile.java | 4 +- .../minicraft/level/tile/BossFloorTile.java | 4 +- .../minicraft/level/tile/BossWallTile.java | 4 +- .../java/minicraft/level/tile/CloudTile.java | 2 +- .../java/minicraft/level/tile/DecorTile.java | 2 +- .../java/minicraft/level/tile/DirtTile.java | 2 +- .../java/minicraft/level/tile/DoorTile.java | 2 +- .../java/minicraft/level/tile/FloorTile.java | 2 +- .../java/minicraft/level/tile/FlowerTile.java | 2 +- .../java/minicraft/level/tile/GrassTile.java | 2 +- .../minicraft/level/tile/HardRockTile.java | 2 +- .../minicraft/level/tile/LavaBrickTile.java | 2 +- .../minicraft/level/tile/MaterialTile.java | 2 +- .../java/minicraft/level/tile/OreTile.java | 2 +- .../java/minicraft/level/tile/PathTile.java | 2 +- .../java/minicraft/level/tile/RockTile.java | 2 +- .../java/minicraft/level/tile/SandTile.java | 2 +- .../java/minicraft/level/tile/StairsTile.java | 4 +- .../java/minicraft/level/tile/Tile.java | 14 ++ .../java/minicraft/level/tile/TorchTile.java | 2 +- .../java/minicraft/level/tile/TreeTile.java | 2 +- .../java/minicraft/level/tile/WallTile.java | 2 +- .../java/minicraft/level/tile/WoolTile.java | 2 +- .../level/tile/farming/FarmTile.java | 2 +- .../java/minicraft/screen/BookDisplay.java | 2 +- .../minicraft/screen/ContainerDisplay.java | 14 +- .../minicraft/screen/CraftingDisplay.java | 4 +- .../minicraft/screen/PlayerInvDisplay.java | 4 +- .../screen/TutorialDisplayHandler.java | 4 +- 46 files changed, 187 insertions(+), 132 deletions(-) diff --git a/src/client/java/minicraft/core/io/InputHandler.java b/src/client/java/minicraft/core/io/InputHandler.java index 3279141b6..a1194fafd 100644 --- a/src/client/java/minicraft/core/io/InputHandler.java +++ b/src/client/java/minicraft/core/io/InputHandler.java @@ -180,10 +180,9 @@ private void initButtonMap() { buttonMap.put("ATTACK", ControllerButton.A); buttonMap.put("INTERACT", ControllerButton.B); - buttonMap.put("MENU", ControllerButton.Y); - buttonMap.put("CRAFT", ControllerButton.X); + buttonMap.put("INVENTORY", ControllerButton.X); + buttonMap.put("CRAFT", ControllerButton.Y); buttonMap.put("PICKUP", ControllerButton.LEFTSTICK); - buttonMap.put("INVENTORY", ControllerButton.RIGHTSTICK); buttonMap.put("SEARCHER-BAR", ControllerButton.START); diff --git a/src/client/java/minicraft/entity/Entity.java b/src/client/java/minicraft/entity/Entity.java index 0ff319460..7c1cf8c2c 100644 --- a/src/client/java/minicraft/entity/Entity.java +++ b/src/client/java/minicraft/entity/Entity.java @@ -106,13 +106,13 @@ public boolean canBeAffectedByLava() { protected void touchedBy(Entity entity) {} /** - * Interacts with the entity this method is called on + * Attacks the entity this method is called on * @param player The player attacking * @param item The item the player attacked with * @param attackDir The direction to interact * @return If the interaction was successful */ - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { return false; } diff --git a/src/client/java/minicraft/entity/furniture/Bed.java b/src/client/java/minicraft/entity/furniture/Bed.java index 41f57fd99..8ce60c202 100644 --- a/src/client/java/minicraft/entity/furniture/Bed.java +++ b/src/client/java/minicraft/entity/furniture/Bed.java @@ -23,7 +23,7 @@ public Bed() { } /** Called when the player attempts to get in bed. */ - public boolean use(Player player) { + public boolean interact(Player player) { if (checkCanSleep(player)) { // If it is late enough in the day to sleep... // Set the player spawn coord. to their current position, in tile coords (hence " >> 4") diff --git a/src/client/java/minicraft/entity/furniture/Chest.java b/src/client/java/minicraft/entity/furniture/Chest.java index b2f186cc6..0bae663de 100644 --- a/src/client/java/minicraft/entity/furniture/Chest.java +++ b/src/client/java/minicraft/entity/furniture/Chest.java @@ -33,8 +33,8 @@ public Chest(String name, LinkedSprite itemSprite) { inventory = new Inventory(); // Initialize the inventory. } - /** This is what occurs when the player uses the "Menu" command near this */ - public boolean use(Player player) { + /** This is what occurs when the player uses the "Interact" command near this */ + public boolean interact(Player player) { Game.setDisplay(new ContainerDisplay(player, this)); return true; } @@ -62,9 +62,9 @@ public void populateInvRandom(String lootTable, int depth) { } @Override - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { if (inventory.invSize() == 0) - return super.interact(player, item, attackDir); + return super.attack(player, item, attackDir); return false; } diff --git a/src/client/java/minicraft/entity/furniture/Crafter.java b/src/client/java/minicraft/entity/furniture/Crafter.java index 27f40ee23..865eff800 100644 --- a/src/client/java/minicraft/entity/furniture/Crafter.java +++ b/src/client/java/minicraft/entity/furniture/Crafter.java @@ -48,7 +48,7 @@ public Crafter(Crafter.Type type) { this.type = type; } - public boolean use(Player player) { + public boolean interact(Player player) { Game.setDisplay(new CraftingDisplay(type.recipes, type.name(), player)); return true; } diff --git a/src/client/java/minicraft/entity/furniture/DeathChest.java b/src/client/java/minicraft/entity/furniture/DeathChest.java index 3e7741dd4..f6c39e977 100644 --- a/src/client/java/minicraft/entity/furniture/DeathChest.java +++ b/src/client/java/minicraft/entity/furniture/DeathChest.java @@ -89,7 +89,7 @@ public void render(Screen screen) { Font.draw(timeString, screen, x - Font.textWidth(timeString)/2, y - Font.textHeight() - getBounds().getHeight()/2, Color.WHITE); } - public boolean use(Player player) { return false; } // can't open it, just walk into it. + public boolean interact(Player player) { return false; } // can't open it, just walk into it. public void take(Player player) {} // can't grab a death chest. diff --git a/src/client/java/minicraft/entity/furniture/DungeonChest.java b/src/client/java/minicraft/entity/furniture/DungeonChest.java index a7aaf9ddf..5dc7d6f38 100644 --- a/src/client/java/minicraft/entity/furniture/DungeonChest.java +++ b/src/client/java/minicraft/entity/furniture/DungeonChest.java @@ -47,7 +47,7 @@ public DungeonChest(boolean populateInv, boolean unlocked) { return new DungeonChest(false, !this.isLocked); } - public boolean use(Player player) { + public boolean interact(Player player) { if (isLocked) { boolean activeKey = player.activeItem != null && player.activeItem.equals(Items.get("Key")); boolean invKey = player.getInventory().count(Items.get("key")) > 0; @@ -72,12 +72,12 @@ public boolean use(Player player) { level.dropItem(x, y, 5, Items.get("Gold Apple")); } - return super.use(player); // the player unlocked the chest. + return super.interact(player); // the player unlocked the chest. } return false; // the chest is locked, and the player has no key. } - else return super.use(player); // the chest was already unlocked. + else return super.interact(player); // the chest was already unlocked. } /** @@ -113,9 +113,9 @@ protected void touchedBy(Entity entity) { } @Override - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { if(!isLocked) - return super.interact(player, item, attackDir); + return super.attack(player, item, attackDir); return false; } } diff --git a/src/client/java/minicraft/entity/furniture/Furniture.java b/src/client/java/minicraft/entity/furniture/Furniture.java index 148a8098a..3a98b39d1 100644 --- a/src/client/java/minicraft/entity/furniture/Furniture.java +++ b/src/client/java/minicraft/entity/furniture/Furniture.java @@ -70,8 +70,8 @@ public void tick() { /** Draws the furniture on the screen. */ public void render(Screen screen) { screen.render(x-8, y-8, sprite); } - /** Called when the player presses the MENU key in front of this. */ - public boolean use(Player player) { return false; } + /** Called when the player presses the INTERACT key in front of this. */ + public boolean interact(Player player) { return false; } @Override public boolean blocks(Entity e) { @@ -89,7 +89,7 @@ protected void touchedBy(Entity entity) { * @param player The player picking up the furniture. */ @Override - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { if (item instanceof PowerGloveItem) { Sound.play("monsterhurt"); remove(); diff --git a/src/client/java/minicraft/entity/furniture/KnightStatue.java b/src/client/java/minicraft/entity/furniture/KnightStatue.java index 566b0ed13..c1a929b60 100644 --- a/src/client/java/minicraft/entity/furniture/KnightStatue.java +++ b/src/client/java/minicraft/entity/furniture/KnightStatue.java @@ -19,7 +19,7 @@ public KnightStatue(int health) { } @Override - public boolean interact(Player player, Item heldItem, Direction attackDir) { + public boolean attack(Player player, Item heldItem, Direction attackDir) { if (!ObsidianKnight.active) { if (touches == 0) { // Touched the first time. Game.notifications.add(Localization.getLocalized("minicraft.notifications.statue_tapped")); diff --git a/src/client/java/minicraft/entity/furniture/Spawner.java b/src/client/java/minicraft/entity/furniture/Spawner.java index 6a9eb9059..5f198e504 100644 --- a/src/client/java/minicraft/entity/furniture/Spawner.java +++ b/src/client/java/minicraft/entity/furniture/Spawner.java @@ -173,7 +173,7 @@ private void trySpawn() { } @Override - public boolean interact(Player player, Item item, Direction attackDir) { + public boolean attack(Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem)item; @@ -211,13 +211,13 @@ public boolean interact(Player player, Item item, Direction attackDir) { return true; } - if (item == null) return use(player); + if (item == null) return interact(player); return false; } @Override - public boolean use(Player player) { + public boolean interact(Player player) { if (Game.isMode("minicraft.settings.mode.creative") && mob instanceof EnemyMob) { lvl++; if (lvl > maxMobLevel) lvl = 1; diff --git a/src/client/java/minicraft/entity/furniture/Tnt.java b/src/client/java/minicraft/entity/furniture/Tnt.java index 9b659d2c0..7e5ce3efc 100644 --- a/src/client/java/minicraft/entity/furniture/Tnt.java +++ b/src/client/java/minicraft/entity/furniture/Tnt.java @@ -124,7 +124,7 @@ public void actionPerformed(ActionEvent e) { } @Override - public boolean interact(Player player, Item heldItem, Direction attackDir) { + public boolean attack(Player player, Item heldItem, Direction attackDir) { if (!fuseLit) { fuseLit = true; Sound.play("fuse"); diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index 302bdea4e..010a3db35 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -500,7 +500,14 @@ public void tick() { attack(); } - if (input.inputPressed("menu") && activeItem != null) { + if ((activeItem == null || !activeItem.used_pending) && (input.inputPressed("interact")) && stamina != 0 && onFallDelay <= 0) { // This only allows interactions when such action is possible. + if (!potioneffects.containsKey(PotionType.Energy)) stamina--; + staminaRecharge = 0; + + interact(); + } + + if (input.inputPressed("INVENTORY") && activeItem != null) { int returned = inventory.add(0, activeItem); if (activeItem instanceof StackableItem) { StackableItem stackable = (StackableItem)activeItem; @@ -519,11 +526,11 @@ public void tick() { } if (Game.getDisplay() == null) { - if (input.inputPressed("menu") && !use()) // !use() = no furniture in front of the player; this prevents player inventory from opening (will open furniture inventory instead) + if (input.inputPressed("INVENTORY")) Game.setDisplay(new PlayerInvDisplay(this)); if (input.inputPressed("pause")) Game.setDisplay(new PauseDisplay()); - if (input.inputPressed("craft") && !use()) + if (input.inputPressed("craft")) Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); if (input.inputPressed("QUICK-SAVE") && !Updater.saving) { @@ -591,21 +598,6 @@ protected void attack() { // walkDist is not synced, so this can happen for both the client and server. walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } - - if (activeItem != null && !activeItem.interactsWithWorld()) { - attackDir = dir; // Make the attack direction equal the current direction - attackItem = activeItem; // Make attackItem equal activeItem - activeItem.interactOn(Tiles.get("rock"), level, 0, 0, this, attackDir); - if (activeItem.isDepleted()) { - activeItem = null; - } - return; - } - attackDir = dir; // Make the attack direction equal the current direction attackItem = activeItem; // Make attackItem equal activeItem @@ -614,25 +606,8 @@ protected void attack() { attackTime = 10; boolean done = false; - // Fire a bow if we have the stamina and an arrow. - if (activeItem instanceof ToolItem && stamina - 1 >= 0) { - ToolItem tool = (ToolItem) activeItem; - if (tool.type == ToolType.Bow && tool.dur > 0 && inventory.count(Items.arrowItem) > 0) { - - inventory.removeItem(Items.arrowItem); - level.add(new Arrow(this, attackDir, tool.level)); - attackTime = 10; - - if (!Game.isMode("minicraft.settings.mode.creative")) tool.dur--; - - AchievementsDisplay.setAchievement("minicraft.achievement.bow",true); - - return; - } - } - // If the interaction between you and an entity is successful, then return. - if (interact(getInteractionBox(INTERACT_DIST))) return; + if (attack(getInteractionBox(INTERACT_DIST))) return; // Attempt to interact with the tile. Point t = getInteractionTile(); @@ -648,11 +623,11 @@ protected void attack() { Tile tile = level.getTile(t.x, t.y); // If the item successfully interacts with the target tile. - if (activeItem.interactOn(tile, level, t.x, t.y, this, attackDir)) { + if (activeItem.attackOn(tile, level, t.x, t.y, this, attackDir)) { done = true; // Returns true if the target tile successfully interacts with the item. - } else if (tile.interact(level, t.x, t.y, this, activeItem, attackDir)){ + } else if (tile.attack(level, t.x, t.y, this, activeItem, attackDir)){ done = true; } } @@ -665,7 +640,7 @@ protected void attack() { if (done) return; // Skip the rest if interaction was handled } - if (activeItem == null || activeItem.canAttack()) { // If there is no active item, OR if the item can be used to attack... + if (activeItem == null) { // If there is no active item, OR if the item can be used to attack... attackTime = 5; // Attacks the enemy in the appropriate direction. boolean used = hurt(getInteractionBox(ATTACK_DIST)); @@ -684,6 +659,62 @@ protected void attack() { } } + protected void interact() { + // walkDist is not synced, so this can happen for both the client and server. + walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) + + if (isFishing) { + isFishing = false; + fishingTicks = maxFishingTicks; + } + + if (activeItem != null && !activeItem.interactsWithWorld()) { + if (activeItem.interactOn(Tiles.get(0), level, x >> 4, y >> 4, this, attackDir)) { + if (activeItem.isDepleted()) { + activeItem = null; + } + return; + } + } + + // If we are holding an item. + if (activeItem != null) { + boolean done = false; + + // If the interaction between you and an entity is successful, then return. + if (interact(getInteractionBox(INTERACT_DIST))) return; + + // Attempt to interact with the tile. + Point t = getInteractionTile(); + + // If the target coordinates are a valid tile. + if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { + + // Get any entities (except dropped items and particles) on the tile. + List tileEntities = level.getEntitiesInTiles(t.x, t.y, t.x, t.y, false, ItemEntity.class, Particle.class); + + // If there are no other entities than us on the tile. + if (tileEntities.size() == 0 || tileEntities.size() == 1 && tileEntities.get(0) == this) { + Tile tile = level.getTile(t.x, t.y); + + // If the item successfully interacts with the target tile. + if (activeItem.interactOn(tile, level, t.x, t.y, this, attackDir)) { + done = true; + + // Returns true if the target tile successfully interacts with the item. + } else if (tile.interact(level, t.x, t.y, this, activeItem, attackDir)){ + done = true; + } + } + + if (done && activeItem.isDepleted()) { + // If the activeItem has 0 items left, then "destroy" it. + activeItem = null; + } + } + } + } + private Rectangle getInteractionBox(int range) { int x = this.x, y = this.y - 2; @@ -763,22 +794,20 @@ private void goFishing() { fishingTicks = maxFishingTicks; // If you didn't catch anything, try again in 120 ticks } - private boolean use() { return use(getInteractionBox(INTERACT_DIST)); } - /** called by other use method; this serves as a buffer in case there is no entity in front of the player. */ - private boolean use(Rectangle area) { + private boolean interact(Rectangle area) { List entities = level.getEntitiesInRect(area); // Gets the entities within the 4 points for (Entity e : entities) { - if (e instanceof Furniture && ((Furniture) e).use(this)) return true; // If the entity is not the player, then call it's use method, and return the result. Only some furniture classes use this. + if (e instanceof Furniture && ((Furniture) e).interact(this)) return true; // If the entity is not the player, then call it's use method, and return the result. Only some furniture classes use this. } return false; } - /** same, but for interaction. */ - private boolean interact(Rectangle area) { + /** same, but for attack. */ + private boolean attack(Rectangle area) { List entities = level.getEntitiesInRect(area); for (Entity e : entities) { - if (e != this && e.interact(this, activeItem, attackDir)) return true; // This is the ONLY place that the Entity.interact method is actually called. + if (e != this && e.attack(this, activeItem, attackDir)) return true; // This is the ONLY place that the Entity.interact method is actually called. } return false; } @@ -794,7 +823,7 @@ private boolean hurt(Rectangle area) { ((Mob) e).hurt(this, dmg, attackDir); } if (e instanceof Furniture) - e.interact(this, null, attackDir); + e.attack(this, null, attackDir); } return maxDmg > 0; } diff --git a/src/client/java/minicraft/entity/mob/Sheep.java b/src/client/java/minicraft/entity/mob/Sheep.java index 90a594d49..9bf0c322f 100644 --- a/src/client/java/minicraft/entity/mob/Sheep.java +++ b/src/client/java/minicraft/entity/mob/Sheep.java @@ -54,7 +54,7 @@ public void tick() { } } - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { if (cut) return false; if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/item/FishingRodItem.java b/src/client/java/minicraft/item/FishingRodItem.java index 5a8fade64..555e30712 100644 --- a/src/client/java/minicraft/item/FishingRodItem.java +++ b/src/client/java/minicraft/item/FishingRodItem.java @@ -68,10 +68,7 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return false; } - @Override - public boolean canAttack() { return false; } - - @Override + @Override public boolean isDepleted() { if (random.nextInt(100) > 120 - uses + level * 6) { // Breaking is random, the lower the level, and the more times you use it, the higher the chance Game.notifications.add("Your Fishing rod broke."); diff --git a/src/client/java/minicraft/item/FurnitureItem.java b/src/client/java/minicraft/item/FurnitureItem.java index 0bf800a8d..4ee5144a5 100644 --- a/src/client/java/minicraft/item/FurnitureItem.java +++ b/src/client/java/minicraft/item/FurnitureItem.java @@ -70,12 +70,7 @@ public FurnitureItem(Furniture furniture) { placed = false; } - /** Determines if you can attack enemies with furniture (you can't) */ - public boolean canAttack() { - return false; - } - - /** What happens when you press the "Attack" key with the furniture in your hands */ + /** What happens when you press the "Attack" key with the furniture in your hands */ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (tile.mayPass(level, xt, yt, furniture)) { // If the furniture can go on the tile Sound.play("craft"); diff --git a/src/client/java/minicraft/item/Item.java b/src/client/java/minicraft/item/Item.java index a7fed6f38..bfea42c1c 100644 --- a/src/client/java/minicraft/item/Item.java +++ b/src/client/java/minicraft/item/Item.java @@ -37,6 +37,11 @@ public void renderHUD(Screen screen, int x, int y, int fontColor) { Font.drawBackground(dispName, screen, x + 8, y, fontColor); } + /** Determines what happens when the player attacks with a tile */ + public boolean attackOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + return false; + } + /** Determines what happens when the player interacts with a tile */ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { return false; @@ -47,11 +52,6 @@ public boolean isDepleted() { return false; } - /** Returns if the item can attack mobs or not */ - public boolean canAttack() { - return false; - } - /** Sees if an item equals another item */ public boolean equals(Item item) { return item != null && item.getClass().equals(getClass()) && item.name.equals(name); diff --git a/src/client/java/minicraft/item/ToolItem.java b/src/client/java/minicraft/item/ToolItem.java index 297760fd1..06265ac20 100644 --- a/src/client/java/minicraft/item/ToolItem.java +++ b/src/client/java/minicraft/item/ToolItem.java @@ -2,10 +2,16 @@ import minicraft.core.Game; import minicraft.core.io.Localization; +import minicraft.entity.Arrow; +import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Mob; +import minicraft.entity.mob.Player; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.level.Level; +import minicraft.level.tile.Tile; +import minicraft.screen.AchievementsDisplay; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -71,9 +77,24 @@ public boolean isDepleted() { return dur <= 0 && type.durability > 0; } - /** You can attack mobs with tools. */ - public boolean canAttack() { - return type != ToolType.Shears; + @Override + public boolean interactsWithWorld() { + return type != ToolType.Bow; + } + + @Override + public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + Inventory inventory = player.getInventory(); + // Fire a bow if the player has the stamina and an arrow. + if (type == ToolType.Bow && player.payStamina(1) && inventory.count(Items.arrowItem) > 0) { + inventory.removeItem(Items.arrowItem); + level.add(new Arrow(player, attackDir, this.level)); + if (!Game.isMode("minicraft.settings.mode.creative")) dur--; + AchievementsDisplay.setAchievement("minicraft.achievement.bow",true); + return true; + } + + return super.interactOn(tile, level, xt, yt, player, attackDir); } public boolean payDurability() { diff --git a/src/client/java/minicraft/level/tile/BossDoorTile.java b/src/client/java/minicraft/level/tile/BossDoorTile.java index 581030dd5..7f0b0a62c 100644 --- a/src/client/java/minicraft/level/tile/BossDoorTile.java +++ b/src/client/java/minicraft/level/tile/BossDoorTile.java @@ -18,7 +18,7 @@ protected BossDoorTile() { super(Material.Obsidian, "Boss Door"); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; @@ -34,7 +34,7 @@ public boolean interact(Level level, int xt, int yt, Player player, Item item, D return false; } - return super.interact(level, xt, yt, player, item, attackDir); + return super.attack(level, xt, yt, player, item, attackDir); } @Override diff --git a/src/client/java/minicraft/level/tile/BossFloorTile.java b/src/client/java/minicraft/level/tile/BossFloorTile.java index b7ac654c5..452545bdb 100644 --- a/src/client/java/minicraft/level/tile/BossFloorTile.java +++ b/src/client/java/minicraft/level/tile/BossFloorTile.java @@ -17,7 +17,7 @@ protected BossFloorTile() { super(Material.Obsidian, "Boss Floor"); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; @@ -33,6 +33,6 @@ public boolean interact(Level level, int xt, int yt, Player player, Item item, D return false; } - return super.interact(level, xt, yt, player, item, attackDir); + return super.attack(level, xt, yt, player, item, attackDir); } } diff --git a/src/client/java/minicraft/level/tile/BossWallTile.java b/src/client/java/minicraft/level/tile/BossWallTile.java index 12d1ea05f..823f73581 100644 --- a/src/client/java/minicraft/level/tile/BossWallTile.java +++ b/src/client/java/minicraft/level/tile/BossWallTile.java @@ -23,7 +23,7 @@ protected BossWallTile() { sprite = obsidian; // Renewing the connectivity. } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; @@ -39,6 +39,6 @@ public boolean interact(Level level, int xt, int yt, Player player, Item item, D return false; } - return super.interact(level, xt, yt, player, item, attackDir); + return super.attack(level, xt, yt, player, item, attackDir); } } diff --git a/src/client/java/minicraft/level/tile/CloudTile.java b/src/client/java/minicraft/level/tile/CloudTile.java index 6503df7c1..3e9dd089a 100644 --- a/src/client/java/minicraft/level/tile/CloudTile.java +++ b/src/client/java/minicraft/level/tile/CloudTile.java @@ -26,7 +26,7 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { // We don't want the tile to break when attacked with just anything, even in creative mode if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; diff --git a/src/client/java/minicraft/level/tile/DecorTile.java b/src/client/java/minicraft/level/tile/DecorTile.java index a40f13f2a..9b584c7c9 100644 --- a/src/client/java/minicraft/level/tile/DecorTile.java +++ b/src/client/java/minicraft/level/tile/DecorTile.java @@ -25,7 +25,7 @@ protected DecorTile(Material type) { maySpawn = true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/DirtTile.java b/src/client/java/minicraft/level/tile/DirtTile.java index 090f19ff4..3c641fba9 100644 --- a/src/client/java/minicraft/level/tile/DirtTile.java +++ b/src/client/java/minicraft/level/tile/DirtTile.java @@ -47,7 +47,7 @@ public void render(Screen screen, Level level, int x, int y) { levelSprite[dIdx(level.depth)].render(screen, level, x, y); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/DoorTile.java b/src/client/java/minicraft/level/tile/DoorTile.java index e01b023cc..84c19deea 100644 --- a/src/client/java/minicraft/level/tile/DoorTile.java +++ b/src/client/java/minicraft/level/tile/DoorTile.java @@ -46,7 +46,7 @@ public void render(Screen screen, Level level, int x, int y) { curSprite.render(screen, level, x, y); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/FloorTile.java b/src/client/java/minicraft/level/tile/FloorTile.java index a3cbd60da..b3e665182 100644 --- a/src/client/java/minicraft/level/tile/FloorTile.java +++ b/src/client/java/minicraft/level/tile/FloorTile.java @@ -27,7 +27,7 @@ protected FloorTile(Material type, String name) { } } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/FlowerTile.java b/src/client/java/minicraft/level/tile/FlowerTile.java index bf09593a0..ff52362f4 100644 --- a/src/client/java/minicraft/level/tile/FlowerTile.java +++ b/src/client/java/minicraft/level/tile/FlowerTile.java @@ -47,7 +47,7 @@ public void render(Screen screen, Level level, int x, int y) { (shape == 0 ? flowerSprite0 : flowerSprite1).render(screen, level, x, y); } - public boolean interact(Level level, int x, int y, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int x, int y, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/GrassTile.java b/src/client/java/minicraft/level/tile/GrassTile.java index 5b14bd396..72b061467 100644 --- a/src/client/java/minicraft/level/tile/GrassTile.java +++ b/src/client/java/minicraft/level/tile/GrassTile.java @@ -46,7 +46,7 @@ public void render(Screen screen, Level level, int x, int y) { sprite.render(screen, level, x, y); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/HardRockTile.java b/src/client/java/minicraft/level/tile/HardRockTile.java index 07c18c4d2..f6eacece0 100644 --- a/src/client/java/minicraft/level/tile/HardRockTile.java +++ b/src/client/java/minicraft/level/tile/HardRockTile.java @@ -38,7 +38,7 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at return true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if(Game.isMode("minicraft.settings.mode.creative")) return false; // Go directly to hurt method if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index 13508f7db..01c62a0f7 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -18,7 +18,7 @@ protected LavaBrickTile(String name) { super(name, new SpriteAnimation(SpriteType.Tile, "missing_tile")); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Pickaxe) { diff --git a/src/client/java/minicraft/level/tile/MaterialTile.java b/src/client/java/minicraft/level/tile/MaterialTile.java index 53df6a95b..494c45d20 100644 --- a/src/client/java/minicraft/level/tile/MaterialTile.java +++ b/src/client/java/minicraft/level/tile/MaterialTile.java @@ -26,7 +26,7 @@ protected MaterialTile(Material type) { } } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/OreTile.java b/src/client/java/minicraft/level/tile/OreTile.java index 2bfe1506a..c47e68d7e 100644 --- a/src/client/java/minicraft/level/tile/OreTile.java +++ b/src/client/java/minicraft/level/tile/OreTile.java @@ -66,7 +66,7 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at return true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if(Game.isMode("minicraft.settings.mode.creative")) return false; // Go directly to hurt method if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/level/tile/PathTile.java b/src/client/java/minicraft/level/tile/PathTile.java index dea91f486..70dfd9b35 100644 --- a/src/client/java/minicraft/level/tile/PathTile.java +++ b/src/client/java/minicraft/level/tile/PathTile.java @@ -21,7 +21,7 @@ public PathTile(String name) { maySpawn = true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/RockTile.java b/src/client/java/minicraft/level/tile/RockTile.java index b5f7e69b7..c981b8c1d 100644 --- a/src/client/java/minicraft/level/tile/RockTile.java +++ b/src/client/java/minicraft/level/tile/RockTile.java @@ -51,7 +51,7 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at return true; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Pickaxe && player.payStamina(5 - tool.level) && tool.payDurability()) { diff --git a/src/client/java/minicraft/level/tile/SandTile.java b/src/client/java/minicraft/level/tile/SandTile.java index 2e2a036f8..807131652 100644 --- a/src/client/java/minicraft/level/tile/SandTile.java +++ b/src/client/java/minicraft/level/tile/SandTile.java @@ -62,7 +62,7 @@ public void steppedOn(Level level, int x, int y, Entity entity) { } } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/StairsTile.java b/src/client/java/minicraft/level/tile/StairsTile.java index 58d07c39c..b4d004e1f 100644 --- a/src/client/java/minicraft/level/tile/StairsTile.java +++ b/src/client/java/minicraft/level/tile/StairsTile.java @@ -37,8 +37,8 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - super.interact(level, xt, yt, player, item, attackDir); + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + super.attack(level, xt, yt, player, item, attackDir); // Makes it so you can remove the stairs if you are in creative and debug mode. if (item instanceof PowerGloveItem && Game.isMode("minicraft.settings.mode.creative")) { diff --git a/src/client/java/minicraft/level/tile/Tile.java b/src/client/java/minicraft/level/tile/Tile.java index fe52cf1e1..034a709a6 100644 --- a/src/client/java/minicraft/level/tile/Tile.java +++ b/src/client/java/minicraft/level/tile/Tile.java @@ -119,6 +119,20 @@ public void steppedOn(Level level, int xt, int yt, Entity entity) {} * @param attackDir The direction of the player attacking. * @return Was the operation successful? */ + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + return false; + } + + /** + * Called when you interact an item on a tile (ex: Pickaxe on rock). + * @param level The level the player is on. + * @param xt X position of the player in tile coordinates (32x per tile). + * @param yt Y position of the player in tile coordinates (32px per tile). + * @param player The player who called this method. + * @param item The item the player is currently holding. + * @param attackDir The direction of the player attacking. + * @return Was the operation successful? + */ public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { return false; } diff --git a/src/client/java/minicraft/level/tile/TorchTile.java b/src/client/java/minicraft/level/tile/TorchTile.java index 52353ac45..aff6bc61f 100644 --- a/src/client/java/minicraft/level/tile/TorchTile.java +++ b/src/client/java/minicraft/level/tile/TorchTile.java @@ -47,7 +47,7 @@ public int getLightRadius(Level level, int x, int y) { return 5; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if(item instanceof PowerGloveItem) { int data = level.getData(xt, yt); level.setTile(xt, yt, this.onType); diff --git a/src/client/java/minicraft/level/tile/TreeTile.java b/src/client/java/minicraft/level/tile/TreeTile.java index 895ad1fd4..b343e2000 100644 --- a/src/client/java/minicraft/level/tile/TreeTile.java +++ b/src/client/java/minicraft/level/tile/TreeTile.java @@ -90,7 +90,7 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at } @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if(Game.isMode("minicraft.settings.mode.creative")) return false; // Go directly to hurt method if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/level/tile/WallTile.java b/src/client/java/minicraft/level/tile/WallTile.java index df986e62a..a14f705e0 100644 --- a/src/client/java/minicraft/level/tile/WallTile.java +++ b/src/client/java/minicraft/level/tile/WallTile.java @@ -56,7 +56,7 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at } } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (Game.isMode("minicraft.settings.mode.creative")) return false; // Go directly to hurt method if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/level/tile/WoolTile.java b/src/client/java/minicraft/level/tile/WoolTile.java index 0de6bc9af..3ba0af1dc 100644 --- a/src/client/java/minicraft/level/tile/WoolTile.java +++ b/src/client/java/minicraft/level/tile/WoolTile.java @@ -19,7 +19,7 @@ public WoolTile(WoolType woolType) { super(woolType.name, woolType.sprite); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shears) { diff --git a/src/client/java/minicraft/level/tile/farming/FarmTile.java b/src/client/java/minicraft/level/tile/farming/FarmTile.java index 770cc0ead..d9c0dc7f9 100644 --- a/src/client/java/minicraft/level/tile/farming/FarmTile.java +++ b/src/client/java/minicraft/level/tile/farming/FarmTile.java @@ -26,7 +26,7 @@ protected FarmTile(String name, SpriteAnimation sprite) { } @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/screen/BookDisplay.java b/src/client/java/minicraft/screen/BookDisplay.java index 0b462add1..3338fa76d 100644 --- a/src/client/java/minicraft/screen/BookDisplay.java +++ b/src/client/java/minicraft/screen/BookDisplay.java @@ -88,7 +88,7 @@ private void turnPage(int dir) { @Override public void tick(InputHandler input) { - if (input.inputPressed("menu") || input.inputPressed("exit")) Game.exitDisplay(); // Close the menu. + if (input.inputPressed("INVENTORY") || input.inputPressed("exit")) Game.exitDisplay(); // Close the menu. if (input.inputPressed("cursor-left")) turnPage(-1); // This is what turns the page back if (input.inputPressed("cursor-right")) turnPage(1); // This is what turns the page forward } diff --git a/src/client/java/minicraft/screen/ContainerDisplay.java b/src/client/java/minicraft/screen/ContainerDisplay.java index 3912f0f93..ddd664484 100644 --- a/src/client/java/minicraft/screen/ContainerDisplay.java +++ b/src/client/java/minicraft/screen/ContainerDisplay.java @@ -20,7 +20,7 @@ public class ContainerDisplay extends Display { public ContainerDisplay(Player player, Chest chest) { super( - new InventoryMenu(player, player.getInventory(), "minicraft.display.menus.inventory", RelPos.LEFT), + new InventoryMenu(player, player.getInventory(), "minicraft.display.menus.inventory", RelPos.LEFT), new InventoryMenu(chest, chest.getInventory(), chest.name, RelPos.RIGHT) ); @@ -44,14 +44,14 @@ public ContainerDisplay(Player player, Chest chest) { @Override protected void onSelectionChange(int oldSel, int newSel) { super.onSelectionChange(oldSel, newSel); - + if (oldSel == newSel) return; // this also serves as a protection against access to menus[0] when such may not exist. - + int shift = 0; - + if (newSel == 0) shift = padding - menus[0].getBounds().getLeft(); if (newSel == 1) shift = (Screen.w - padding) - menus[1].getBounds().getRight(); - + for (Menu m: menus) { m.translate(shift, 0); } @@ -77,7 +77,7 @@ public void tick(InputHandler input) { if (onScreenKeyboardMenu == null || !curMenu.isSearcherBarActive() && !onScreenKeyboardMenu.isVisible()) { super.tick(input); - if (input.inputPressed("menu") || chest.isRemoved()) { + if (input.inputPressed("INVENTORY") || chest.isRemoved()) { Game.setDisplay(null); return; } @@ -95,7 +95,7 @@ public void tick(InputHandler input) { if (!acted) curMenu.tick(input); - if (input.getKey("menu").clicked || chest.isRemoved()) { + if (input.inputPressed("INVENTORY") || input.inputPressed("EXIT") || chest.isRemoved()) { Game.setDisplay(null); return; } diff --git a/src/client/java/minicraft/screen/CraftingDisplay.java b/src/client/java/minicraft/screen/CraftingDisplay.java index 1957c3f62..0d2cd1d6e 100644 --- a/src/client/java/minicraft/screen/CraftingDisplay.java +++ b/src/client/java/minicraft/screen/CraftingDisplay.java @@ -117,7 +117,7 @@ public void tick(InputHandler input) { boolean mainMethod = false; if (onScreenKeyboardMenu == null || !recipeMenu.isSearcherBarActive() && !onScreenKeyboardMenu.isVisible()) { - if (input.inputPressed("menu") || (isPersonalCrafter && input.inputPressed("craft"))) { + if (input.inputPressed("INVENTORY") || (isPersonalCrafter && input.inputPressed("craft"))) { Game.exitDisplay(); return; } @@ -134,7 +134,7 @@ public void tick(InputHandler input) { if (!acted) recipeMenu.tick(input); - if (input.getKey("menu").clicked || (isPersonalCrafter && input.inputPressed("craft"))) { + if (input.inputPressed("INVENTORY") || input.inputPressed("EXIT") || (isPersonalCrafter && input.inputPressed("craft"))) { Game.exitDisplay(); return; } diff --git a/src/client/java/minicraft/screen/PlayerInvDisplay.java b/src/client/java/minicraft/screen/PlayerInvDisplay.java index c152accc1..06c77417b 100644 --- a/src/client/java/minicraft/screen/PlayerInvDisplay.java +++ b/src/client/java/minicraft/screen/PlayerInvDisplay.java @@ -82,7 +82,7 @@ public void tick(InputHandler input) { if (onScreenKeyboardMenu == null || !curMenu.isSearcherBarActive() && !onScreenKeyboardMenu.isVisible()) { super.tick(input); - if (input.inputPressed("menu")) { + if (input.inputPressed("INVENTORY")) { Game.exitDisplay(); return; } @@ -100,7 +100,7 @@ public void tick(InputHandler input) { if (!acted) curMenu.tick(input); - if (input.getKey("menu").clicked) { // Should not listen button press. + if (input.inputPressed("INVENTORY") || input.inputPressed("EXIT")) { // Should not listen button press. Game.exitDisplay(); return; } diff --git a/src/client/java/minicraft/screen/TutorialDisplayHandler.java b/src/client/java/minicraft/screen/TutorialDisplayHandler.java index 184a5fabd..01e5ae3b6 100644 --- a/src/client/java/minicraft/screen/TutorialDisplayHandler.java +++ b/src/client/java/minicraft/screen/TutorialDisplayHandler.java @@ -69,8 +69,8 @@ private static void loadTutorialElement(String criterionName, JSONObject json) { Game.input.getMapping("move-right"))))); controlGuides.add(new ControlGuide(1, "attack", () -> Localization.getLocalized("minicraft.control_guide.attack", Game.input.getMapping("attack")))); - controlGuides.add(new ControlGuide(1, "menu", - () -> Localization.getLocalized("minicraft.control_guide.menu", Game.input.getMapping("menu")))); + controlGuides.add(new ControlGuide(1, "inventory", + () -> Localization.getLocalized("minicraft.control_guide.menu", Game.input.getMapping("INVENTORY")))); controlGuides.add(new ControlGuide(1, "craft", () -> Localization.getLocalized("minicraft.control_guide.craft", Game.input.getMapping("craft")))); } From cc7957b3b6f9f46da99dfd84737cca349aac4a8d Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 4 Aug 2023 16:20:40 +0800 Subject: [PATCH 03/14] Resolve door tile interaction --- .../java/minicraft/level/tile/BossDoorTile.java | 12 +++++------- src/client/java/minicraft/level/tile/DoorTile.java | 10 ++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/client/java/minicraft/level/tile/BossDoorTile.java b/src/client/java/minicraft/level/tile/BossDoorTile.java index 7f0b0a62c..c8c75d365 100644 --- a/src/client/java/minicraft/level/tile/BossDoorTile.java +++ b/src/client/java/minicraft/level/tile/BossDoorTile.java @@ -38,14 +38,12 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - if (source instanceof Player) { - if (ObsidianKnight.active && !Game.isMode("minicraft.settings.mode.creative")) { - Game.notifications.add(doorMsg); - return true; - } + public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + if (ObsidianKnight.active && !Game.isMode("minicraft.settings.mode.creative")) { + Game.notifications.add(doorMsg); + return true; } - return super.hurt(level, x, y, source, dmg, attackDir); + return super.interact(level, xt, yt, player, item, attackDir); } } diff --git a/src/client/java/minicraft/level/tile/DoorTile.java b/src/client/java/minicraft/level/tile/DoorTile.java index 84c19deea..e1a81065b 100644 --- a/src/client/java/minicraft/level/tile/DoorTile.java +++ b/src/client/java/minicraft/level/tile/DoorTile.java @@ -65,12 +65,10 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - if (source instanceof Player) { - boolean closed = level.getData(x, y) == 0; - level.setData(x, y, closed ? 1 : 0); - } - return false; + public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + boolean closed = level.getData(xt, yt) == 0; + level.setData(xt, yt, closed ? 1 : 0); + return true; } public boolean mayPass(Level level, int x, int y, Entity e) { From 7967cfca16b04a540f662e6835910ee07c825c58 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 4 Aug 2023 16:22:08 +0800 Subject: [PATCH 04/14] Update Item.java --- src/client/java/minicraft/item/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/java/minicraft/item/Item.java b/src/client/java/minicraft/item/Item.java index bfea42c1c..5e42956f4 100644 --- a/src/client/java/minicraft/item/Item.java +++ b/src/client/java/minicraft/item/Item.java @@ -37,7 +37,7 @@ public void renderHUD(Screen screen, int x, int y, int fontColor) { Font.drawBackground(dispName, screen, x + 8, y, fontColor); } - /** Determines what happens when the player attacks with a tile */ + /** Determines what happens when the player attacks a tile */ public boolean attackOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { return false; } From 100e07857467661053367ca6e9baa16fca4d0a3c Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Fri, 4 Aug 2023 19:33:47 +0800 Subject: [PATCH 05/14] Change some attack input into select --- .../java/minicraft/entity/mob/Player.java | 21 ++++++++++--------- .../minicraft/screen/ContainerDisplay.java | 2 +- .../minicraft/screen/CraftingDisplay.java | 2 +- .../minicraft/screen/PlayerInvDisplay.java | 6 +++--- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index 010a3db35..d1fb88438 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -526,12 +526,12 @@ public void tick() { } if (Game.getDisplay() == null) { - if (input.inputPressed("INVENTORY")) + if (input.inputPressed("craft")) // obtain SHIFT modifier input with E + Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); + else if (input.inputPressed("INVENTORY")) Game.setDisplay(new PlayerInvDisplay(this)); if (input.inputPressed("pause")) Game.setDisplay(new PauseDisplay()); - if (input.inputPressed("craft")) - Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); if (input.inputPressed("QUICK-SAVE") && !Updater.saving) { Updater.saving = true; @@ -601,14 +601,15 @@ protected void attack() { attackDir = dir; // Make the attack direction equal the current direction attackItem = activeItem; // Make attackItem equal activeItem + attackTime = 10; + + // If the interaction between you and an entity is successful, then return. + if (attack(getInteractionBox(INTERACT_DIST))) return; + // If we are holding an item. if (activeItem != null) { - attackTime = 10; boolean done = false; - // If the interaction between you and an entity is successful, then return. - if (attack(getInteractionBox(INTERACT_DIST))) return; - // Attempt to interact with the tile. Point t = getInteractionTile(); @@ -677,13 +678,13 @@ protected void interact() { } } + // If the interaction between you and an entity is successful, then return. + if (interact(getInteractionBox(INTERACT_DIST))) return; + // If we are holding an item. if (activeItem != null) { boolean done = false; - // If the interaction between you and an entity is successful, then return. - if (interact(getInteractionBox(INTERACT_DIST))) return; - // Attempt to interact with the tile. Point t = getInteractionTile(); diff --git a/src/client/java/minicraft/screen/ContainerDisplay.java b/src/client/java/minicraft/screen/ContainerDisplay.java index ddd664484..b91d7b14a 100644 --- a/src/client/java/minicraft/screen/ContainerDisplay.java +++ b/src/client/java/minicraft/screen/ContainerDisplay.java @@ -110,7 +110,7 @@ public void tick(InputHandler input) { } if (mainMethod || !onScreenKeyboardMenu.isVisible()) - if (input.inputPressed("attack") || input.getKey("shift-enter").clicked) { + if (input.inputPressed("SELECT") || input.getKey("shift-enter").clicked) { if (curMenu.getEntries().length == 0) return; // switch inventories diff --git a/src/client/java/minicraft/screen/CraftingDisplay.java b/src/client/java/minicraft/screen/CraftingDisplay.java index 0d2cd1d6e..75f6d7d1d 100644 --- a/src/client/java/minicraft/screen/CraftingDisplay.java +++ b/src/client/java/minicraft/screen/CraftingDisplay.java @@ -155,7 +155,7 @@ public void tick(InputHandler input) { refreshData(); } - if ((input.inputPressed("select") || input.inputPressed("attack")) && recipeMenu.getSelection() >= 0) { + if ((input.inputPressed("select")) && recipeMenu.getSelection() >= 0) { // check the selected recipe if (recipes.length == 0) return; Recipe selectedRecipe = recipes[recipeMenu.getSelection()]; diff --git a/src/client/java/minicraft/screen/PlayerInvDisplay.java b/src/client/java/minicraft/screen/PlayerInvDisplay.java index 06c77417b..cb7ffa050 100644 --- a/src/client/java/minicraft/screen/PlayerInvDisplay.java +++ b/src/client/java/minicraft/screen/PlayerInvDisplay.java @@ -122,7 +122,7 @@ public void tick(InputHandler input) { Inventory from, to; if (selection == 0) { - if (input.inputPressed("attack") && menus[0].getNumOptions() > 0) { + if (input.inputPressed("SELECT") && menus[0].getNumOptions() > 0) { player.activeItem = player.getInventory().remove(menus[0].getSelection()); Game.exitDisplay(); return; @@ -159,7 +159,7 @@ public void tick(InputHandler input) { Item fromItem = from.get(fromSel); boolean transferAll; - if (input.inputPressed("attack")) { // If stack limit is available, this can transfer whole stack + if (input.inputPressed("SELECT")) { // If stack limit is available, this can transfer whole stack transferAll = !(fromItem instanceof StackableItem) || ((StackableItem)fromItem).count == 1; } else return; @@ -174,7 +174,7 @@ public void tick(InputHandler input) { } } else { - if (input.inputPressed("attack") && menus[0].getNumOptions() > 0) { + if (input.inputPressed("SELECT") && menus[0].getNumOptions() > 0) { player.activeItem = player.getInventory().remove(menus[0].getSelection()); Game.exitDisplay(); } From 59b40352756739c64e39b2b17cc9c3b3edc24ad4 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sun, 4 Aug 2024 05:46:03 +0800 Subject: [PATCH 06/14] Resolve post-merge errors --- src/client/java/minicraft/entity/furniture/Composter.java | 2 +- src/client/java/minicraft/entity/furniture/Tnt.java | 2 +- src/client/java/minicraft/entity/mob/Player.java | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/client/java/minicraft/entity/furniture/Composter.java b/src/client/java/minicraft/entity/furniture/Composter.java index 079d90795..700f51a7b 100644 --- a/src/client/java/minicraft/entity/furniture/Composter.java +++ b/src/client/java/minicraft/entity/furniture/Composter.java @@ -22,7 +22,7 @@ public Composter() { } @Override - public boolean interact(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Player player, @Nullable Item item, Direction attackDir) { if (compost == MAX_COMPOST) { compost = 0; StackableItem i = (StackableItem) Items.get("Fertilizer").copy(); diff --git a/src/client/java/minicraft/entity/furniture/Tnt.java b/src/client/java/minicraft/entity/furniture/Tnt.java index 91a20cc19..428483a53 100644 --- a/src/client/java/minicraft/entity/furniture/Tnt.java +++ b/src/client/java/minicraft/entity/furniture/Tnt.java @@ -102,7 +102,7 @@ public void render(Screen screen) { public boolean attack(Player player, Item heldItem, Direction attackDir) { if (heldItem instanceof PowerGloveItem) { if (!fuseLit) { - return super.interact(player, heldItem, attackDir); + return super.attack(player, heldItem, attackDir); } } else { if (!fuseLit) { diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index 69f86b8b3..f3c8ddde0 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -47,6 +47,7 @@ import minicraft.saveload.Save; import minicraft.screen.AchievementsDisplay; import minicraft.screen.CraftingDisplay; +import minicraft.screen.InfoDisplay; import minicraft.screen.LoadingDisplay; import minicraft.screen.PauseDisplay; import minicraft.screen.PlayerInvDisplay; @@ -531,10 +532,10 @@ public void tick() { } if (Game.getDisplay() == null) { - if (input.inputPressed("craft") && !use()) { // obtain SHIFT modifier input with E + if (input.inputPressed("craft") && !interact(getInteractionBox(INTERACT_DIST))) { // obtain SHIFT modifier input with E Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); return; - } else if (input.inputPressed("menu") && !use()) { // !use() = no furniture in front of the player; this prevents player inventory from opening (will open furniture inventory instead) + } else if (input.inputPressed("menu") && !interact(getInteractionBox(INTERACT_DIST))) { // !use() = no furniture in front of the player; this prevents player inventory from opening (will open furniture inventory instead) Game.setDisplay(new PlayerInvDisplay(this)); return; } else if (input.inputPressed("pause")) { @@ -688,7 +689,7 @@ protected void interact() { } if (activeItem != null && !activeItem.interactsWithWorld()) { - if (activeItem.interactOn(Tiles.get(0), level, x >> 4, y >> 4, this, attackDir)) { + if (activeItem.interactOn(Tiles.get((short) 0), level, x >> 4, y >> 4, this, attackDir)) { if (activeItem.isDepleted()) { activeItem = null; if (isFishing) { From 3790fe71e543956c3cd12010ecc9590a5d4b0542 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Mon, 5 Aug 2024 05:19:18 +0800 Subject: [PATCH 07/14] Tidy up interact keys --- src/client/java/minicraft/core/io/InputHandler.java | 4 ++-- src/client/java/minicraft/entity/mob/Player.java | 12 ++++++------ src/client/java/minicraft/item/Item.java | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/client/java/minicraft/core/io/InputHandler.java b/src/client/java/minicraft/core/io/InputHandler.java index 97a97dcfb..f9f7b0b40 100644 --- a/src/client/java/minicraft/core/io/InputHandler.java +++ b/src/client/java/minicraft/core/io/InputHandler.java @@ -151,7 +151,7 @@ private void initKeyMap() { keymap.put("QUICK-SAVE", "R"); // Saves the game while still playing keymap.put("ATTACK", "C|SPACE"); // Attack/destroy action references "C" key - keymap.put("INTERACT", "X|ENTER"); // Interact action references "X" key (formerly "menu") + keymap.put("USE", "X|ENTER"); // Use action references "X" key (formerly "menu") keymap.put("INVENTORY", "E"); // Open/close player inventory menu and exit action of some displays. keymap.put("CRAFT", "Z|SHIFT-E"); // Open/close personal crafting window. keymap.put("PICKUP", "V|P"); // Pickup torches / furniture; this replaces the power glove. @@ -194,7 +194,7 @@ private void initButtonMap() { buttonMap.put("EXIT", ControllerButton.B); buttonMap.put("ATTACK", ControllerButton.A); - buttonMap.put("INTERACT", ControllerButton.B); + buttonMap.put("USE", ControllerButton.B); buttonMap.put("INVENTORY", ControllerButton.X); buttonMap.put("CRAFT", ControllerButton.Y); buttonMap.put("PICKUP", ControllerButton.LEFTSTICK); diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index f3c8ddde0..dd9018fab 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -507,14 +507,14 @@ public void tick() { level.dropItem(x, y, drop); } - if ((activeItem == null || !activeItem.used_pending) && (input.inputPressed("attack")) && stamina != 0 && onFallDelay <= 0) { // This only allows attacks when such action is possible. + if ((activeItem == null) && (input.inputPressed("attack")) && stamina != 0 && onFallDelay <= 0) { // This only allows attacks when such action is possible. if (!potioneffects.containsKey(PotionType.Energy)) stamina--; staminaRecharge = 0; attack(); } - if ((activeItem == null || !activeItem.used_pending) && (input.inputPressed("interact")) && stamina != 0 && onFallDelay <= 0) { // This only allows interactions when such action is possible. + if ((activeItem == null) && (input.inputPressed("USE")) && stamina != 0 && onFallDelay <= 0) { // This only allows interactions when such action is possible. if (!potioneffects.containsKey(PotionType.Energy)) stamina--; staminaRecharge = 0; @@ -532,10 +532,10 @@ public void tick() { } if (Game.getDisplay() == null) { - if (input.inputPressed("craft") && !interact(getInteractionBox(INTERACT_DIST))) { // obtain SHIFT modifier input with E + if (input.inputPressed("craft")) { // obtain SHIFT modifier input with E Game.setDisplay(new CraftingDisplay(Recipes.craftRecipes, "minicraft.displays.crafting", this, true)); return; - } else if (input.inputPressed("menu") && !interact(getInteractionBox(INTERACT_DIST))) { // !use() = no furniture in front of the player; this prevents player inventory from opening (will open furniture inventory instead) + } else if (input.inputPressed("INVENTORY")) { Game.setDisplay(new PlayerInvDisplay(this)); return; } else if (input.inputPressed("pause")) { @@ -546,7 +546,7 @@ public void tick() { return; } - if (input.inputDown("quicksave") && !Updater.saving) { + if (input.inputDown("QUICK-SAVE") && !Updater.saving) { Updater.saving = true; LoadingDisplay.setPercentage(0); new Save(WorldSelectDisplay.getWorldName()); @@ -558,7 +558,7 @@ public void tick() { } } - if (input.inputPressed("pickup") && (activeItem == null || !activeItem.used_pending)) { + if (input.inputPressed("pickup") && (activeItem == null)) { if (!(activeItem instanceof PowerGloveItem)) { // If you are not already holding a power glove (aka in the middle of a separate interaction)... prevItem = activeItem; // Then save the current item... if (isFishing) { diff --git a/src/client/java/minicraft/item/Item.java b/src/client/java/minicraft/item/Item.java index 3daa32eff..3a48608f1 100644 --- a/src/client/java/minicraft/item/Item.java +++ b/src/client/java/minicraft/item/Item.java @@ -19,7 +19,7 @@ public abstract class Item { private final String name; public LinkedSprite sprite; - public boolean used_pending = false; // This is for multiplayer, when an item has been used, and is pending server response as to the outcome, this is set to true so it cannot be used again unless the server responds that the item wasn't used. Which should basically replace the item anyway, soo... yeah. this never gets set back. +// public boolean used_pending = false; // This is for multiplayer, when an item has been used, and is pending server response as to the outcome, this is set to true so it cannot be used again unless the server responds that the item wasn't used. Which should basically replace the item anyway, soo... yeah. this never gets set back. protected Item(String name) { sprite = SpriteLinker.missingTexture(SpriteType.Item); From ffda41c1898559352590c117aa6e1e7d24fbee5b Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sat, 10 Aug 2024 06:18:14 +0800 Subject: [PATCH 08/14] Reorganize entity interaction methods --- src/client/java/minicraft/entity/Arrow.java | 25 ++++- .../java/minicraft/entity/Direction.java | 4 + src/client/java/minicraft/entity/Entity.java | 86 ++++++++++++++++- .../minicraft/entity/ExplosionTileTicker.java | 20 ++++ .../java/minicraft/entity/FireSpark.java | 22 +++++ .../java/minicraft/entity/ItemEntity.java | 21 ++++ src/client/java/minicraft/entity/Spark.java | 24 ++++- .../java/minicraft/entity/furniture/Bed.java | 5 +- .../minicraft/entity/furniture/Chest.java | 12 +-- .../minicraft/entity/furniture/Composter.java | 2 +- .../minicraft/entity/furniture/Crafter.java | 5 +- .../entity/furniture/DeathChest.java | 8 +- .../entity/furniture/DungeonChest.java | 12 +-- .../minicraft/entity/furniture/Furniture.java | 44 +++++---- .../entity/furniture/KnightStatue.java | 2 +- .../minicraft/entity/furniture/Spawner.java | 36 +++---- .../java/minicraft/entity/furniture/Tnt.java | 24 ++--- .../java/minicraft/entity/mob/AirWizard.java | 8 +- .../java/minicraft/entity/mob/Creeper.java | 5 +- .../java/minicraft/entity/mob/EnemyMob.java | 20 +++- src/client/java/minicraft/entity/mob/Mob.java | 95 ++++++++----------- .../java/minicraft/entity/mob/MobAi.java | 20 ---- .../minicraft/entity/mob/ObsidianKnight.java | 25 +++-- .../java/minicraft/entity/mob/PassiveMob.java | 19 ++++ .../java/minicraft/entity/mob/Player.java | 45 ++++----- .../java/minicraft/entity/mob/Sheep.java | 4 +- .../java/minicraft/entity/mob/Snake.java | 2 +- .../minicraft/entity/particle/Particle.java | 23 +++++ .../java/minicraft/level/tile/CactusTile.java | 12 +-- .../minicraft/level/tile/LavaBrickTile.java | 2 +- .../level/tile/entity/SignTileEntity.java | 23 +++++ 31 files changed, 453 insertions(+), 202 deletions(-) diff --git a/src/client/java/minicraft/entity/Arrow.java b/src/client/java/minicraft/entity/Arrow.java index 8b565c286..8de70fa49 100644 --- a/src/client/java/minicraft/entity/Arrow.java +++ b/src/client/java/minicraft/entity/Arrow.java @@ -7,7 +7,11 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; import minicraft.util.Logging; +import org.jetbrains.annotations.Nullable; import javax.security.auth.DestroyFailedException; @@ -71,8 +75,7 @@ public void tick() { if (hit instanceof Mob && hit != owner) { Mob mob = (Mob) hit; damage += (hit instanceof Player ? 0 : 3) + (criticalHit ? 0 : 1); // Extra damage bonus. - damage = mob.calculateEntityDamage(this, damage); - mob.hurt(owner, damage, dir); //normal hurting to other mobs + mob.attack(owner, null, dir, damage); // normal hurting to other mobs } if (!level.getTile(x >> 4, y >> 4).mayPass(level, x >> 4, y >> 4, this) @@ -92,6 +95,24 @@ public boolean isSolid() { return false; } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + @Override public void render(Screen screen) { screen.render(x - 4, y - 4, sprite); diff --git a/src/client/java/minicraft/entity/Direction.java b/src/client/java/minicraft/entity/Direction.java index 291be85f9..dc00b47a1 100644 --- a/src/client/java/minicraft/entity/Direction.java +++ b/src/client/java/minicraft/entity/Direction.java @@ -46,4 +46,8 @@ public static Direction getDirection(int dir) { public int getDir() { return ordinal() - 1; } + + public Direction getOpposite() { + return Direction.getDirection(getDir() ^ 0b11); + } } diff --git a/src/client/java/minicraft/entity/Entity.java b/src/client/java/minicraft/entity/Entity.java index 080549f87..9cdfd55e3 100644 --- a/src/client/java/minicraft/entity/Entity.java +++ b/src/client/java/minicraft/entity/Entity.java @@ -7,6 +7,7 @@ import minicraft.gfx.Screen; import minicraft.item.Item; import minicraft.level.Level; +import minicraft.level.tile.Tile; import minicraft.network.Network; import minicraft.util.Logging; import org.jetbrains.annotations.Nullable; @@ -141,17 +142,96 @@ public int getLightRadius() { protected void touchedBy(Entity entity) { } + /** + * The amount of damage to attack when the item has no damage attribute set. + * @return amount of damage by fists + */ + protected int baseDamage() { + return 1; + } + + /** + * An indicator for which the entity is attackable by certain entity, even under certain conditions. + * This is invoked each time an entity is being targetted regardless it is interacted. + * Most probably used by Player. + * @return {@code false} if not attackable and {@link #attack(Entity, Item, Direction, int)} would not be invoked + * when triggered. + */ + public abstract boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir); + + /** + * An indicator for which the entity is attackable by certain entity, even under certain conditions. + * This is invoked each time an entity is being targetted regardless it is interacted. + * Most probably used by Player. + * Though the usefulness of this is doubtable. + * @return {@code false} if not attackable and {@link #attack(Tile, Level, int, int, Direction, int)} would not be + * invoked when triggered. + */ + public abstract boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir); + + /** + * An indicator for which the entity is attackable by certain entity, even under certain conditions. + * This is invoked each time an entity is being targetted regardless it is interacted. + * Most probably used by Player. + * @return {@code false} if not attackable and {@link #attack(Entity, Item, Direction, int)} would not be invoked + * when triggered. + */ + public abstract boolean isUsable(); + + // TODO Here, attackDir may be changed to use an angle instead of axis to perform more accurate actions. + /** * Attacks the entity this method is called on - * @param player The player attacking + * @param source The entity attacking * @param item The item the player attacked with * @param attackDir The direction to interact + * @param damage The amount of damage intended to emit this time * @return If the interaction was successful */ - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { + public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { return false; } + /** + * Attacks the entity this method is called on (coordinates in tile coordinates) + * @param source The entity attacking + * @param attackDir The direction to interact + * @param damage The amount of damage intended to emit this time + * @return If the interaction was successful + */ + public boolean attack(Tile source, Level level, int x, int y, Direction attackDir, int damage) { + return false; + } + + /** + * Hurt the entity directly, based on only damage and a direction + * Usually this is invoked by {@link #attack(Entity, Item, Direction, int)} and + * {@link #attack(Tile, Level, int, int, Direction, int)} + * @param damage The amount of damage to hurt the entity with + * @param attackDir The direction this entity was attacked from + */ + protected abstract void hurt(int damage, Direction attackDir); // TODO damage type + + public static Direction getInteractionDir(Entity attacker, Entity hurt) { + return Direction.getDirection(hurt.x - attacker.x, hurt.y - attacker.y); + } + + /** + * Called when the player presses the USE key in front of this. + */ + public boolean use(Player player, @Nullable Item item, Direction attackDir) { + return false; + } + + /** + * Picks up this entity + * @param player The player interacting + * @return the item picked up; {@code null} if picking up failed + */ + public @Nullable Item take(Player player) { + return null; + } + /** * Moves an entity horizontally and vertically. Returns whether entity was unimpeded in it's movement. */ @@ -309,7 +389,7 @@ public void handleDespawn() { /** * This exists as a way to signify that the entity has been removed through player action and/or world action; basically, it's actually gone, not just removed from a level because it's out of range or something. Calls to this method are used to, say, drop items. */ - public void die() { + public void die() { // TODO damage type remove(); } diff --git a/src/client/java/minicraft/entity/ExplosionTileTicker.java b/src/client/java/minicraft/entity/ExplosionTileTicker.java index 5331a82f4..5ecec57fa 100644 --- a/src/client/java/minicraft/entity/ExplosionTileTicker.java +++ b/src/client/java/minicraft/entity/ExplosionTileTicker.java @@ -1,10 +1,12 @@ package minicraft.entity; import minicraft.gfx.Screen; +import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.ExplodedTile; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import org.jetbrains.annotations.Nullable; // This is a kind of tile entity. Maybe this should be savable. public class ExplosionTileTicker extends Entity { @@ -53,4 +55,22 @@ public void tick() { tick++; } + + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} } diff --git a/src/client/java/minicraft/entity/FireSpark.java b/src/client/java/minicraft/entity/FireSpark.java index 6a67764de..2e229f9c7 100644 --- a/src/client/java/minicraft/entity/FireSpark.java +++ b/src/client/java/minicraft/entity/FireSpark.java @@ -6,6 +6,10 @@ import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; +import org.jetbrains.annotations.Nullable; public class FireSpark extends Entity { private static final SpriteLinker.LinkedSprite sprite = new SpriteLinker.LinkedSprite(SpriteLinker.SpriteType.Entity, "spark"); @@ -82,6 +86,24 @@ public boolean isSolid() { return false; } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + @Override public void render(Screen screen) { int randmirror = 0; diff --git a/src/client/java/minicraft/entity/ItemEntity.java b/src/client/java/minicraft/entity/ItemEntity.java index f12622bf1..5cfca0f85 100644 --- a/src/client/java/minicraft/entity/ItemEntity.java +++ b/src/client/java/minicraft/entity/ItemEntity.java @@ -4,6 +4,9 @@ import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -145,6 +148,24 @@ protected void touchedBy(Entity entity) { } } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + @Override protected List getDataPrints() { List prints = super.getDataPrints(); diff --git a/src/client/java/minicraft/entity/Spark.java b/src/client/java/minicraft/entity/Spark.java index 049d45d88..5be2d867d 100644 --- a/src/client/java/minicraft/entity/Spark.java +++ b/src/client/java/minicraft/entity/Spark.java @@ -7,6 +7,10 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; +import org.jetbrains.annotations.Nullable; public class Spark extends Entity { private final int lifeTime; // How much time until the spark disappears @@ -51,7 +55,7 @@ public void tick() { Player player = getClosestPlayer(); if (player != null && player.isWithin(0, this)) { - player.hurt(owner, 1); + player.attack(owner, null, getInteractionDir(this, player), 1); } } @@ -62,6 +66,24 @@ public boolean isSolid() { return false; } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + @Override public void render(Screen screen) { int randmirror = 0; diff --git a/src/client/java/minicraft/entity/furniture/Bed.java b/src/client/java/minicraft/entity/furniture/Bed.java index 159ad294b..7193148a2 100644 --- a/src/client/java/minicraft/entity/furniture/Bed.java +++ b/src/client/java/minicraft/entity/furniture/Bed.java @@ -3,10 +3,13 @@ import minicraft.core.Game; import minicraft.core.Updater; import minicraft.core.io.Localization; +import minicraft.entity.Direction; import minicraft.entity.mob.Player; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -25,7 +28,7 @@ public Bed() { /** * Called when the player attempts to get in bed. */ - public boolean interact(Player player) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { if (checkCanSleep(player)) { // If it is late enough in the day to sleep... // Set the player spawn coord. to their current position, in tile coords (hence " >> 4") diff --git a/src/client/java/minicraft/entity/furniture/Chest.java b/src/client/java/minicraft/entity/furniture/Chest.java index 4c6ac1b0c..3e8209e5f 100644 --- a/src/client/java/minicraft/entity/furniture/Chest.java +++ b/src/client/java/minicraft/entity/furniture/Chest.java @@ -39,10 +39,8 @@ public Chest(String name, LinkedSprite itemSprite) { inventory = new Inventory(); // Initialize the inventory. } - /** - * This is what occurs when the player uses the "Interact" command near this - */ - public boolean interact(Player player) { + @Override + public boolean use(Player player, @Nullable Item item, Direction attackDir) { Game.setDisplay(new ContainerDisplay(player, this)); return true; } @@ -70,10 +68,10 @@ public void populateInvRandom(Random random, String lootTable, @SuppressWarnings } @Override - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { + public @Nullable Item take(Player player) { if (inventory.invSize() == 0) - return super.attack(player, item, attackDir); - return false; + return super.take(player); + return null; // TODO a state that the item cannot be put into inventory } @Override diff --git a/src/client/java/minicraft/entity/furniture/Composter.java b/src/client/java/minicraft/entity/furniture/Composter.java index 700f51a7b..d6e2374c6 100644 --- a/src/client/java/minicraft/entity/furniture/Composter.java +++ b/src/client/java/minicraft/entity/furniture/Composter.java @@ -22,7 +22,7 @@ public Composter() { } @Override - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { if (compost == MAX_COMPOST) { compost = 0; StackableItem i = (StackableItem) Items.get("Fertilizer").copy(); diff --git a/src/client/java/minicraft/entity/furniture/Crafter.java b/src/client/java/minicraft/entity/furniture/Crafter.java index badc6ce61..6d00c43ac 100644 --- a/src/client/java/minicraft/entity/furniture/Crafter.java +++ b/src/client/java/minicraft/entity/furniture/Crafter.java @@ -1,13 +1,16 @@ package minicraft.entity.furniture; import minicraft.core.Game; +import minicraft.entity.Direction; import minicraft.entity.mob.Player; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.item.Recipe; import minicraft.item.Recipes; import minicraft.screen.CraftingDisplay; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -49,7 +52,7 @@ public Crafter(Crafter.Type type) { this.type = type; } - public boolean interact(Player player) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { Game.setDisplay(new CraftingDisplay(type.recipes, type.name(), player)); return true; } diff --git a/src/client/java/minicraft/entity/furniture/DeathChest.java b/src/client/java/minicraft/entity/furniture/DeathChest.java index 12503781c..dc648e32f 100644 --- a/src/client/java/minicraft/entity/furniture/DeathChest.java +++ b/src/client/java/minicraft/entity/furniture/DeathChest.java @@ -4,6 +4,7 @@ import minicraft.core.Updater; import minicraft.core.io.Localization; import minicraft.core.io.Settings; +import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.Color; @@ -13,7 +14,7 @@ import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Inventory; import minicraft.item.Item; -import minicraft.item.StackableItem; +import org.jetbrains.annotations.Nullable; public class DeathChest extends Chest { private static LinkedSprite normalSprite = new LinkedSprite(SpriteType.Entity, "chest"); @@ -91,13 +92,10 @@ public void render(Screen screen) { Font.draw(timeString, screen, x - Font.textWidth(timeString) / 2, y - Font.textHeight() - getBounds().getHeight() / 2, Color.WHITE); } - public boolean interact(Player player) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { return false; } // can't open it, just walk into it. - public void take(Player player) { - } // can't grab a death chest. - @Override public void touchedBy(Entity other) { if (other instanceof Player) { diff --git a/src/client/java/minicraft/entity/furniture/DungeonChest.java b/src/client/java/minicraft/entity/furniture/DungeonChest.java index dd9605dce..d57d9bb61 100644 --- a/src/client/java/minicraft/entity/furniture/DungeonChest.java +++ b/src/client/java/minicraft/entity/furniture/DungeonChest.java @@ -46,7 +46,7 @@ public DungeonChest(@Nullable Random random, boolean unlocked) { return new DungeonChest(null, !this.isLocked); } - public boolean interact(Player player) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { if (isLocked) { boolean activeKey = player.activeItem != null && player.activeItem.equals(Items.get("Key")); boolean invKey = player.getInventory().count(Items.get("key")) > 0; @@ -71,11 +71,11 @@ public boolean interact(Player player) { level.dropItem(x, y, 5, Items.get("Gold Apple")); } - return super.interact(player); // the player unlocked the chest. + return super.use(player, item, attackDir); // the player unlocked the chest. } return false; // the chest is locked, and the player has no key. - } else return super.interact(player); // the chest was already unlocked. + } else return super.use(player, item, attackDir); // the chest was already unlocked. } /** @@ -110,9 +110,9 @@ protected void touchedBy(Entity entity) { } @Override - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { + public @Nullable Item take(Player player) { if (!isLocked) - return super.attack(player, item, attackDir); - return false; + return super.take(player); + return null; } } diff --git a/src/client/java/minicraft/entity/furniture/Furniture.java b/src/client/java/minicraft/entity/furniture/Furniture.java index 55f6b4fdd..2398b1e60 100644 --- a/src/client/java/minicraft/entity/furniture/Furniture.java +++ b/src/client/java/minicraft/entity/furniture/Furniture.java @@ -8,7 +8,8 @@ import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.item.FurnitureItem; import minicraft.item.Item; -import minicraft.item.PowerGloveItem; +import minicraft.level.Level; +import minicraft.level.tile.Tile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -76,13 +77,6 @@ public void render(Screen screen) { screen.render(x - 8, y - 8, sprite); } - /** - * Called when the player presses the INTERACT key in front of this. - */ - public boolean interact(Player player) { - return false; - } - @Override public boolean blocks(Entity e) { return true; // Furniture blocks all entities, even non-solid ones like arrows. @@ -94,21 +88,33 @@ protected void touchedBy(Entity entity) { tryPush((Player) entity); } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return true; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return true; + } + + @Override + public boolean isUsable() { + return true; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + /** - * Used in PowerGloveItem.java to let the user pick up furniture. + * Lets the user pick up furniture. * @param player The player picking up the furniture. */ @Override - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { - if (item instanceof PowerGloveItem) { - Sound.play("monsterhurt"); - remove(); - if (player.activeItem != null && !(player.activeItem instanceof PowerGloveItem)) - player.getLevel().dropItem(player.x, player.y, player.activeItem); // Put whatever item the player is holding into their inventory - player.activeItem = new FurnitureItem(this); // Make this the player's current item. - return true; - } - return false; + public @Nullable Item take(Player player) { + Sound.play("monsterhurt"); + remove(); + return new FurnitureItem(this); } /** diff --git a/src/client/java/minicraft/entity/furniture/KnightStatue.java b/src/client/java/minicraft/entity/furniture/KnightStatue.java index 181b1aaca..044c0020f 100644 --- a/src/client/java/minicraft/entity/furniture/KnightStatue.java +++ b/src/client/java/minicraft/entity/furniture/KnightStatue.java @@ -19,7 +19,7 @@ public KnightStatue(int health) { } @Override - public boolean attack(Player player, Item heldItem, Direction attackDir) { + public boolean use(Player player, Item heldItem, Direction attackDir) { if (!ObsidianKnight.active) { if (touches == 0) { // Touched the first time. Game.notifications.add(Localization.getLocalized("minicraft.notifications.statue_tapped")); diff --git a/src/client/java/minicraft/entity/furniture/Spawner.java b/src/client/java/minicraft/entity/furniture/Spawner.java index b003114b4..229d5cbdf 100644 --- a/src/client/java/minicraft/entity/furniture/Spawner.java +++ b/src/client/java/minicraft/entity/furniture/Spawner.java @@ -4,6 +4,7 @@ import minicraft.core.Updater; import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Cow; import minicraft.entity.mob.Creeper; import minicraft.entity.mob.EnemyMob; @@ -29,6 +30,7 @@ import minicraft.item.ToolItem; import minicraft.item.ToolType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; import java.util.ArrayList; @@ -173,22 +175,20 @@ private void trySpawn() { } @Override - public boolean attack(Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { - ToolItem tool = (ToolItem) item; + public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (source instanceof Player) { Sound.play("monsterhurt"); - int dmg; + int dmg = 1; if (Game.isMode("minicraft.settings.mode.creative")) dmg = health; - else { + else if (item instanceof ToolItem) { + ToolItem tool = (ToolItem) item; dmg = tool.level + random.nextInt(2); - if (tool.type == ToolType.Pickaxe) dmg += random.nextInt(5) + 2; - - if (player.potioneffects.containsKey(PotionType.Haste)) + if (((Player) source).potioneffects.containsKey(PotionType.Haste)) dmg *= 2; } @@ -197,27 +197,27 @@ public boolean attack(Player player, Item item, Direction attackDir) { if (health <= 0) { level.remove(this); Sound.play("death"); - player.addScore(500); + ((Player) source).addScore(500); } return true; } - if (item instanceof PowerGloveItem && Game.isMode("minicraft.settings.mode.creative")) { + return false; + } + + @Override + public @Nullable Item take(Player player) { + if (Game.isMode("minicraft.settings.mode.creative")) { level.remove(this); - if (!(player.activeItem instanceof PowerGloveItem)) - player.getLevel().dropItem(player.x, player.y, player.activeItem); - player.activeItem = new FurnitureItem(this); - return true; + return new FurnitureItem(this); } - if (item == null) return interact(player); - - return false; + return null; } @Override - public boolean interact(Player player) { + public boolean use(Player player, @Nullable Item item, Direction attackDir) { if (Game.isMode("minicraft.settings.mode.creative") && mob instanceof EnemyMob) { lvl++; if (lvl > maxMobLevel) lvl = 1; diff --git a/src/client/java/minicraft/entity/furniture/Tnt.java b/src/client/java/minicraft/entity/furniture/Tnt.java index 428483a53..1fae2aa69 100644 --- a/src/client/java/minicraft/entity/furniture/Tnt.java +++ b/src/client/java/minicraft/entity/furniture/Tnt.java @@ -17,6 +17,7 @@ import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; import minicraft.screen.AchievementsDisplay; +import org.jetbrains.annotations.Nullable; import javax.swing.Timer; @@ -99,17 +100,18 @@ public void render(Screen screen) { } @Override - public boolean attack(Player player, Item heldItem, Direction attackDir) { - if (heldItem instanceof PowerGloveItem) { - if (!fuseLit) { - return super.attack(player, heldItem, attackDir); - } - } else { - if (!fuseLit) { - fuseLit = true; - Sound.play("fuse"); - return true; - } + public @Nullable Item take(Player player) { + if (!fuseLit) + return super.take(player); + return null; + } + + @Override + public boolean use(Player player, @Nullable Item item, Direction attackDir) { + if (!fuseLit) { + fuseLit = true; + Sound.play("fuse"); + return true; } return false; diff --git a/src/client/java/minicraft/entity/mob/AirWizard.java b/src/client/java/minicraft/entity/mob/AirWizard.java index 8f2c2705e..b03f46592 100644 --- a/src/client/java/minicraft/entity/mob/AirWizard.java +++ b/src/client/java/minicraft/entity/mob/AirWizard.java @@ -11,9 +11,11 @@ import minicraft.gfx.Font; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; +import minicraft.item.Item; import minicraft.item.Items; import minicraft.network.Analytics; import minicraft.screen.AchievementsDisplay; +import org.jetbrains.annotations.Nullable; public class AirWizard extends EnemyMob { private static final LinkedSprite[][][] sprites = new LinkedSprite[][][] { @@ -117,11 +119,11 @@ public void tick() { } @Override - public void doHurt(int damage, Direction attackDir) { - super.doHurt(damage, attackDir); + public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { if (attackDelay == 0 && attackTime == 0) { attackDelay = 60 * 2; } + return super.attack(source, item, attackDir, damage); } @Override @@ -151,7 +153,7 @@ public void render(Screen screen) { protected void touchedBy(Entity entity) { if (entity instanceof Player) { // If the entity is the Player, then deal them 1 damage points. - ((Player) entity).hurt(this, 1); + entity.attack(this, null, getInteractionDir(this, entity), 1); } } diff --git a/src/client/java/minicraft/entity/mob/Creeper.java b/src/client/java/minicraft/entity/mob/Creeper.java index 94860cc37..8b52cc51f 100644 --- a/src/client/java/minicraft/entity/mob/Creeper.java +++ b/src/client/java/minicraft/entity/mob/Creeper.java @@ -97,7 +97,8 @@ public void tick() { int distx = Math.abs(mob.x - x); int disty = Math.abs(mob.y - y); float distDiag = (float) Math.sqrt(distx * distx + disty * disty); - mob.hurt(this, (int) (lvlDamage * (1 / (distDiag + 1)) + Settings.getIdx("diff"))); + mob.attack(this, null, getInteractionDir(this, mob), + (int) (lvlDamage * (1 / (distDiag + 1)) + Settings.getIdx("diff"))); } else if (entity instanceof Spawner) { spawners.add(entity); } @@ -155,7 +156,7 @@ protected void touchedBy(Entity entity) { fuseTime = MAX_FUSE_TIME; fuseLit = true; } - ((Player) entity).hurt(this, 1); + entity.attack(this, null, getInteractionDir(this, entity), 1); } } diff --git a/src/client/java/minicraft/entity/mob/EnemyMob.java b/src/client/java/minicraft/entity/mob/EnemyMob.java index 0788005ec..6ec7a05e2 100644 --- a/src/client/java/minicraft/entity/mob/EnemyMob.java +++ b/src/client/java/minicraft/entity/mob/EnemyMob.java @@ -3,13 +3,16 @@ import minicraft.core.Game; import minicraft.core.Updater; import minicraft.core.io.Settings; +import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.furniture.Bed; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; +import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import org.jetbrains.annotations.Nullable; public class EnemyMob extends MobAi { @@ -111,10 +114,25 @@ protected void touchedBy(Entity entity) { // If an entity (like the player) touc super.touchedBy(entity); // Hurts the player, damage is based on lvl. if (entity instanceof Player) { - ((Player) entity).hurt(this, lvl * (Settings.get("diff").equals("minicraft.settings.difficulty.hard") ? 2 : 1)); + entity.attack(this, null, dir, lvl * (Settings.get("diff").equals("minicraft.settings.difficulty.hard") ? 2 : 1)); } } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return true; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return true; + } + + @Override + public boolean isUsable() { + return false; + } + public void die() { super.die(50 * lvl, 1); } diff --git a/src/client/java/minicraft/entity/mob/Mob.java b/src/client/java/minicraft/entity/mob/Mob.java index bd2cd181e..a6a62aa07 100644 --- a/src/client/java/minicraft/entity/mob/Mob.java +++ b/src/client/java/minicraft/entity/mob/Mob.java @@ -2,6 +2,7 @@ import minicraft.core.Game; import minicraft.core.Renderer; +import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.furniture.Tnt; @@ -10,9 +11,12 @@ import minicraft.gfx.Color; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.item.PotionType; +import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import org.jetbrains.annotations.Nullable; public abstract class Mob extends Entity { @@ -54,7 +58,8 @@ public void tick() { noActionTime++; if (level != null && level.getTile(x >> 4, y >> 4) == Tiles.get("lava")) // If we are trying to swim in lava - hurt(Tiles.get("lava"), x, y, 4); // Inflict 4 damage to ourselves, sourced from the lava Tile, with the direction as the opposite of ours. + // Inflict 4 damage to ourselves, sourced from the lava Tile, with the direction as the opposite of ours. + attack(Tiles.get("lava"), level, x >> 4, y >> 4, Direction.NONE, 4); if (canBurn()) { if (this.burningDuration > 0) { @@ -62,12 +67,13 @@ public void tick() { if (this.burningDuration % 10 == 0) level.add(new BurnParticle(x - 8 + (random.nextInt(8) - 4), y - 8 + (random.nextInt(8) - 4))); this.burningDuration--; + // TODO different damage? if (this instanceof Player) { if (this.burningDuration % 70 == 0 && !Renderer.player.potioneffects.containsKey(PotionType.Lava)) - hurt(this, 1, Direction.NONE); //burning damage + hurt( 1, Direction.NONE); //burning damage } else { if (this.burningDuration % 70 == 0) - hurt(this, 2, Direction.NONE); //burning damage + hurt( 2, Direction.NONE); //burning damage } } } @@ -79,11 +85,11 @@ public void tick() { /// The code below checks the direction of the knockback, moves the Mob accordingly, and brings the knockback closer to 0. int xd = 0, yd = 0; if (xKnockback != 0) { - xd = (int) Math.ceil(xKnockback / 2); + xd = (int) Math.ceil(xKnockback / 2F); xKnockback -= xKnockback / Math.abs(xKnockback); } if (yKnockback != 0) { - yd = (int) Math.ceil(yKnockback / 2); + yd = (int) Math.ceil(yKnockback / 2F); yKnockback -= yKnockback / Math.abs(yKnockback); } @@ -218,38 +224,24 @@ public boolean isSwimming() { return tile == Tiles.get("water") || tile == Tiles.get("lava"); // Check if the tile is liquid, and return true if so } - /** - * Do damage to the mob this method is called on. - * @param tile The tile that hurt the player - * @param x The x position of the mob - * @param y The x position of the mob - * @param damage The amount of damage to hurt the mob with - */ - public void hurt(Tile tile, int x, int y, int damage) { // Hurt the mob, when the source of damage is a tile - Direction attackDir = Direction.getDirection(dir.getDir() ^ 1); // Set attackDir to our own direction, inverted. XORing it with 1 flips the rightmost bit in the variable, this effectively adds one when even, and subtracts one when odd. - if (!(tile == Tiles.get("lava") && this instanceof Player && ((Player) this).potioneffects.containsKey(PotionType.Lava))) - doHurt(damage, tile.mayPass(level, x, y, this) ? Direction.NONE : attackDir); // Call the method that actually performs damage, and set it to no particular direction - } + @Override + public boolean attack(Tile source, Level level, int x, int y, Direction attackDir, int damage) { + if (source == Tiles.get("lava")) { + // TODO Generalize potion effects to all mobs + if (!(this instanceof Player && ((Player) this).potioneffects.containsKey(PotionType.Lava))) { + hurt(damage, attackDir); + } + } else { + hurt(damage, attackDir); + } - /** - * Do damage to the mob this method is called on. - * @param mob The mob that hurt this mob - * @param damage The amount of damage to hurt the mob with - */ - public void hurt(Mob mob, int damage) { - hurt(mob, damage, getAttackDir(mob, this)); + return true; } - /** - * Do damage to the mob this method is called on. - * @param mob The mob that hurt this mob - * @param damage The amount of damage to hurt the mob with - * @param attackDir The direction this mob was attacked from - */ - public void hurt(Mob mob, int damage, Direction attackDir) { // Hurt the mob, when the source is another mob - if (mob instanceof Player && Game.isMode("minicraft.settings.mode.creative") && mob != this) - doHurt(health, attackDir); // Kill the mob instantly - else doHurt(damage, attackDir); // Call the method that actually performs damage, and use our provided attackDir + @Override + public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { + hurt(damage, attackDir); + return true; } /** @@ -265,19 +257,25 @@ public void burn(int sec) { * @param dmg The amount of damage the explosion does. */ public void onExploded(Tnt tnt, int dmg) { - doHurt(dmg, getAttackDir(tnt, this)); + hurt(dmg, getInteractionDir(tnt, this)); } - /** - * Hurt the mob, based on only damage and a direction - * This is overridden in Player.java - * @param damage The amount of damage to hurt the mob with - * @param attackDir The direction this mob was attacked from - */ - protected void doHurt(int damage, Direction attackDir) { + protected void hurt(int damage, Direction attackDir) { if (isRemoved() || hurtTime > 0) return; // If the mob has been hurt recently and hasn't cooled down, don't continue + Player player = getClosestPlayer(); + if (player != null) { // If there is a player in the level + + /// Play the hurt sound only if the player is less than 80 entity coordinates away; or 5 tiles away. + int xd = player.x - x; + int yd = player.y - y; + if (xd * xd + yd * yd < 80 * 80) { + Sound.play("monsterhurt"); + } + } + level.add(new TextParticle("" + damage, x, y, Color.RED)); // Make a text particle at this position in this level, bright red and displaying the damage inflicted + health -= damage; // Actually change the health // Add the knockback in the correct direction @@ -298,17 +296,4 @@ public void heal(int heal) { // Restore health on the mob if (health > (Player.baseHealth + Player.extraHealth)) health = (Player.baseHealth + Player.extraHealth); // If our health has exceeded our maximum, lower it back down to said maximum } - - protected static Direction getAttackDir(Entity attacker, Entity hurt) { - return Direction.getDirection(hurt.x - attacker.x, hurt.y - attacker.y); - } - - /** - * This checks how the {@code attacker} can damage this mob. - * @param attacker The attacker entity. - * @return The calculated damage. - */ - public int calculateEntityDamage(Entity attacker, int damage) { - return damage; - } } diff --git a/src/client/java/minicraft/entity/mob/MobAi.java b/src/client/java/minicraft/entity/mob/MobAi.java index 00c2df1eb..e7d1c06b8 100644 --- a/src/client/java/minicraft/entity/mob/MobAi.java +++ b/src/client/java/minicraft/entity/mob/MobAi.java @@ -147,26 +147,6 @@ public boolean move(int xd, int yd) { return super.move(xd, yd); } - @Override - public void doHurt(int damage, Direction attackDir) { - if (isRemoved() || hurtTime > 0) - return; // If the mob has been hurt recently and hasn't cooled down, don't continue - - Player player = getClosestPlayer(); - if (player != null) { // If there is a player in the level - - /// Play the hurt sound only if the player is less than 80 entity coordinates away; or 5 tiles away. - int xd = player.x - x; - int yd = player.y - y; - if (xd * xd + yd * yd < 80 * 80) { - Sound.play("monsterhurt"); - } - } - level.add(new TextParticle("" + damage, x, y, Color.RED)); // Make a text particle at this position in this level, bright red and displaying the damage inflicted - - super.doHurt(damage, attackDir); - } - @Override public boolean canWool() { return true; diff --git a/src/client/java/minicraft/entity/mob/ObsidianKnight.java b/src/client/java/minicraft/entity/mob/ObsidianKnight.java index 5d874e1a5..70d7ba9e4 100644 --- a/src/client/java/minicraft/entity/mob/ObsidianKnight.java +++ b/src/client/java/minicraft/entity/mob/ObsidianKnight.java @@ -14,8 +14,12 @@ import minicraft.gfx.Font; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker; +import minicraft.item.Item; import minicraft.item.Items; +import minicraft.level.Level; +import minicraft.level.tile.Tile; import minicraft.screen.AchievementsDisplay; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; public class ObsidianKnight extends EnemyMob { @@ -199,11 +203,16 @@ public void tick() { } @Override - public void doHurt(int damage, Direction attackDir) { - super.doHurt(damage, attackDir); + public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { if (attackDelay == 0 && attackTime == 0) { attackDelay = 60 * 2; } + + if (source instanceof Arrow && phase == 0) { + source.remove(); + } + + return super.attack(source, item, attackDir, damage); } @Override @@ -233,7 +242,7 @@ public void render(Screen screen) { protected void touchedBy(Entity entity) { if (entity instanceof Player) { // If the entity is the Player, then deal them 2 damage points. - ((Player) entity).hurt(this, 2); + entity.attack(this, null, getInteractionDir(this, entity), 1); if (attackPhase == AttackPhase.Dashing) { dashTime = Math.max(dashTime - 10, 0); } @@ -273,14 +282,4 @@ public void die() { super.die(); // Calls the die() method in EnemyMob.java } - - @Override - public int calculateEntityDamage(Entity attacker, int damage) { - if (attacker instanceof Arrow && phase == 0) { - attacker.remove(); - return 0; - } - - return super.calculateEntityDamage(attacker, damage); - } } diff --git a/src/client/java/minicraft/entity/mob/PassiveMob.java b/src/client/java/minicraft/entity/mob/PassiveMob.java index e6ec7f6cb..8cde1db95 100644 --- a/src/client/java/minicraft/entity/mob/PassiveMob.java +++ b/src/client/java/minicraft/entity/mob/PassiveMob.java @@ -3,11 +3,15 @@ import minicraft.core.Game; import minicraft.core.Updater; import minicraft.core.io.Settings; +import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; +import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import org.jetbrains.annotations.Nullable; public class PassiveMob extends MobAi { protected int color; @@ -42,6 +46,21 @@ public void render(Screen screen) { super.render(screen); } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return true; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return true; + } + + @Override + public boolean isUsable() { + return false; + } + @Override public void randomizeWalkDir(boolean byChance) { if (xmov == 0 && ymov == 0 && random.nextInt(5) == 0 || byChance || random.nextInt(randomWalkChance) == 0) { diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index dd9018fab..e4678b848 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -6,7 +6,6 @@ import minicraft.core.io.InputHandler; import minicraft.core.io.Settings; import minicraft.core.io.Sound; -import minicraft.entity.Arrow; import minicraft.entity.ClientTickable; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -39,7 +38,6 @@ import minicraft.item.StackableItem; import minicraft.item.TileItem; import minicraft.item.ToolItem; -import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; @@ -826,7 +824,7 @@ private void goFishing() { private boolean interact(Rectangle area) { List entities = level.getEntitiesInRect(area); // Gets the entities within the 4 points for (Entity e : entities) { - if (e instanceof Furniture && ((Furniture) e).interact(this)) + if (e instanceof Furniture && e.use(this, activeItem, dir)) return true; // If the entity is not the player, then call it's use method, and return the result. Only some furniture classes use this. } return false; @@ -838,7 +836,7 @@ private boolean interact(Rectangle area) { private boolean attack(Rectangle area) { List entities = level.getEntitiesInRect(area); for (Entity e : entities) { - if (e != this && e.attack(this, activeItem, attackDir)) + if (e != this && e.attack(this, activeItem, attackDir, getAttackDamage(e))) return true; // This is the ONLY place that the Entity.interact method is actually called. } return false; @@ -851,13 +849,11 @@ private boolean hurt(Rectangle area) { List entities = level.getEntitiesInRect(area); int maxDmg = 0; for (Entity e : entities) { - if (e != this && e instanceof Mob) { + if (e != this && e.isAttackable(this, activeItem, attackDir)) { int dmg = getAttackDamage(e); maxDmg = Math.max(dmg, maxDmg); - ((Mob) e).hurt(this, dmg, attackDir); + e.attack(this, activeItem, attackDir, getAttackDamage(e)); } - if (e instanceof Furniture) - e.attack(this, null, attackDir); } return maxDmg > 0; } @@ -1161,6 +1157,21 @@ public int getLightRadius() { return r; // Return light radius } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return true; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return true; + } + + @Override + public boolean isUsable() { + return false; + } + /** * What happens when the player dies */ @@ -1191,17 +1202,8 @@ public void onExploded(Tnt tnt, int dmg) { payStamina(dmg * 2); } - /** - * Hurt the player. - * @param damage How much damage to do to player. - * @param attackDir What direction to attack. - */ - public void hurt(int damage, Direction attackDir) { - doHurt(damage, attackDir); - } - @Override - protected void doHurt(int damage, Direction attackDir) { + protected void hurt(int damage, Direction attackDir) { if (Game.isMode("minicraft.settings.mode.creative") || hurtTime > 0 || Bed.inBed(this)) return; // Can't get hurt in creative, hurt cooldown, or while someone is in bed @@ -1234,7 +1236,7 @@ protected void doHurt(int damage, Direction attackDir) { if (healthDam > 0 || this != Game.player) { level.add(new TextParticle("" + damage, x, y, Color.get(-1, 504))); - if (this == Game.player) super.doHurt(healthDam, attackDir); // Sets knockback, and takes away health. + if (this == Game.player) super.hurt(healthDam, attackDir); // Sets knockback, and takes away health. } Sound.play("playerhurt"); @@ -1255,9 +1257,8 @@ private void directHurt(int damage, Direction attackDir) { healthDam = damage; // Subtract that amount } - if (healthDam > 0 || this != Game.player) { - level.add(new TextParticle("" + damage, x, y, Color.get(-1, 504))); - if (this == Game.player) super.doHurt(healthDam, attackDir); // Sets knockback, and takes away health. + if (healthDam > 0) { + super.hurt(healthDam, attackDir); // Sets knockback, and takes away health. } Sound.play("playerhurt"); diff --git a/src/client/java/minicraft/entity/mob/Sheep.java b/src/client/java/minicraft/entity/mob/Sheep.java index bd8fb04a1..7289846cf 100644 --- a/src/client/java/minicraft/entity/mob/Sheep.java +++ b/src/client/java/minicraft/entity/mob/Sheep.java @@ -2,6 +2,7 @@ import minicraft.core.io.Settings; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.item.Item; @@ -51,7 +52,8 @@ public void tick() { } } - public boolean attack(Player player, @Nullable Item item, Direction attackDir) { + @Override + public boolean use(Player player, @Nullable Item item, Direction attackDir) { if (cut) return false; if (item instanceof ToolItem) { diff --git a/src/client/java/minicraft/entity/mob/Snake.java b/src/client/java/minicraft/entity/mob/Snake.java index 81c66b340..253a799f7 100644 --- a/src/client/java/minicraft/entity/mob/Snake.java +++ b/src/client/java/minicraft/entity/mob/Snake.java @@ -21,7 +21,7 @@ public Snake(int lvl) { protected void touchedBy(Entity entity) { if (entity instanceof Player) { int damage = lvl + Settings.getIdx("diff"); - ((Player) entity).hurt(this, damage); + entity.attack(this, null, getInteractionDir(this, entity), damage); } } diff --git a/src/client/java/minicraft/entity/particle/Particle.java b/src/client/java/minicraft/entity/particle/Particle.java index 04e0382ec..f7e9148e7 100644 --- a/src/client/java/minicraft/entity/particle/Particle.java +++ b/src/client/java/minicraft/entity/particle/Particle.java @@ -1,10 +1,15 @@ package minicraft.entity.particle; import minicraft.entity.ClientTickable; +import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.gfx.Screen; import minicraft.gfx.SpriteLinker.LinkedSprite; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; import minicraft.util.Logging; +import org.jetbrains.annotations.Nullable; import javax.security.auth.DestroyFailedException; @@ -58,4 +63,22 @@ public void render(Screen screen) { public boolean isSolid() { return false; } + + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} } diff --git a/src/client/java/minicraft/level/tile/CactusTile.java b/src/client/java/minicraft/level/tile/CactusTile.java index 8f076592a..f203f4299 100644 --- a/src/client/java/minicraft/level/tile/CactusTile.java +++ b/src/client/java/minicraft/level/tile/CactusTile.java @@ -59,13 +59,11 @@ public void bumpedInto(Level level, int x, int y, Entity entity) { if (!(entity instanceof Mob)) return; Mob m = (Mob) entity; if (Settings.get("diff").equals("minicraft.settings.difficulty.easy")) { - m.hurt(this, x, y, 1); - } - if (Settings.get("diff").equals("minicraft.settings.difficulty.normal")) { - m.hurt(this, x, y, 1); - } - if (Settings.get("diff").equals("minicraft.settings.difficulty.hard")) { - m.hurt(this, x, y, 2); + m.attack(this, level, x, y, m.dir.getOpposite(), 1); + } else if (Settings.get("diff").equals("minicraft.settings.difficulty.normal")) { + m.attack(this, level, x, y, m.dir.getOpposite(), 1); + } else if (Settings.get("diff").equals("minicraft.settings.difficulty.hard")) { + m.attack(this, level, x, y, m.dir.getOpposite(), 2); } } diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index 8031a6d99..72bf5c18c 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -38,7 +38,7 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir public void bumpedInto(Level level, int x, int y, Entity entity) { if (entity instanceof Mob) - ((Mob) entity).hurt(this, x, y, 3); + entity.attack(this, level, x, y, ((Mob) entity).dir.getOpposite(), 3); } public boolean mayPass(Level level, int x, int y, Entity e) { diff --git a/src/client/java/minicraft/level/tile/entity/SignTileEntity.java b/src/client/java/minicraft/level/tile/entity/SignTileEntity.java index 719c7e7e5..f7b73a854 100644 --- a/src/client/java/minicraft/level/tile/entity/SignTileEntity.java +++ b/src/client/java/minicraft/level/tile/entity/SignTileEntity.java @@ -2,9 +2,14 @@ import minicraft.core.Game; import minicraft.core.Renderer; +import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.gfx.Screen; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; import minicraft.screen.SignDisplayMenu; +import org.jetbrains.annotations.Nullable; public class SignTileEntity extends Entity { public SignTileEntity() { @@ -19,6 +24,24 @@ public boolean isSolid() { return false; } + @Override + public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { + return false; + } + + @Override + public boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir) { + return false; + } + + @Override + public boolean isUsable() { + return false; + } + + @Override + protected void hurt(int damage, Direction attackDir) {} + @Override public void tick() { int xt = x >> 4, yt = y >> 4; From 99a23083862cb2cf2fc27a34839cb38a15346a3c Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Mon, 12 Aug 2024 01:21:51 +0800 Subject: [PATCH 09/14] Update entity damage handling system --- src/client/java/minicraft/entity/Arrow.java | 11 +- src/client/java/minicraft/entity/Entity.java | 66 +++++---- .../minicraft/entity/ExplosionTileTicker.java | 8 +- .../java/minicraft/entity/FireSpark.java | 8 +- .../java/minicraft/entity/ItemEntity.java | 8 +- src/client/java/minicraft/entity/Spark.java | 11 +- .../minicraft/entity/furniture/Furniture.java | 8 +- .../minicraft/entity/furniture/Spawner.java | 21 +-- .../java/minicraft/entity/mob/AirWizard.java | 8 +- .../java/minicraft/entity/mob/Creeper.java | 6 +- .../java/minicraft/entity/mob/EnemyMob.java | 10 +- src/client/java/minicraft/entity/mob/Mob.java | 51 +++---- .../minicraft/entity/mob/ObsidianKnight.java | 13 +- .../java/minicraft/entity/mob/Player.java | 95 +++++-------- .../java/minicraft/entity/mob/Snake.java | 9 +- .../minicraft/entity/particle/Particle.java | 8 +- .../java/minicraft/item/PotionType.java | 2 +- src/client/java/minicraft/item/ToolItem.java | 6 + .../java/minicraft/level/tile/CactusTile.java | 18 ++- .../java/minicraft/level/tile/CloudTile.java | 16 ++- .../minicraft/level/tile/LavaBrickTile.java | 4 +- .../java/minicraft/level/tile/Tile.java | 44 +++--- .../java/minicraft/util/DamageSource.java | 128 ++++++++++++++++++ 23 files changed, 363 insertions(+), 196 deletions(-) create mode 100644 src/client/java/minicraft/util/DamageSource.java diff --git a/src/client/java/minicraft/entity/Arrow.java b/src/client/java/minicraft/entity/Arrow.java index 8de70fa49..e2c28466d 100644 --- a/src/client/java/minicraft/entity/Arrow.java +++ b/src/client/java/minicraft/entity/Arrow.java @@ -10,6 +10,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import minicraft.util.Logging; import org.jetbrains.annotations.Nullable; @@ -75,7 +76,8 @@ public void tick() { if (hit instanceof Mob && hit != owner) { Mob mob = (Mob) hit; damage += (hit instanceof Player ? 0 : 3) + (criticalHit ? 0 : 1); // Extra damage bonus. - mob.attack(owner, null, dir, damage); // normal hurting to other mobs + mob.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.ARROW, owner), + dir, damage); // normal hurting to other mobs } if (!level.getTile(x >> 4, y >> 4).mayPass(level, x >> 4, y >> 4, this) @@ -111,7 +113,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } @Override public void render(Screen screen) { diff --git a/src/client/java/minicraft/entity/Entity.java b/src/client/java/minicraft/entity/Entity.java index 9cdfd55e3..ea7c0fcea 100644 --- a/src/client/java/minicraft/entity/Entity.java +++ b/src/client/java/minicraft/entity/Entity.java @@ -1,6 +1,7 @@ package minicraft.entity; import minicraft.core.Action; +import minicraft.core.Game; import minicraft.core.Updater; import minicraft.entity.mob.Player; import minicraft.gfx.Rectangle; @@ -9,6 +10,7 @@ import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.network.Network; +import minicraft.util.DamageSource; import minicraft.util.Logging; import org.jetbrains.annotations.Nullable; @@ -34,6 +36,19 @@ public abstract class Entity implements Tickable { * These bit shift operators are used to easily get the X & Y coordinates of a tile that the entity is standing on. */ + /* + * In total there are 3 types of active entity interactions: attack, use and take. + * While only players can use and take entities and tiles, generally all mobs may attack other entities and tiles. + * This is because players could use different keys for different interactions, but not for mob AIs. + * However, not all entities are able to be attacked (as well as use and take). + * Tiles can also attack entities in the similar sense. + * In the process of damage/hurting calculations and handling, the flow is like: + * - 1. Attack: interaction triggered by damage source; damage with bonus intended to emit is calculated here + * - With a method if there exists an AI in the source + * - 2. Hurt: target entity receives damage from damage source; calculation includes armors and shields + * - 3. Handle damage: final damage value is passed to this when all damage calculations are completed + */ + // Entity coordinates are per pixel, not per tile; each tile is 16x16 entity pixels. protected final Random random = new Random(); public int x, y; // x, y entity coordinates on the map @@ -142,6 +157,10 @@ public int getLightRadius() { protected void touchedBy(Entity entity) { } + public boolean isFireImmune() { + return false; + } + /** * The amount of damage to attack when the item has no damage attribute set. * @return amount of damage by fists @@ -154,7 +173,7 @@ protected int baseDamage() { * An indicator for which the entity is attackable by certain entity, even under certain conditions. * This is invoked each time an entity is being targetted regardless it is interacted. * Most probably used by Player. - * @return {@code false} if not attackable and {@link #attack(Entity, Item, Direction, int)} would not be invoked + * @return {@code false} if not attackable and {@link #hurt(DamageSource, Direction, int)} would not be invoked * when triggered. */ public abstract boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir); @@ -164,16 +183,25 @@ protected int baseDamage() { * This is invoked each time an entity is being targetted regardless it is interacted. * Most probably used by Player. * Though the usefulness of this is doubtable. - * @return {@code false} if not attackable and {@link #attack(Tile, Level, int, int, Direction, int)} would not be + * @return {@code false} if not attackable and {@link #hurt(DamageSource, Direction, int)} would not be * invoked when triggered. */ public abstract boolean isAttackable(Tile source, Level level, int x, int y, Direction attackDir); + public boolean isInvulnerableTo(DamageSource source) { + return isRemoved() || + source instanceof DamageSource.EntityDamageSource && + ((DamageSource.EntityDamageSource) source).getEntity() instanceof Player && + Game.isMode("minicraft.settings.mode.creative") || + source instanceof DamageSource.OtherDamageSource && + ((DamageSource.OtherDamageSource) source).getDamageType().isFireRelated() && isFireImmune(); + } + /** * An indicator for which the entity is attackable by certain entity, even under certain conditions. * This is invoked each time an entity is being targetted regardless it is interacted. * Most probably used by Player. - * @return {@code false} if not attackable and {@link #attack(Entity, Item, Direction, int)} would not be invoked + * @return {@code false} if not attackable and {@link #use(Player, Item, Direction)} would not be invoked * when triggered. */ public abstract boolean isUsable(); @@ -181,36 +209,22 @@ protected int baseDamage() { // TODO Here, attackDir may be changed to use an angle instead of axis to perform more accurate actions. /** - * Attacks the entity this method is called on - * @param source The entity attacking - * @param item The item the player attacked with - * @param attackDir The direction to interact - * @param damage The amount of damage intended to emit this time - * @return If the interaction was successful + * Hurt the entity directly, based on only damage and a direction + * Usually this is invoked by {@link #hurt(DamageSource, Direction, int)}.

+ * Note that using {@link #hurt(DamageSource, Direction, int)} is more recommended. + * @param damage The amount of damage to hurt the entity with + * @param attackDir The direction this entity was attacked from */ - public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { - return false; - } + protected abstract void handleDamage(DamageSource source, Direction attackDir, int damage); /** - * Attacks the entity this method is called on (coordinates in tile coordinates) - * @param source The entity attacking + * Attacks the entity this method is called on + * @param source The cause of damage * @param attackDir The direction to interact * @param damage The amount of damage intended to emit this time * @return If the interaction was successful */ - public boolean attack(Tile source, Level level, int x, int y, Direction attackDir, int damage) { - return false; - } - - /** - * Hurt the entity directly, based on only damage and a direction - * Usually this is invoked by {@link #attack(Entity, Item, Direction, int)} and - * {@link #attack(Tile, Level, int, int, Direction, int)} - * @param damage The amount of damage to hurt the entity with - * @param attackDir The direction this entity was attacked from - */ - protected abstract void hurt(int damage, Direction attackDir); // TODO damage type + public abstract boolean hurt(DamageSource source, Direction attackDir, int damage); public static Direction getInteractionDir(Entity attacker, Entity hurt) { return Direction.getDirection(hurt.x - attacker.x, hurt.y - attacker.y); diff --git a/src/client/java/minicraft/entity/ExplosionTileTicker.java b/src/client/java/minicraft/entity/ExplosionTileTicker.java index 5ecec57fa..f4dbbad43 100644 --- a/src/client/java/minicraft/entity/ExplosionTileTicker.java +++ b/src/client/java/minicraft/entity/ExplosionTileTicker.java @@ -6,6 +6,7 @@ import minicraft.level.tile.ExplodedTile; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; // This is a kind of tile entity. Maybe this should be savable. @@ -72,5 +73,10 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } } diff --git a/src/client/java/minicraft/entity/FireSpark.java b/src/client/java/minicraft/entity/FireSpark.java index 2e229f9c7..71a83d62c 100644 --- a/src/client/java/minicraft/entity/FireSpark.java +++ b/src/client/java/minicraft/entity/FireSpark.java @@ -9,6 +9,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class FireSpark extends Entity { @@ -102,7 +103,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } @Override public void render(Screen screen) { diff --git a/src/client/java/minicraft/entity/ItemEntity.java b/src/client/java/minicraft/entity/ItemEntity.java index 5cfca0f85..d5c500733 100644 --- a/src/client/java/minicraft/entity/ItemEntity.java +++ b/src/client/java/minicraft/entity/ItemEntity.java @@ -6,6 +6,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -164,7 +165,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } @Override protected List getDataPrints() { diff --git a/src/client/java/minicraft/entity/Spark.java b/src/client/java/minicraft/entity/Spark.java index 5be2d867d..bd84c8a8c 100644 --- a/src/client/java/minicraft/entity/Spark.java +++ b/src/client/java/minicraft/entity/Spark.java @@ -10,6 +10,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class Spark extends Entity { @@ -55,7 +56,8 @@ public void tick() { Player player = getClosestPlayer(); if (player != null && player.isWithin(0, this)) { - player.attack(owner, null, getInteractionDir(this, player), 1); + player.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.SPARK, owner), + getInteractionDir(this, player), 1); } } @@ -82,7 +84,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } @Override public void render(Screen screen) { diff --git a/src/client/java/minicraft/entity/furniture/Furniture.java b/src/client/java/minicraft/entity/furniture/Furniture.java index 2398b1e60..9ef56e903 100644 --- a/src/client/java/minicraft/entity/furniture/Furniture.java +++ b/src/client/java/minicraft/entity/furniture/Furniture.java @@ -10,6 +10,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -104,7 +105,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } /** * Lets the user pick up furniture. diff --git a/src/client/java/minicraft/entity/furniture/Spawner.java b/src/client/java/minicraft/entity/furniture/Spawner.java index 229d5cbdf..31cb61bf9 100644 --- a/src/client/java/minicraft/entity/furniture/Spawner.java +++ b/src/client/java/minicraft/entity/furniture/Spawner.java @@ -29,6 +29,7 @@ import minicraft.item.PowerGloveItem; import minicraft.item.ToolItem; import minicraft.item.ToolType; +import minicraft.util.DamageSource; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; @@ -175,29 +176,21 @@ private void trySpawn() { } @Override - public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { - if (source instanceof Player) { - + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + if (source instanceof DamageSource.EntityDamageSource && + ((DamageSource.EntityDamageSource) source).getEntity() instanceof Player) { + Item item = ((DamageSource.EntityDamageSource) source).getItem(); Sound.play("monsterhurt"); - - int dmg = 1; + int dmg = item instanceof ToolItem ? ((ToolItem) item).getAttackDamageBonus(this) : 1; if (Game.isMode("minicraft.settings.mode.creative")) dmg = health; - else if (item instanceof ToolItem) { - ToolItem tool = (ToolItem) item; - dmg = tool.level + random.nextInt(2); - if (tool.type == ToolType.Pickaxe) - dmg += random.nextInt(5) + 2; - if (((Player) source).potioneffects.containsKey(PotionType.Haste)) - dmg *= 2; - } health -= dmg; level.add(new TextParticle("" + dmg, x, y, Color.get(-1, 200, 300, 400))); if (health <= 0) { level.remove(this); Sound.play("death"); - ((Player) source).addScore(500); + ((Player) ((DamageSource.EntityDamageSource) source).getEntity()).addScore(500); } return true; diff --git a/src/client/java/minicraft/entity/mob/AirWizard.java b/src/client/java/minicraft/entity/mob/AirWizard.java index b03f46592..ce389d425 100644 --- a/src/client/java/minicraft/entity/mob/AirWizard.java +++ b/src/client/java/minicraft/entity/mob/AirWizard.java @@ -3,6 +3,7 @@ import minicraft.core.Game; import minicraft.core.Updater; import minicraft.core.io.Localization; +import minicraft.core.io.Settings; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -15,6 +16,7 @@ import minicraft.item.Items; import minicraft.network.Analytics; import minicraft.screen.AchievementsDisplay; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class AirWizard extends EnemyMob { @@ -119,11 +121,11 @@ public void tick() { } @Override - public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { + public boolean hurt(DamageSource source, Direction attackDir, int damage) { if (attackDelay == 0 && attackTime == 0) { attackDelay = 60 * 2; } - return super.attack(source, item, attackDir, damage); + return super.hurt(source, attackDir, damage); } @Override @@ -153,7 +155,7 @@ public void render(Screen screen) { protected void touchedBy(Entity entity) { if (entity instanceof Player) { // If the entity is the Player, then deal them 1 damage points. - entity.attack(this, null, getInteractionDir(this, entity), 1); + attack(entity); } } diff --git a/src/client/java/minicraft/entity/mob/Creeper.java b/src/client/java/minicraft/entity/mob/Creeper.java index 8b52cc51f..f4ff5e193 100644 --- a/src/client/java/minicraft/entity/mob/Creeper.java +++ b/src/client/java/minicraft/entity/mob/Creeper.java @@ -12,6 +12,7 @@ import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.item.Items; import minicraft.level.tile.Tiles; +import minicraft.util.DamageSource; import java.util.ArrayList; import java.util.List; @@ -97,7 +98,8 @@ public void tick() { int distx = Math.abs(mob.x - x); int disty = Math.abs(mob.y - y); float distDiag = (float) Math.sqrt(distx * distx + disty * disty); - mob.attack(this, null, getInteractionDir(this, mob), + entity.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.EXPLOSION, level, x, y), + getInteractionDir(this, mob), (int) (lvlDamage * (1 / (distDiag + 1)) + Settings.getIdx("diff"))); } else if (entity instanceof Spawner) { spawners.add(entity); @@ -156,7 +158,7 @@ protected void touchedBy(Entity entity) { fuseTime = MAX_FUSE_TIME; fuseLit = true; } - entity.attack(this, null, getInteractionDir(this, entity), 1); + attack(entity); } } diff --git a/src/client/java/minicraft/entity/mob/EnemyMob.java b/src/client/java/minicraft/entity/mob/EnemyMob.java index 6ec7a05e2..d76c5adab 100644 --- a/src/client/java/minicraft/entity/mob/EnemyMob.java +++ b/src/client/java/minicraft/entity/mob/EnemyMob.java @@ -12,6 +12,7 @@ import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class EnemyMob extends MobAi { @@ -111,13 +112,18 @@ public void render(Screen screen) { @Override protected void touchedBy(Entity entity) { // If an entity (like the player) touches the enemy mob - super.touchedBy(entity); // Hurts the player, damage is based on lvl. if (entity instanceof Player) { - entity.attack(this, null, dir, lvl * (Settings.get("diff").equals("minicraft.settings.difficulty.hard") ? 2 : 1)); + attack(entity); } } + @Override + public boolean attack(Entity entity) { + return hurt(new DamageSource.EntityDamageSource(this, null), dir, + lvl * (Settings.get("diff").equals("minicraft.settings.difficulty.hard") ? 2 : 1)); + } + @Override public boolean isAttackable(Entity source, @Nullable Item item, Direction attackDir) { return true; diff --git a/src/client/java/minicraft/entity/mob/Mob.java b/src/client/java/minicraft/entity/mob/Mob.java index a6a62aa07..211d8657b 100644 --- a/src/client/java/minicraft/entity/mob/Mob.java +++ b/src/client/java/minicraft/entity/mob/Mob.java @@ -1,6 +1,5 @@ package minicraft.entity.mob; -import minicraft.core.Game; import minicraft.core.Renderer; import minicraft.core.io.Sound; import minicraft.entity.Direction; @@ -16,6 +15,7 @@ import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.level.tile.Tiles; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public abstract class Mob extends Entity { @@ -59,7 +59,8 @@ public void tick() { if (level != null && level.getTile(x >> 4, y >> 4) == Tiles.get("lava")) // If we are trying to swim in lava // Inflict 4 damage to ourselves, sourced from the lava Tile, with the direction as the opposite of ours. - attack(Tiles.get("lava"), level, x >> 4, y >> 4, Direction.NONE, 4); + hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.LAVA, level, x >> 4, y >> 4), + Direction.NONE, 4); if (canBurn()) { if (this.burningDuration > 0) { @@ -68,13 +69,8 @@ public void tick() { level.add(new BurnParticle(x - 8 + (random.nextInt(8) - 4), y - 8 + (random.nextInt(8) - 4))); this.burningDuration--; // TODO different damage? - if (this instanceof Player) { - if (this.burningDuration % 70 == 0 && !Renderer.player.potioneffects.containsKey(PotionType.Lava)) - hurt( 1, Direction.NONE); //burning damage - } else { - if (this.burningDuration % 70 == 0) - hurt( 2, Direction.NONE); //burning damage - } + hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.ON_FIRE, level, x, y), + Direction.NONE, this instanceof Player ? 1 : 2); //burning damage } } @@ -224,24 +220,13 @@ public boolean isSwimming() { return tile == Tiles.get("water") || tile == Tiles.get("lava"); // Check if the tile is liquid, and return true if so } - @Override - public boolean attack(Tile source, Level level, int x, int y, Direction attackDir, int damage) { - if (source == Tiles.get("lava")) { - // TODO Generalize potion effects to all mobs - if (!(this instanceof Player && ((Player) this).potioneffects.containsKey(PotionType.Lava))) { - hurt(damage, attackDir); - } - } else { - hurt(damage, attackDir); - } - - return true; - } - - @Override - public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { - hurt(damage, attackDir); - return true; + /** + * Attacks an entity + * @param entity The entity to attack + * @return If the interaction was successful + */ + public boolean attack(Entity entity) { + return false; } /** @@ -257,10 +242,18 @@ public void burn(int sec) { * @param dmg The amount of damage the explosion does. */ public void onExploded(Tnt tnt, int dmg) { - hurt(dmg, getInteractionDir(tnt, this)); + hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.EXPLOSION, level, x, y), + getInteractionDir(tnt, this), dmg); + } + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + handleDamage(source, attackDir, damage); + return true; } - protected void hurt(int damage, Direction attackDir) { + @Override + protected void handleDamage(DamageSource source, Direction attackDir, int damage) { if (isRemoved() || hurtTime > 0) return; // If the mob has been hurt recently and hasn't cooled down, don't continue diff --git a/src/client/java/minicraft/entity/mob/ObsidianKnight.java b/src/client/java/minicraft/entity/mob/ObsidianKnight.java index 70d7ba9e4..dd03e1ce5 100644 --- a/src/client/java/minicraft/entity/mob/ObsidianKnight.java +++ b/src/client/java/minicraft/entity/mob/ObsidianKnight.java @@ -19,6 +19,7 @@ import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.screen.AchievementsDisplay; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; @@ -203,16 +204,18 @@ public void tick() { } @Override - public boolean attack(Entity source, @Nullable Item item, Direction attackDir, int damage) { + public boolean hurt(DamageSource source, Direction attackDir, int damage) { if (attackDelay == 0 && attackTime == 0) { attackDelay = 60 * 2; } - if (source instanceof Arrow && phase == 0) { - source.remove(); + if (source instanceof DamageSource.EntityDamageSource && + ((DamageSource.EntityDamageSource) source).getEntity() instanceof Arrow && phase == 0) { + ((DamageSource.EntityDamageSource) source).getEntity().remove(); + return false; } - return super.attack(source, item, attackDir, damage); + return super.hurt(source, attackDir, damage); } @Override @@ -242,7 +245,7 @@ public void render(Screen screen) { protected void touchedBy(Entity entity) { if (entity instanceof Player) { // If the entity is the Player, then deal them 2 damage points. - entity.attack(this, null, getInteractionDir(this, entity), 1); + attack(entity); if (attackPhase == AttackPhase.Dashing) { dashTime = Math.max(dashTime - 10, 0); } diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index e4678b848..db6eee064 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -52,6 +52,7 @@ import minicraft.screen.SkinDisplay; import minicraft.screen.WorldSelectDisplay; import minicraft.util.AdvancementElement; +import minicraft.util.DamageSource; import minicraft.util.Logging; import minicraft.util.Vector2; import org.jetbrains.annotations.Nullable; @@ -431,7 +432,8 @@ public void tick() { if (hunger == 0 && health > minStarveHealth[diffIdx]) { if (hungerStarveDelay > 0) hungerStarveDelay--; if (hungerStarveDelay == 0) { - directHurt(1, Direction.NONE); // Do 1 damage to the player + hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.STARVE, level, x, y), + Direction.NONE, 1); // Do 1 damage to the player } } } @@ -484,7 +486,9 @@ public void tick() { if (isSwimming() && tickTime % 60 == 0 && !potioneffects.containsKey(PotionType.Swim)) { // If drowning... :P if (stamina > 0) payStamina(1); // Take away stamina - else directHurt(1, Direction.NONE); // If no stamina, take damage. + else + hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.DRONE, level, x, y), + Direction.NONE, 1); // If no stamina, take damage. } if (activeItem != null && (input.inputPressed("drop-one") || input.inputPressed("drop-stack"))) { @@ -641,7 +645,7 @@ protected void attack() { done = true; // Returns true if the target tile successfully interacts with the item. - } else if (tile.attack(level, t.x, t.y, this, activeItem, attackDir)) { + } else if (tile.attack(level, t.x, t.y, this, activeItem, attackDir, 1)) { done = true; } } @@ -661,7 +665,7 @@ protected void attack() { if (activeItem == null) { // If there is no active item, OR if the item can be used to attack... attackTime = 5; // Attacks the enemy in the appropriate direction. - boolean used = hurt(getInteractionBox(ATTACK_DIST)); + boolean used = attack(getInteractionBox(ATTACK_DIST)); // Attempts to hurt the tile in the appropriate direction. Point t = getInteractionTile(); @@ -669,7 +673,7 @@ protected void attack() { // Check if tile is in bounds of the map. if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { Tile tile = level.getTile(t.x, t.y); - used = tile.hurt(level, t.x, t.y, this, random.nextInt(3) + 1, attackDir) || used; + used = tile.attack(level, t.x, t.y, this, null, attackDir, random.nextInt(3) + 1) || used; } if (used && activeItem instanceof ToolItem) @@ -700,7 +704,7 @@ protected void interact() { } // If the interaction between you and an entity is successful, then return. - if (interact(getInteractionBox(INTERACT_DIST))) return; + if (use(getInteractionBox(INTERACT_DIST))) return; // If we are holding an item. if (activeItem != null) { @@ -724,7 +728,7 @@ protected void interact() { done = true; // Returns true if the target tile successfully interacts with the item. - } else if (tile.interact(level, t.x, t.y, this, activeItem, attackDir)){ + } else if (tile.use(level, t.x, t.y, this, activeItem, attackDir)){ done = true; } } @@ -821,7 +825,7 @@ private void goFishing() { } /** called by other use method; this serves as a buffer in case there is no entity in front of the player. */ - private boolean interact(Rectangle area) { + private boolean use(Rectangle area) { List entities = level.getEntitiesInRect(area); // Gets the entities within the 4 points for (Entity e : entities) { if (e instanceof Furniture && e.use(this, activeItem, dir)) @@ -830,45 +834,26 @@ private boolean interact(Rectangle area) { return false; } - /** - * same, but for attack. - */ + /** called by other attack method; this serves as a buffer in case there is no entity in front of the player. */ private boolean attack(Rectangle area) { List entities = level.getEntitiesInRect(area); + boolean sucessful = false; for (Entity e : entities) { - if (e != this && e.attack(this, activeItem, attackDir, getAttackDamage(e))) - return true; // This is the ONLY place that the Entity.interact method is actually called. - } - return false; - } - - /** - * same, but for attacking. - */ - private boolean hurt(Rectangle area) { - List entities = level.getEntitiesInRect(area); - int maxDmg = 0; - for (Entity e : entities) { - if (e != this && e.isAttackable(this, activeItem, attackDir)) { - int dmg = getAttackDamage(e); - maxDmg = Math.max(dmg, maxDmg); - e.attack(this, activeItem, attackDir, getAttackDamage(e)); + if (e != this && e.isAttackable(this, activeItem, attackDir) && + !e.isInvulnerableTo(new DamageSource.EntityDamageSource(this, activeItem))) { + sucessful |= attack(e); } } - return maxDmg > 0; + return sucessful; } - /** - * Calculates how much damage the player will do. - * @param e Entity being attacked. - * @return How much damage the player does. - */ - private int getAttackDamage(Entity e) { - int dmg = random.nextInt(2) + 1; + @Override + public boolean attack(Entity entity) { + int dmg = random.nextInt(2) + baseDamage(); if (activeItem != null && activeItem instanceof ToolItem) { - dmg += ((ToolItem) activeItem).getAttackDamageBonus(e); // Sword/Axe are more effective at dealing damage. + dmg += ((ToolItem) activeItem).getAttackDamageBonus(entity); // Sword/Axe are more effective at dealing damage. } - return dmg; + return entity.hurt(new DamageSource.EntityDamageSource(this, activeItem), attackDir, dmg); } /** @@ -1203,9 +1188,14 @@ public void onExploded(Tnt tnt, int dmg) { } @Override - protected void hurt(int damage, Direction attackDir) { + public boolean isFireImmune() { + return potioneffects.containsKey(PotionType.Lava); + } + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { if (Game.isMode("minicraft.settings.mode.creative") || hurtTime > 0 || Bed.inBed(this)) - return; // Can't get hurt in creative, hurt cooldown, or while someone is in bed + return false; // Can't get hurt in creative, hurt cooldown, or while someone is in bed int healthDam = 0, armorDam = 0; if (this == Game.player) { @@ -1236,33 +1226,12 @@ protected void hurt(int damage, Direction attackDir) { if (healthDam > 0 || this != Game.player) { level.add(new TextParticle("" + damage, x, y, Color.get(-1, 504))); - if (this == Game.player) super.hurt(healthDam, attackDir); // Sets knockback, and takes away health. - } - - Sound.play("playerhurt"); - hurtTime = playerHurtTime; - } - - /** - * Hurt the player directly. Don't use the armor as a shield. - * @param damage Amount of damage to do to player - * @param attackDir The direction of attack. - */ - private void directHurt(int damage, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative") || hurtTime > 0 || Bed.inBed(this)) - return; // Can't get hurt in creative, hurt cooldown, or while someone is in bed - - int healthDam = 0; - if (this == Game.player) { - healthDam = damage; // Subtract that amount - } - - if (healthDam > 0) { - super.hurt(healthDam, attackDir); // Sets knockback, and takes away health. + if (this == Game.player) handleDamage(source, attackDir, healthDam); // Sets knockback, and takes away health. } Sound.play("playerhurt"); hurtTime = playerHurtTime; + return true; } @Override diff --git a/src/client/java/minicraft/entity/mob/Snake.java b/src/client/java/minicraft/entity/mob/Snake.java index 253a799f7..c7eb66140 100644 --- a/src/client/java/minicraft/entity/mob/Snake.java +++ b/src/client/java/minicraft/entity/mob/Snake.java @@ -4,6 +4,7 @@ import minicraft.entity.Entity; import minicraft.gfx.SpriteLinker.LinkedSprite; import minicraft.item.Items; +import minicraft.util.DamageSource; public class Snake extends EnemyMob { private static LinkedSprite[][][] sprites = new LinkedSprite[][][] { @@ -18,11 +19,9 @@ public Snake(int lvl) { } @Override - protected void touchedBy(Entity entity) { - if (entity instanceof Player) { - int damage = lvl + Settings.getIdx("diff"); - entity.attack(this, null, getInteractionDir(this, entity), damage); - } + public boolean attack(Entity entity) { + return hurt(new DamageSource.EntityDamageSource(this, null), dir, + lvl + Settings.getIdx("diff")); } public void die() { diff --git a/src/client/java/minicraft/entity/particle/Particle.java b/src/client/java/minicraft/entity/particle/Particle.java index f7e9148e7..209262efb 100644 --- a/src/client/java/minicraft/entity/particle/Particle.java +++ b/src/client/java/minicraft/entity/particle/Particle.java @@ -8,6 +8,7 @@ import minicraft.item.Item; import minicraft.level.Level; import minicraft.level.tile.Tile; +import minicraft.util.DamageSource; import minicraft.util.Logging; import org.jetbrains.annotations.Nullable; @@ -80,5 +81,10 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } } diff --git a/src/client/java/minicraft/item/PotionType.java b/src/client/java/minicraft/item/PotionType.java index 67714a2be..45bc30019 100644 --- a/src/client/java/minicraft/item/PotionType.java +++ b/src/client/java/minicraft/item/PotionType.java @@ -31,7 +31,7 @@ public boolean toggleEffect(Player player, boolean addEffect) { Time(Color.get(1, 163), 1800), Lava(Color.get(1, 199, 58, 58), 7200), Shield(Color.get(1, 84, 84, 204), 5400), - Haste(Color.get(1, 201, 71, 201), 4800), + Haste(Color.get(1, 201, 71, 201), 4800), // Currently no use Escape(Color.get(1, 222, 162, 162), 0) { public boolean toggleEffect(Player player, boolean addEffect) { diff --git a/src/client/java/minicraft/item/ToolItem.java b/src/client/java/minicraft/item/ToolItem.java index 8fd610eca..419df4254 100644 --- a/src/client/java/minicraft/item/ToolItem.java +++ b/src/client/java/minicraft/item/ToolItem.java @@ -5,6 +5,7 @@ import minicraft.entity.Arrow; import minicraft.entity.Direction; import minicraft.entity.Entity; +import minicraft.entity.furniture.Spawner; import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; import minicraft.gfx.SpriteLinker.LinkedSprite; @@ -129,6 +130,11 @@ public int getAttackDamageBonus(Entity e) { } else if (type == ToolType.Pickaxe) return (level + 1) + random.nextInt(2); // Wood: 3-6 damage; gem: 15-66 damage. return 1; + } else if (e instanceof Spawner) { + if (type == ToolType.Pickaxe) { + return 3 + level + random.nextInt(7); + } else + return 1 + level + random.nextInt(2); } return 0; diff --git a/src/client/java/minicraft/level/tile/CactusTile.java b/src/client/java/minicraft/level/tile/CactusTile.java index f203f4299..1309119fd 100644 --- a/src/client/java/minicraft/level/tile/CactusTile.java +++ b/src/client/java/minicraft/level/tile/CactusTile.java @@ -12,8 +12,10 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.item.Items; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class CactusTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "cactus"); @@ -31,7 +33,14 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return false; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { + @Override + public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + hurt(level, x, y, damage); + return true; + } + + @Override + public void hurt(Level level, int x, int y, int dmg) { int damage = level.getData(x, y) + dmg; int cHealth = 10; if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = cHealth; @@ -46,7 +55,6 @@ public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction at } else { level.setData(x, y, damage); } - return true; } @Override @@ -59,11 +67,11 @@ public void bumpedInto(Level level, int x, int y, Entity entity) { if (!(entity instanceof Mob)) return; Mob m = (Mob) entity; if (Settings.get("diff").equals("minicraft.settings.difficulty.easy")) { - m.attack(this, level, x, y, m.dir.getOpposite(), 1); + m.attack(this, level, x, y, null, m.dir.getOpposite(), 1); } else if (Settings.get("diff").equals("minicraft.settings.difficulty.normal")) { - m.attack(this, level, x, y, m.dir.getOpposite(), 1); + m.attack(this, level, x, y, null, m.dir.getOpposite(), 1); } else if (Settings.get("diff").equals("minicraft.settings.difficulty.hard")) { - m.attack(this, level, x, y, m.dir.getOpposite(), 2); + m.attack(this, level, x, y, null, m.dir.getOpposite(), 2); } } diff --git a/src/client/java/minicraft/level/tile/CloudTile.java b/src/client/java/minicraft/level/tile/CloudTile.java index 937f36f7d..98589a117 100644 --- a/src/client/java/minicraft/level/tile/CloudTile.java +++ b/src/client/java/minicraft/level/tile/CloudTile.java @@ -12,6 +12,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class CloudTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "cloud") @@ -26,18 +27,19 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return true; } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + @Override + public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { // We don't want the tile to break when attacked with just anything, even in creative mode - if (item instanceof ToolItem) { + if (source instanceof Player && item instanceof ToolItem) { ToolItem tool = (ToolItem) item; - if (tool.type == ToolType.Shovel && player.payStamina(5)) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Infinite Fall")); // Would allow you to shovel cloud, I think. + if (tool.type == ToolType.Shovel && ((Player) source).payStamina(5)) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Infinite Fall")); // Would allow you to shovel cloud, I think. Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, 1, 3, Items.get("Cloud")); + level.dropItem((x << 4) + 8, (y << 4) + 8, 1, 3, Items.get("Cloud")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index 72bf5c18c..f5c035019 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -12,6 +12,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import minicraft.util.DamageSource; public class LavaBrickTile extends Tile { protected LavaBrickTile(String name) { @@ -38,7 +39,8 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir public void bumpedInto(Level level, int x, int y, Entity entity) { if (entity instanceof Mob) - entity.attack(this, level, x, y, ((Mob) entity).dir.getOpposite(), 3); + entity.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.LAVA_BRICK, level, entity.x, entity.y), + Direction.NONE, 3); } public boolean mayPass(Level level, int x, int y, Entity e) { diff --git a/src/client/java/minicraft/level/tile/Tile.java b/src/client/java/minicraft/level/tile/Tile.java index d5edb53d3..361459875 100644 --- a/src/client/java/minicraft/level/tile/Tile.java +++ b/src/client/java/minicraft/level/tile/Tile.java @@ -3,13 +3,13 @@ import minicraft.core.World; import minicraft.entity.Direction; import minicraft.entity.Entity; -import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.item.Item; import minicraft.item.ToolType; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; import java.util.Random; @@ -89,28 +89,14 @@ public int getLightRadius(Level level, int x, int y) { } /** - * Hurt the tile with a specified amount of damage. - * @param level The level this happened on. - * @param x X pos of the tile. - * @param y Y pos of the tile. - * @param source The mob that damaged the tile. - * @param dmg Damage to taken. - * @param attackDir The direction of the player hitting. - * @return If the damage was applied. - */ - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - return false; - } - - /** - * Hurt the tile with a specified amount of damage. + * Hurt the tile with a specified amount of damage directly. This is supposed to be used internally. + * Using {@link #attack(Level, int, int, Entity, Item, Direction, int)} is more recommended. * @param level The level this happened on. * @param x X position of the tile. * @param y Y position of the tile. * @param dmg The damage taken. */ - public void hurt(Level level, int x, int y, int dmg) { - } + public void hurt(Level level, int x, int y, int dmg) {} /** * What happens when you run into the tile (ex: run into a cactus) @@ -134,19 +120,20 @@ public void steppedOn(Level level, int xt, int yt, Entity entity) { /** * Called when you hit an item on a tile (ex: Pickaxe on rock). * @param level The level the player is on. - * @param xt X position of the player in tile coordinates (32x per tile). - * @param yt Y position of the player in tile coordinates (32px per tile). - * @param player The player who called this method. + * @param x X position of the player in tile coordinates (32x per tile). + * @param y Y position of the player in tile coordinates (32px per tile). + * @param source The entity attacking. * @param item The item the player is currently holding. * @param attackDir The direction of the player attacking. + * @param damage The amount of damage intended to emit this time * @return Was the operation successful? */ - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { return false; } /** - * Called when you interact an item on a tile (ex: Pickaxe on rock). + * Called when you use an item on a tile (ex: Pickaxe on rock). * @param level The level the player is on. * @param xt X position of the player in tile coordinates (32x per tile). * @param yt Y position of the player in tile coordinates (32px per tile). @@ -155,10 +142,19 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir * @param attackDir The direction of the player attacking. * @return Was the operation successful? */ - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean use(Level level, int xt, int yt, Player player, @Nullable Item item, Direction attackDir) { return false; } + /** + * Picks up this tile + * @param player The player interacting + * @return the item picked up; {@code null} if picking up failed + */ + public @Nullable Item take(Player player) { + return null; + } + /** * Executed when the tile is exploded. * The call for this method is done just before the tiles are changed to exploded tiles. diff --git a/src/client/java/minicraft/util/DamageSource.java b/src/client/java/minicraft/util/DamageSource.java new file mode 100644 index 000000000..21090f8a1 --- /dev/null +++ b/src/client/java/minicraft/util/DamageSource.java @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: 2024 Minicraft+ contributors + * SPDX-License-Identifier: GPL-3.0-only + */ + +package minicraft.util; + +import minicraft.entity.Entity; +import minicraft.gfx.Point; +import minicraft.item.Item; +import minicraft.level.Level; +import minicraft.level.tile.Tile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class DamageSource { + @NotNull + public abstract Level getLevel(); + + /** Get position of damage source based on entity coordinates. */ + @NotNull + public abstract Point getPosition(); + + public static class TileDamageSource extends DamageSource { + private final @NotNull Tile tile; + private final @NotNull Level level; + private final int x, y; + + public TileDamageSource(@NotNull Tile tile, @NotNull Level level, int x, int y) { + this.tile = tile; + this.level = level; + this.x = x; + this.y = y; + } + + public @NotNull Tile getTile() { + return tile; + } + + @Override + public @NotNull Level getLevel() { + return level; + } + + @Override + public @NotNull Point getPosition() { + return new Point((x << 4) + 8, (y << 4) + 8); + } + } + + public static class EntityDamageSource extends DamageSource { + private final @NotNull Entity entity; + private final @Nullable Item item; + + public EntityDamageSource(@NotNull Entity entity, @Nullable Item item) { + this.entity = entity; + this.item = item; + } + + public @NotNull Entity getEntity() { + return entity; + } + + /** Gets the item the entity is holding */ + public @Nullable Item getItem() { + return item; + } + + @Override + public @NotNull Level getLevel() { + return entity.getLevel(); + } + + @Override + public @NotNull Point getPosition() { + return new Point(entity.x, entity.y); + } + } + + public static class OtherDamageSource extends DamageSource { + private final @NotNull Level level; + private final int x, y; + private final @NotNull DamageType damageType; + private final @Nullable Entity causingEntity; + + public enum DamageType { + IN_FIRE, ON_FIRE, LAVA, EXPLOSION, DRONE, STARVE, ARROW, SPARK, LAVA_BRICK; + + public boolean isFireRelated() { + return this == IN_FIRE || this == ON_FIRE || this == LAVA || this == LAVA_BRICK; + } + } + + public OtherDamageSource(@NotNull DamageType damageType, @NotNull Level level, int x, int y) { + this.damageType = damageType; + this.level = level; + this.x = x; + this.y = y; + this.causingEntity = null; + } + + public OtherDamageSource(@NotNull DamageType damageType, @NotNull Entity causingEntity) { + this.damageType = damageType; + this.causingEntity = causingEntity; + this.level = causingEntity.getLevel(); + this.x = causingEntity.x; + this.y = causingEntity.y; + } + + public @Nullable Entity getCausingEntity() { + return causingEntity; + } + + public @NotNull DamageType getDamageType() { + return damageType; + } + + @Override + public @NotNull Level getLevel() { + return level; + } + + @Override + public @NotNull Point getPosition() { + return new Point(x, y); + } + } +} From 8ae3beaeb810e5a7f07440ae666e7e7958be6b18 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Tue, 13 Aug 2024 00:17:46 +0800 Subject: [PATCH 10/14] Update tile interaction handling system --- src/client/java/minicraft/entity/Arrow.java | 2 +- src/client/java/minicraft/entity/Entity.java | 7 +- src/client/java/minicraft/entity/Spark.java | 2 +- .../minicraft/entity/furniture/Spawner.java | 7 +- .../java/minicraft/entity/mob/Creeper.java | 2 +- .../java/minicraft/entity/mob/EnemyMob.java | 2 +- src/client/java/minicraft/entity/mob/Mob.java | 7 +- .../minicraft/entity/mob/ObsidianKnight.java | 5 +- .../java/minicraft/entity/mob/Player.java | 12 +- .../java/minicraft/entity/mob/Snake.java | 2 +- .../minicraft/level/tile/BossDoorTile.java | 15 +- .../minicraft/level/tile/BossFloorTile.java | 11 +- .../minicraft/level/tile/BossWallTile.java | 11 +- .../java/minicraft/level/tile/CactusTile.java | 25 ++- .../java/minicraft/level/tile/CloudTile.java | 5 +- .../minicraft/level/tile/ConnectTile.java | 5 + .../java/minicraft/level/tile/DecorTile.java | 21 +- .../java/minicraft/level/tile/DirtTile.java | 5 + .../java/minicraft/level/tile/DoorTile.java | 22 +- .../minicraft/level/tile/ExplodedTile.java | 5 + .../java/minicraft/level/tile/FenceTile.java | 20 +- .../java/minicraft/level/tile/FloorTile.java | 21 +- .../java/minicraft/level/tile/FlowerTile.java | 12 +- .../java/minicraft/level/tile/GrassTile.java | 34 +-- .../minicraft/level/tile/HardRockTile.java | 33 +-- .../java/minicraft/level/tile/HoleTile.java | 5 + .../level/tile/InfiniteFallTile.java | 5 + .../minicraft/level/tile/LavaBrickTile.java | 19 +- .../java/minicraft/level/tile/LavaTile.java | 5 + .../minicraft/level/tile/MaterialTile.java | 21 +- .../java/minicraft/level/tile/OreTile.java | 27 +-- .../java/minicraft/level/tile/PathTile.java | 20 +- .../java/minicraft/level/tile/RockTile.java | 43 ++-- .../java/minicraft/level/tile/SandTile.java | 19 +- .../minicraft/level/tile/SaplingTile.java | 9 +- .../java/minicraft/level/tile/SignTile.java | 40 ++-- .../java/minicraft/level/tile/StairsTile.java | 12 +- .../java/minicraft/level/tile/Tile.java | 8 +- .../java/minicraft/level/tile/TorchTile.java | 16 +- .../java/minicraft/level/tile/TreeTile.java | 34 ++- .../java/minicraft/level/tile/WallTile.java | 38 ++-- .../java/minicraft/level/tile/WaterTile.java | 5 + .../java/minicraft/level/tile/WoolTile.java | 21 +- .../level/tile/entity/SignTileEntity.java | 8 +- .../level/tile/farming/CropTile.java | 11 +- .../level/tile/farming/FarmTile.java | 17 +- .../java/minicraft/util/DamageSource.java | 194 +++++++++--------- 47 files changed, 502 insertions(+), 368 deletions(-) diff --git a/src/client/java/minicraft/entity/Arrow.java b/src/client/java/minicraft/entity/Arrow.java index e2c28466d..a693b7382 100644 --- a/src/client/java/minicraft/entity/Arrow.java +++ b/src/client/java/minicraft/entity/Arrow.java @@ -76,7 +76,7 @@ public void tick() { if (hit instanceof Mob && hit != owner) { Mob mob = (Mob) hit; damage += (hit instanceof Player ? 0 : 3) + (criticalHit ? 0 : 1); // Extra damage bonus. - mob.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.ARROW, owner), + mob.hurt(new DamageSource(DamageSource.DamageType.ARROW, owner, this, null), dir, damage); // normal hurting to other mobs } diff --git a/src/client/java/minicraft/entity/Entity.java b/src/client/java/minicraft/entity/Entity.java index ea7c0fcea..b511b9d85 100644 --- a/src/client/java/minicraft/entity/Entity.java +++ b/src/client/java/minicraft/entity/Entity.java @@ -190,11 +190,8 @@ protected int baseDamage() { public boolean isInvulnerableTo(DamageSource source) { return isRemoved() || - source instanceof DamageSource.EntityDamageSource && - ((DamageSource.EntityDamageSource) source).getEntity() instanceof Player && - Game.isMode("minicraft.settings.mode.creative") || - source instanceof DamageSource.OtherDamageSource && - ((DamageSource.OtherDamageSource) source).getDamageType().isFireRelated() && isFireImmune(); + source.getCausingEntity() instanceof Player && Game.isMode("minicraft.settings.mode.creative") || + source.getDamageType().isFireRelated() && isFireImmune(); } /** diff --git a/src/client/java/minicraft/entity/Spark.java b/src/client/java/minicraft/entity/Spark.java index bd84c8a8c..3a66b546a 100644 --- a/src/client/java/minicraft/entity/Spark.java +++ b/src/client/java/minicraft/entity/Spark.java @@ -56,7 +56,7 @@ public void tick() { Player player = getClosestPlayer(); if (player != null && player.isWithin(0, this)) { - player.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.SPARK, owner), + player.hurt(new DamageSource(DamageSource.DamageType.SPARK, owner, this, null), getInteractionDir(this, player), 1); } } diff --git a/src/client/java/minicraft/entity/furniture/Spawner.java b/src/client/java/minicraft/entity/furniture/Spawner.java index 31cb61bf9..33c2cd21c 100644 --- a/src/client/java/minicraft/entity/furniture/Spawner.java +++ b/src/client/java/minicraft/entity/furniture/Spawner.java @@ -177,9 +177,8 @@ private void trySpawn() { @Override public boolean hurt(DamageSource source, Direction attackDir, int damage) { - if (source instanceof DamageSource.EntityDamageSource && - ((DamageSource.EntityDamageSource) source).getEntity() instanceof Player) { - Item item = ((DamageSource.EntityDamageSource) source).getItem(); + if (source.getCausingEntity() instanceof Player) { + Item item = source.getItem(); Sound.play("monsterhurt"); int dmg = item instanceof ToolItem ? ((ToolItem) item).getAttackDamageBonus(this) : 1; if (Game.isMode("minicraft.settings.mode.creative")) @@ -190,7 +189,7 @@ public boolean hurt(DamageSource source, Direction attackDir, int damage) { if (health <= 0) { level.remove(this); Sound.play("death"); - ((Player) ((DamageSource.EntityDamageSource) source).getEntity()).addScore(500); + ((Player) source.getCausingEntity()).addScore(500); } return true; diff --git a/src/client/java/minicraft/entity/mob/Creeper.java b/src/client/java/minicraft/entity/mob/Creeper.java index f4ff5e193..9b70716e4 100644 --- a/src/client/java/minicraft/entity/mob/Creeper.java +++ b/src/client/java/minicraft/entity/mob/Creeper.java @@ -98,7 +98,7 @@ public void tick() { int distx = Math.abs(mob.x - x); int disty = Math.abs(mob.y - y); float distDiag = (float) Math.sqrt(distx * distx + disty * disty); - entity.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.EXPLOSION, level, x, y), + entity.hurt(new DamageSource(DamageSource.DamageType.EXPLOSION, this, null), getInteractionDir(this, mob), (int) (lvlDamage * (1 / (distDiag + 1)) + Settings.getIdx("diff"))); } else if (entity instanceof Spawner) { diff --git a/src/client/java/minicraft/entity/mob/EnemyMob.java b/src/client/java/minicraft/entity/mob/EnemyMob.java index d76c5adab..b8b3e4d9b 100644 --- a/src/client/java/minicraft/entity/mob/EnemyMob.java +++ b/src/client/java/minicraft/entity/mob/EnemyMob.java @@ -120,7 +120,7 @@ protected void touchedBy(Entity entity) { // If an entity (like the player) touc @Override public boolean attack(Entity entity) { - return hurt(new DamageSource.EntityDamageSource(this, null), dir, + return hurt(new DamageSource(DamageSource.DamageType.GENERIC, this, null), dir, lvl * (Settings.get("diff").equals("minicraft.settings.difficulty.hard") ? 2 : 1)); } diff --git a/src/client/java/minicraft/entity/mob/Mob.java b/src/client/java/minicraft/entity/mob/Mob.java index 211d8657b..ae3f0b493 100644 --- a/src/client/java/minicraft/entity/mob/Mob.java +++ b/src/client/java/minicraft/entity/mob/Mob.java @@ -59,8 +59,7 @@ public void tick() { if (level != null && level.getTile(x >> 4, y >> 4) == Tiles.get("lava")) // If we are trying to swim in lava // Inflict 4 damage to ourselves, sourced from the lava Tile, with the direction as the opposite of ours. - hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.LAVA, level, x >> 4, y >> 4), - Direction.NONE, 4); + hurt(new DamageSource(DamageSource.DamageType.LAVA, level, x, y, Tiles.get("lava")), Direction.NONE, 4); if (canBurn()) { if (this.burningDuration > 0) { @@ -69,7 +68,7 @@ public void tick() { level.add(new BurnParticle(x - 8 + (random.nextInt(8) - 4), y - 8 + (random.nextInt(8) - 4))); this.burningDuration--; // TODO different damage? - hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.ON_FIRE, level, x, y), + hurt(new DamageSource(DamageSource.DamageType.ON_FIRE, level, x, y, null), // TODO last attacker Direction.NONE, this instanceof Player ? 1 : 2); //burning damage } } @@ -242,7 +241,7 @@ public void burn(int sec) { * @param dmg The amount of damage the explosion does. */ public void onExploded(Tnt tnt, int dmg) { - hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.EXPLOSION, level, x, y), + hurt(new DamageSource(DamageSource.DamageType.EXPLOSION, tnt, null), getInteractionDir(tnt, this), dmg); } diff --git a/src/client/java/minicraft/entity/mob/ObsidianKnight.java b/src/client/java/minicraft/entity/mob/ObsidianKnight.java index dd03e1ce5..f14d97ccf 100644 --- a/src/client/java/minicraft/entity/mob/ObsidianKnight.java +++ b/src/client/java/minicraft/entity/mob/ObsidianKnight.java @@ -209,9 +209,8 @@ public boolean hurt(DamageSource source, Direction attackDir, int damage) { attackDelay = 60 * 2; } - if (source instanceof DamageSource.EntityDamageSource && - ((DamageSource.EntityDamageSource) source).getEntity() instanceof Arrow && phase == 0) { - ((DamageSource.EntityDamageSource) source).getEntity().remove(); + if (source.getDirectEntity() instanceof Arrow && phase == 0) { + source.getDirectEntity().remove(); return false; } diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index db6eee064..bb0ba6126 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -432,7 +432,7 @@ public void tick() { if (hunger == 0 && health > minStarveHealth[diffIdx]) { if (hungerStarveDelay > 0) hungerStarveDelay--; if (hungerStarveDelay == 0) { - hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.STARVE, level, x, y), + hurt(new DamageSource(DamageSource.DamageType.STARVE), Direction.NONE, 1); // Do 1 damage to the player } } @@ -487,7 +487,7 @@ public void tick() { if (isSwimming() && tickTime % 60 == 0 && !potioneffects.containsKey(PotionType.Swim)) { // If drowning... :P if (stamina > 0) payStamina(1); // Take away stamina else - hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.DRONE, level, x, y), + hurt(new DamageSource(DamageSource.DamageType.DROWN), Direction.NONE, 1); // If no stamina, take damage. } @@ -645,7 +645,7 @@ protected void attack() { done = true; // Returns true if the target tile successfully interacts with the item. - } else if (tile.attack(level, t.x, t.y, this, activeItem, attackDir, 1)) { + } else if (tile.hurt(level, t.x, t.y, this, activeItem, attackDir, 1)) { done = true; } } @@ -673,7 +673,7 @@ protected void attack() { // Check if tile is in bounds of the map. if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { Tile tile = level.getTile(t.x, t.y); - used = tile.attack(level, t.x, t.y, this, null, attackDir, random.nextInt(3) + 1) || used; + used = tile.hurt(level, t.x, t.y, this, null, attackDir, random.nextInt(3) + 1) || used; } if (used && activeItem instanceof ToolItem) @@ -840,7 +840,7 @@ private boolean attack(Rectangle area) { boolean sucessful = false; for (Entity e : entities) { if (e != this && e.isAttackable(this, activeItem, attackDir) && - !e.isInvulnerableTo(new DamageSource.EntityDamageSource(this, activeItem))) { + !e.isInvulnerableTo(new DamageSource(DamageSource.DamageType.GENERIC, this, activeItem))) { sucessful |= attack(e); } } @@ -853,7 +853,7 @@ public boolean attack(Entity entity) { if (activeItem != null && activeItem instanceof ToolItem) { dmg += ((ToolItem) activeItem).getAttackDamageBonus(entity); // Sword/Axe are more effective at dealing damage. } - return entity.hurt(new DamageSource.EntityDamageSource(this, activeItem), attackDir, dmg); + return entity.hurt(new DamageSource(DamageSource.DamageType.GENERIC, this, activeItem), attackDir, dmg); } /** diff --git a/src/client/java/minicraft/entity/mob/Snake.java b/src/client/java/minicraft/entity/mob/Snake.java index c7eb66140..c4f65ccf4 100644 --- a/src/client/java/minicraft/entity/mob/Snake.java +++ b/src/client/java/minicraft/entity/mob/Snake.java @@ -20,7 +20,7 @@ public Snake(int lvl) { @Override public boolean attack(Entity entity) { - return hurt(new DamageSource.EntityDamageSource(this, null), dir, + return hurt(new DamageSource( DamageSource.DamageType.GENERIC,this, null), dir, lvl + Settings.getIdx("diff")); } diff --git a/src/client/java/minicraft/level/tile/BossDoorTile.java b/src/client/java/minicraft/level/tile/BossDoorTile.java index c8c75d365..71e0f444e 100644 --- a/src/client/java/minicraft/level/tile/BossDoorTile.java +++ b/src/client/java/minicraft/level/tile/BossDoorTile.java @@ -4,12 +4,14 @@ import minicraft.core.io.Localization; import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.entity.mob.ObsidianKnight; import minicraft.entity.mob.Player; import minicraft.item.Item; import minicraft.item.ToolItem; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class BossDoorTile extends DoorTile { private static final String doorMsg = "minicraft.notification.defeat_obsidian_knight_first"; @@ -18,12 +20,13 @@ protected BossDoorTile() { super(Material.Obsidian, "Boss Door"); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative") && source instanceof Player) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(1)) { + if (((Player) source).payStamina(1)) { Game.notifications.add(Localization.getLocalized(doorMsg)); Sound.play("monsterhurt"); return true; @@ -34,16 +37,16 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - return super.attack(level, xt, yt, player, item, attackDir); + return super.hurt(level, x, y, source, item, attackDir, damage); } @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean use(Level level, int xt, int yt, Player player, @Nullable Item item, Direction attackDir) { if (ObsidianKnight.active && !Game.isMode("minicraft.settings.mode.creative")) { Game.notifications.add(doorMsg); return true; } - return super.interact(level, xt, yt, player, item, attackDir); + return super.use(level, xt, yt, player, item, attackDir); } } diff --git a/src/client/java/minicraft/level/tile/BossFloorTile.java b/src/client/java/minicraft/level/tile/BossFloorTile.java index 452545bdb..95393ed26 100644 --- a/src/client/java/minicraft/level/tile/BossFloorTile.java +++ b/src/client/java/minicraft/level/tile/BossFloorTile.java @@ -4,11 +4,13 @@ import minicraft.core.io.Localization; import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.ObsidianKnight; import minicraft.entity.mob.Player; import minicraft.item.Item; import minicraft.item.ToolItem; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class BossFloorTile extends FloorTile { private static final String floorMsg = "minicraft.notification.defeat_obsidian_knight_first"; @@ -17,12 +19,13 @@ protected BossFloorTile() { super(Material.Obsidian, "Boss Floor"); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative") && source instanceof Player) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(1)) { + if (((Player) source).payStamina(1)) { Game.notifications.add(Localization.getLocalized(floorMsg)); Sound.play("monsterhurt"); return true; @@ -33,6 +36,6 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - return super.attack(level, xt, yt, player, item, attackDir); + return super.hurt(level, x, y, source, item, attackDir, damage); } } diff --git a/src/client/java/minicraft/level/tile/BossWallTile.java b/src/client/java/minicraft/level/tile/BossWallTile.java index 120107145..b0c2c843c 100644 --- a/src/client/java/minicraft/level/tile/BossWallTile.java +++ b/src/client/java/minicraft/level/tile/BossWallTile.java @@ -4,6 +4,7 @@ import minicraft.core.io.Localization; import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.ObsidianKnight; import minicraft.entity.mob.Player; import minicraft.gfx.SpriteAnimation; @@ -11,6 +12,7 @@ import minicraft.item.Item; import minicraft.item.ToolItem; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class BossWallTile extends WallTile { private static SpriteAnimation obsidian = new SpriteAnimation(SpriteLinker.SpriteType.Tile, "obsidian_wall") @@ -23,12 +25,13 @@ protected BossWallTile() { sprite = obsidian; // Renewing the connectivity. } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative")) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if ((!ObsidianKnight.beaten || ObsidianKnight.active) && !Game.isMode("minicraft.settings.mode.creative") && source instanceof Player) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(1)) { + if (((Player) source).payStamina(1)) { Game.notifications.add(Localization.getLocalized(wallMsg)); Sound.play("monsterhurt"); return true; @@ -39,6 +42,6 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - return super.attack(level, xt, yt, player, item, attackDir); + return super.hurt(level, x, y, source, item, attackDir, damage); } } diff --git a/src/client/java/minicraft/level/tile/CactusTile.java b/src/client/java/minicraft/level/tile/CactusTile.java index 1309119fd..daac66fa5 100644 --- a/src/client/java/minicraft/level/tile/CactusTile.java +++ b/src/client/java/minicraft/level/tile/CactusTile.java @@ -15,9 +15,12 @@ import minicraft.item.Item; import minicraft.item.Items; import minicraft.level.Level; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class CactusTile extends Tile { + private static final int MAX_HEALTH = 10; + private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "cactus"); protected CactusTile(String name) { @@ -34,20 +37,21 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { - hurt(level, x, y, damage); + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, MAX_HEALTH); + } else + handleDamage(level, x, y, source, item, damage); return true; } @Override - public void hurt(Level level, int x, int y, int dmg) { + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { int damage = level.getData(x, y) + dmg; - int cHealth = 10; - if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = cHealth; level.add(new SmashParticle(x << 4, y << 4)); level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); - if (damage >= cHealth) { + if (damage >= MAX_HEALTH) { //int count = random.nextInt(2) + 2; level.setTile(x, y, Tiles.get("sand")); Sound.play("monsterhurt"); @@ -67,11 +71,14 @@ public void bumpedInto(Level level, int x, int y, Entity entity) { if (!(entity instanceof Mob)) return; Mob m = (Mob) entity; if (Settings.get("diff").equals("minicraft.settings.difficulty.easy")) { - m.attack(this, level, x, y, null, m.dir.getOpposite(), 1); + m.hurt(new DamageSource(DamageSource.DamageType.CACTUS, level, (x << 4) + 8, (y << 4) + 8, this), + m.dir.getOpposite(), 1); } else if (Settings.get("diff").equals("minicraft.settings.difficulty.normal")) { - m.attack(this, level, x, y, null, m.dir.getOpposite(), 1); + m.hurt(new DamageSource(DamageSource.DamageType.CACTUS, level, (x << 4) + 8, (y << 4) + 8, this), + m.dir.getOpposite(), 1); } else if (Settings.get("diff").equals("minicraft.settings.difficulty.hard")) { - m.attack(this, level, x, y, null, m.dir.getOpposite(), 2); + m.hurt(new DamageSource(DamageSource.DamageType.CACTUS, level, (x << 4) + 8, (y << 4) + 8, this), + m.dir.getOpposite(), 2); } } diff --git a/src/client/java/minicraft/level/tile/CloudTile.java b/src/client/java/minicraft/level/tile/CloudTile.java index 98589a117..34dcbd544 100644 --- a/src/client/java/minicraft/level/tile/CloudTile.java +++ b/src/client/java/minicraft/level/tile/CloudTile.java @@ -28,7 +28,10 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { // We don't want the tile to break when attacked with just anything, even in creative mode if (source instanceof Player && item instanceof ToolItem) { ToolItem tool = (ToolItem) item; diff --git a/src/client/java/minicraft/level/tile/ConnectTile.java b/src/client/java/minicraft/level/tile/ConnectTile.java index f46f1a197..d7e144e8c 100644 --- a/src/client/java/minicraft/level/tile/ConnectTile.java +++ b/src/client/java/minicraft/level/tile/ConnectTile.java @@ -4,7 +4,9 @@ import minicraft.entity.Entity; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; // TODO Remove this. // IMPORTANT: This tile should never be used for anything, it only exists to allow tiles right next to the edge of the world to connect to it @@ -18,6 +20,9 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return false; } + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + @Override public boolean maySpawn() { return false; diff --git a/src/client/java/minicraft/level/tile/DecorTile.java b/src/client/java/minicraft/level/tile/DecorTile.java index e0aea9077..17861df3f 100644 --- a/src/client/java/minicraft/level/tile/DecorTile.java +++ b/src/client/java/minicraft/level/tile/DecorTile.java @@ -12,6 +12,7 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class DecorTile extends Tile { private static final SpriteAnimation stoneSprite = new SpriteAnimation(SpriteType.Tile, "ornate_stone"); @@ -55,16 +56,20 @@ public void render(Screen screen, Level level, int x, int y) { screen.render(x * 16 + 0, y * 16, sprite.getCurrentFrame().getSprite().spritePixels[0][0]); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == mType.getRequiredTool()) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); if (level.depth == 1) { - level.setTile(xt, yt, Tiles.get("Cloud")); + level.setTile(x, y, Tiles.get("Cloud")); } else { - level.setTile(xt, yt, Tiles.get("Hole")); + level.setTile(x, y, Tiles.get("Hole")); } Item drop; switch (thisType) { @@ -81,10 +86,10 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir throw new IllegalStateException("Unexpected value: " + thisType); } Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, drop); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/DirtTile.java b/src/client/java/minicraft/level/tile/DirtTile.java index 16bedf0ee..cf2e7259c 100644 --- a/src/client/java/minicraft/level/tile/DirtTile.java +++ b/src/client/java/minicraft/level/tile/DirtTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.Color; import minicraft.gfx.Screen; @@ -13,6 +14,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class DirtTile extends Tile { private static SpriteAnimation[] levelSprite = new SpriteAnimation[] { @@ -54,6 +56,9 @@ public void render(Screen screen, Level level, int x, int y) { levelSprite[dIdx(level.depth)].render(screen, level, x, y); } + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { if (item instanceof ToolItem) { ToolItem tool = (ToolItem) item; diff --git a/src/client/java/minicraft/level/tile/DoorTile.java b/src/client/java/minicraft/level/tile/DoorTile.java index 0744e17a1..1c1ebfb20 100644 --- a/src/client/java/minicraft/level/tile/DoorTile.java +++ b/src/client/java/minicraft/level/tile/DoorTile.java @@ -13,6 +13,7 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class DoorTile extends Tile { protected Material type; @@ -49,18 +50,22 @@ public void render(Screen screen, Level level, int x, int y) { curSprite.render(screen, level, x, y); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get((short) (id + 3))); // Will get the corresponding floor tile. + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) (id + 3))); // Will get the corresponding floor tile. Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get(type.name() + " Door")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get(type.name() + " Door")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -68,7 +73,8 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + @Override + public boolean use(Level level, int xt, int yt, Player player, @Nullable Item item, Direction attackDir) { boolean closed = level.getData(xt, yt) == 0; level.setData(xt, yt, closed ? 1 : 0); return true; diff --git a/src/client/java/minicraft/level/tile/ExplodedTile.java b/src/client/java/minicraft/level/tile/ExplodedTile.java index b79123d94..05dc831a7 100644 --- a/src/client/java/minicraft/level/tile/ExplodedTile.java +++ b/src/client/java/minicraft/level/tile/ExplodedTile.java @@ -3,7 +3,9 @@ import minicraft.entity.Entity; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; /// This class is for tiles WHILE THEY ARE EXPLODING public class ExplodedTile extends Tile { @@ -27,4 +29,7 @@ public boolean connectsToSand(Level level, int x, int y) { public boolean mayPass(Level level, int x, int y, Entity e) { return true; } + + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} } diff --git a/src/client/java/minicraft/level/tile/FenceTile.java b/src/client/java/minicraft/level/tile/FenceTile.java index c62f84ab6..8dd7d6c3b 100644 --- a/src/client/java/minicraft/level/tile/FenceTile.java +++ b/src/client/java/minicraft/level/tile/FenceTile.java @@ -15,6 +15,7 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class FenceTile extends Tile { @@ -101,26 +102,23 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - hurt(level, x, y, dmg); - return true; - } + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { if (Game.isMode("minicraft.settings.mode.creative")) return false; // Go directly to hurt method - if (item instanceof ToolItem) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); Sound.play("monsterhurt"); - level.dropItem(xt * 16 + 8, yt * 16 + 8, Items.get(name)); - level.setTile(xt, yt, Tiles.get((short) level.getData(xt, yt))); + level.dropItem(x * 16 + 8, y * 16 + 8, Items.get(name)); + level.setTile(x, y, Tiles.get((short) level.getData(x, y))); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/FloorTile.java b/src/client/java/minicraft/level/tile/FloorTile.java index 1f15bda45..ca13448a2 100644 --- a/src/client/java/minicraft/level/tile/FloorTile.java +++ b/src/client/java/minicraft/level/tile/FloorTile.java @@ -11,6 +11,7 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class FloorTile extends Tile { protected Material type; @@ -36,16 +37,17 @@ protected FloorTile(Material type, String name) { } } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); if (level.depth == 1) { - level.setTile(xt, yt, Tiles.get("Cloud")); + level.setTile(x, y, Tiles.get("Cloud")); } else { - level.setTile(xt, yt, Tiles.get("Hole")); + level.setTile(x, y, Tiles.get("Hole")); } Item drop; switch (type) { @@ -57,10 +59,10 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir break; } Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, drop); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -71,4 +73,7 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir public boolean mayPass(Level level, int x, int y, Entity e) { return true; } + + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} } diff --git a/src/client/java/minicraft/level/tile/FlowerTile.java b/src/client/java/minicraft/level/tile/FlowerTile.java index 97262fde4..59e3f2ea9 100644 --- a/src/client/java/minicraft/level/tile/FlowerTile.java +++ b/src/client/java/minicraft/level/tile/FlowerTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; import minicraft.gfx.Screen; @@ -13,6 +14,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class FlowerTile extends Tile { private static final SpriteAnimation flowerSprite0 = new SpriteAnimation(SpriteType.Tile, "flower_shape0"); @@ -51,11 +53,15 @@ public void render(Screen screen, Level level, int x, int y) { (shape == 0 ? flowerSprite0 : flowerSprite1).render(screen, level, x, y); } - public boolean attack(Level level, int x, int y, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(2 - tool.level) && tool.payDurability()) { + if (((Player) source).payStamina(2 - tool.level) && tool.payDurability()) { int data = level.getData(x, y); level.setTile(x, y, Tiles.get("Grass")); Sound.play("monsterhurt"); diff --git a/src/client/java/minicraft/level/tile/GrassTile.java b/src/client/java/minicraft/level/tile/GrassTile.java index a6ed6454b..080a90c01 100644 --- a/src/client/java/minicraft/level/tile/GrassTile.java +++ b/src/client/java/minicraft/level/tile/GrassTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; @@ -12,6 +13,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class GrassTile extends Tile { private static final SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "grass") @@ -50,40 +52,44 @@ public void render(Screen screen, Level level, int x, int y) { sprite.render(screen, level, x, y); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Dirt")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Dirt")); Sound.play("monsterhurt"); if (random.nextInt(5) == 0) { // 20% chance to drop Grass seeds - level.dropItem((xt << 4) + 8, (yt << 4) + 8, 1, Items.get("Grass Seeds")); + level.dropItem((x << 4) + 8, (y << 4) + 8, 1, Items.get("Grass Seeds")); } AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } if (tool.type == ToolType.Hoe) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Farmland")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Farmland")); Sound.play("monsterhurt"); if (random.nextInt(5) != 0) { // 80% chance to drop Wheat seeds - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get("Wheat Seeds")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Wheat Seeds")); } AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } if (tool.type == ToolType.Pickaxe) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - level.setTile(xt, yt, Tiles.get("Path")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + level.setTile(x, y, Tiles.get("Path")); Sound.play("monsterhurt"); } } diff --git a/src/client/java/minicraft/level/tile/HardRockTile.java b/src/client/java/minicraft/level/tile/HardRockTile.java index 7f2ee9030..239e529c7 100644 --- a/src/client/java/minicraft/level/tile/HardRockTile.java +++ b/src/client/java/minicraft/level/tile/HardRockTile.java @@ -18,8 +18,11 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class HardRockTile extends Tile { + private static final int MAX_HEALTH = 200; + // Theoretically the full sprite should never be used, so we can use a placeholder private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "hardrock") .setConnectionChecker((level, x, y, tile, side) -> tile instanceof HardRockTile) @@ -33,25 +36,24 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return false; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - hurt(level, x, y, 0); - return true; - } + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, MAX_HEALTH); + return true; + } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative")) - return false; // Go directly to hurt method - if (item instanceof ToolItem) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; // If we are hitting with a gem pickaxe. if (tool.type == ToolType.Pickaxe && tool.level == 4) { - if (player.payStamina(2) && tool.payDurability()) { - int data = level.getData(xt, yt); - hurt(level, xt, yt, tool.getDamage()); + if (((Player) source).payStamina(2) && tool.payDurability()) { + int data = level.getData(x, y); + handleDamage(level, x, y, source, item, tool.getDamage()); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } else { @@ -61,15 +63,14 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - public void hurt(Level level, int x, int y, int dmg) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { int damage = level.getData(x, y) + dmg; - int hrHealth = 200; - if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = hrHealth; level.add(new SmashParticle(x << 4, y << 4)); Sound.play("monsterhurt"); level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); - if (damage >= hrHealth) { + if (damage >= MAX_HEALTH) { level.setTile(x, y, Tiles.get("dirt")); level.dropItem((x << 4) + 8, (y << 4) + 8, 1, 3, Items.get("Stone")); level.dropItem((x << 4) + 8, (y << 4) + 8, 0, 1, Items.get("Coal")); diff --git a/src/client/java/minicraft/level/tile/HoleTile.java b/src/client/java/minicraft/level/tile/HoleTile.java index a55474fd9..ce6a289a8 100644 --- a/src/client/java/minicraft/level/tile/HoleTile.java +++ b/src/client/java/minicraft/level/tile/HoleTile.java @@ -4,7 +4,9 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class HoleTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "hole") @@ -35,4 +37,7 @@ public void render(Screen screen, Level level, int x, int y) { public boolean mayPass(Level level, int x, int y, Entity e) { return e.canSwim(); } + + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} } diff --git a/src/client/java/minicraft/level/tile/InfiniteFallTile.java b/src/client/java/minicraft/level/tile/InfiniteFallTile.java index 4b660d852..453ecb3f0 100644 --- a/src/client/java/minicraft/level/tile/InfiniteFallTile.java +++ b/src/client/java/minicraft/level/tile/InfiniteFallTile.java @@ -7,7 +7,9 @@ import minicraft.entity.mob.Player; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class InfiniteFallTile extends Tile { @@ -28,4 +30,7 @@ public boolean tick(Level level, int xt, int yt) { public boolean mayPass(Level level, int x, int y, Entity e) { return e instanceof AirWizard || e instanceof Arrow || e instanceof Player && Game.isMode("minicraft.settings.mode.creative"); } + + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} } diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index f5c035019..34d2bb17e 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -13,23 +13,28 @@ import minicraft.level.Level; import minicraft.util.AdvancementElement; import minicraft.util.DamageSource; +import org.jetbrains.annotations.Nullable; public class LavaBrickTile extends Tile { protected LavaBrickTile(String name) { super(name, new SpriteAnimation(SpriteType.Tile, "missing_tile")); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Pickaxe) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Lava")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Lava")); Sound.play("monsterhurt"); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -39,7 +44,7 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir public void bumpedInto(Level level, int x, int y, Entity entity) { if (entity instanceof Mob) - entity.hurt(new DamageSource.OtherDamageSource(DamageSource.OtherDamageSource.DamageType.LAVA_BRICK, level, entity.x, entity.y), + entity.hurt(new DamageSource(DamageSource.DamageType.HOT_FLOOR, level, (x << 4) + 8, (y << 4) + 8, this), Direction.NONE, 3); } diff --git a/src/client/java/minicraft/level/tile/LavaTile.java b/src/client/java/minicraft/level/tile/LavaTile.java index 7ab019118..aefb72d68 100644 --- a/src/client/java/minicraft/level/tile/LavaTile.java +++ b/src/client/java/minicraft/level/tile/LavaTile.java @@ -4,7 +4,9 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class LavaTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "lava") @@ -54,4 +56,7 @@ public boolean tick(Level level, int xt, int yt) { public int getLightRadius(Level level, int x, int y) { return 6; } + + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} } diff --git a/src/client/java/minicraft/level/tile/MaterialTile.java b/src/client/java/minicraft/level/tile/MaterialTile.java index d964133fd..aad31b76b 100644 --- a/src/client/java/minicraft/level/tile/MaterialTile.java +++ b/src/client/java/minicraft/level/tile/MaterialTile.java @@ -11,6 +11,7 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class MaterialTile extends Tile { protected Material type; @@ -30,16 +31,20 @@ protected MaterialTile(Material type) { } } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); if (level.depth == 1) { - level.setTile(xt, yt, Tiles.get("Cloud")); + level.setTile(x, y, Tiles.get("Cloud")); } else { - level.setTile(xt, yt, Tiles.get("Hole")); + level.setTile(x, y, Tiles.get("Hole")); } Item drop; switch (type) { @@ -53,10 +58,10 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir throw new IllegalStateException("Unexpected value: " + type); } Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, drop); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/OreTile.java b/src/client/java/minicraft/level/tile/OreTile.java index 2721ef252..7c8d79c99 100644 --- a/src/client/java/minicraft/level/tile/OreTile.java +++ b/src/client/java/minicraft/level/tile/OreTile.java @@ -19,6 +19,7 @@ import minicraft.level.Level; import minicraft.screen.AchievementsDisplay; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; /// this is all the spikey stuff (except "cloud cactus") public class OreTile extends Tile { @@ -61,23 +62,22 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return false; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - hurt(level, x, y, 0); - return true; - } + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, 100); + return true; + } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative")) - return false; // Go directly to hurt method - if (item instanceof ToolItem) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Pickaxe) { - if (player.payStamina(6 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - hurt(level, xt, yt, tool.getDamage()); + if (((Player) source).payStamina(6 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + handleDamage(level, x, y, source, tool, tool.getDamage()); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -89,7 +89,8 @@ public Item getOre() { return type.getOre(); } - public void hurt(Level level, int x, int y, int dmg) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { int damage = level.getData(x, y) + dmg; int oreH = random.nextInt(10) * 4 + 20; if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = oreH; diff --git a/src/client/java/minicraft/level/tile/PathTile.java b/src/client/java/minicraft/level/tile/PathTile.java index 1656df5c6..96c240d94 100644 --- a/src/client/java/minicraft/level/tile/PathTile.java +++ b/src/client/java/minicraft/level/tile/PathTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -11,6 +12,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class PathTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "path"); @@ -25,18 +27,22 @@ public boolean connectsToGrass(Level level, int x, int y) { return true; } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Hole")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Hole")); Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get("Dirt")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/RockTile.java b/src/client/java/minicraft/level/tile/RockTile.java index c03dda9ec..21a0d8941 100644 --- a/src/client/java/minicraft/level/tile/RockTile.java +++ b/src/client/java/minicraft/level/tile/RockTile.java @@ -19,16 +19,18 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; // This is the normal stone you see underground and on the surface, that drops coal and stone. public class RockTile extends Tile { + private static final int MAX_HEALTH = 50; + private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "rock") .setConnectionChecker((level, x, y, tile, side) -> tile instanceof RockTile) .setSingletonWithConnective(true); private boolean dropCoal = false; - private int maxHealth = 50; private int damage; @@ -45,44 +47,41 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return false; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - dropCoal = false; // Can only be reached when player hits w/o pickaxe, so remove ability to get coal - hurt(level, x, y, dmg); - return true; - } + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, MAX_HEALTH); + return true; + } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + // Can only be reached when player hits w/o pickaxe, so remove ability to get coal + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; - if (tool.type == ToolType.Pickaxe && player.payStamina(5 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); + if (tool.type == ToolType.Pickaxe && ((Player) source).payStamina(5 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); // Drop coal since we use a pickaxe. - dropCoal = true; - hurt(level, xt, yt, tool.getDamage()); + handleDamage(level, x, y, source, item, tool.getDamage()); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } + return false; } - public void hurt(Level level, int x, int y, int dmg) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { damage = level.getData(x, y) + dmg; - if (Game.isMode("minicraft.settings.mode.creative")) { - dmg = damage = maxHealth; - dropCoal = true; - } - level.add(new SmashParticle(x << 4, y << 4)); Sound.play("monsterhurt"); level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); - if (damage >= maxHealth) { + if (damage >= MAX_HEALTH) { int stone = 1; - if (dropCoal) { +// if (dropCoal) { stone += random.nextInt(3) + 1; int coal = 1; @@ -91,7 +90,7 @@ public void hurt(Level level, int x, int y, int dmg) { } level.dropItem((x << 4) + 8, (y << 4) + 8, 0, coal, Items.get("Coal")); - } +// } level.dropItem((x << 4) + 8, (y << 4) + 8, stone, Items.get("Stone")); level.setTile(x, y, Tiles.get("Dirt")); diff --git a/src/client/java/minicraft/level/tile/SandTile.java b/src/client/java/minicraft/level/tile/SandTile.java index a4d0a6a43..6920e5de8 100644 --- a/src/client/java/minicraft/level/tile/SandTile.java +++ b/src/client/java/minicraft/level/tile/SandTile.java @@ -15,6 +15,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class SandTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "sand") @@ -61,18 +62,22 @@ public void steppedOn(Level level, int x, int y, Entity entity) { } } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Hole")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Hole")); Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get("Sand")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Sand")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/level/tile/SaplingTile.java b/src/client/java/minicraft/level/tile/SaplingTile.java index c871d2841..6a83ea3ea 100644 --- a/src/client/java/minicraft/level/tile/SaplingTile.java +++ b/src/client/java/minicraft/level/tile/SaplingTile.java @@ -2,11 +2,14 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class SaplingTile extends Tile { private static final SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "sapling"); @@ -54,7 +57,11 @@ public boolean tick(Level level, int x, int y) { return true; } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { level.setTile(x, y, onType); Sound.play("monsterhurt"); return true; diff --git a/src/client/java/minicraft/level/tile/SignTile.java b/src/client/java/minicraft/level/tile/SignTile.java index 88fb97ff5..2d0273c36 100644 --- a/src/client/java/minicraft/level/tile/SignTile.java +++ b/src/client/java/minicraft/level/tile/SignTile.java @@ -19,6 +19,7 @@ import minicraft.screen.SignDisplay; import minicraft.screen.SignDisplayMenu; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; import org.tinylog.Logger; public class SignTile extends Tile { @@ -46,31 +47,26 @@ public void render(Screen screen, Level level, int x, int y) { sprite.render(screen, level, x, y); } - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item != null) { - if (item instanceof ToolItem && ((ToolItem) item).type == ToolType.Axe) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get((short) data)); - SignDisplay.removeSign(level.depth, xt, yt); - Sound.play("monsterhurt"); - level.dropItem(xt*16+8, yt*16+8, Items.get("Sign")); - AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( - new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); - return true; - } - } else { // TODO Add a way to lock signs - Game.setDisplay(new SignDisplay(level, xt, yt)); - return true; - } - - return false; + @Override + public boolean use(Level level, int xt, int yt, Player player, @Nullable Item item, Direction attackDir) { + Game.setDisplay(new SignDisplay(level, xt, yt)); + return true; // TODO Add a way to lock signs } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - if (source instanceof Player) { - Game.setDisplay(new SignDisplay(level, x, y)); + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && ((ToolItem) item).type == ToolType.Axe) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) data)); + SignDisplay.removeSign(level.depth, x, y); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Sign")); + AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( + new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( + item, this, data, x, y, level.depth)); return true; } diff --git a/src/client/java/minicraft/level/tile/StairsTile.java b/src/client/java/minicraft/level/tile/StairsTile.java index b4d004e1f..f72a0e70b 100644 --- a/src/client/java/minicraft/level/tile/StairsTile.java +++ b/src/client/java/minicraft/level/tile/StairsTile.java @@ -13,6 +13,7 @@ import minicraft.item.PowerGloveItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class StairsTile extends Tile { private static SpriteAnimation down = new SpriteAnimation(SpriteType.Tile, "stairs_down"); @@ -37,17 +38,18 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - super.attack(level, xt, yt, player, item, attackDir); + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { // Makes it so you can remove the stairs if you are in creative and debug mode. if (item instanceof PowerGloveItem && Game.isMode("minicraft.settings.mode.creative")) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Grass")); + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Grass")); Sound.play("monsterhurt"); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } else { return false; diff --git a/src/client/java/minicraft/level/tile/Tile.java b/src/client/java/minicraft/level/tile/Tile.java index 361459875..05bfbb069 100644 --- a/src/client/java/minicraft/level/tile/Tile.java +++ b/src/client/java/minicraft/level/tile/Tile.java @@ -90,13 +90,15 @@ public int getLightRadius(Level level, int x, int y) { /** * Hurt the tile with a specified amount of damage directly. This is supposed to be used internally. - * Using {@link #attack(Level, int, int, Entity, Item, Direction, int)} is more recommended. + * Using {@link #hurt(Level, int, int, Entity, Item, Direction, int)} is more recommended. * @param level The level this happened on. * @param x X position of the tile. * @param y Y position of the tile. + * @param source The entity performed the interaction. + * @param item The item the entity is holding. * @param dmg The damage taken. */ - public void hurt(Level level, int x, int y, int dmg) {} + protected abstract void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg); /** * What happens when you run into the tile (ex: run into a cactus) @@ -128,7 +130,7 @@ public void steppedOn(Level level, int xt, int yt, Entity entity) { * @param damage The amount of damage intended to emit this time * @return Was the operation successful? */ - public boolean attack(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { return false; } diff --git a/src/client/java/minicraft/level/tile/TorchTile.java b/src/client/java/minicraft/level/tile/TorchTile.java index 5462ff080..309531a79 100644 --- a/src/client/java/minicraft/level/tile/TorchTile.java +++ b/src/client/java/minicraft/level/tile/TorchTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; @@ -11,6 +12,7 @@ import minicraft.item.PowerGloveItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class TorchTile extends Tile { protected TorchTile() { @@ -41,15 +43,19 @@ public int getLightRadius(Level level, int x, int y) { return 5; } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { if (item instanceof PowerGloveItem) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get((short) data)); + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) data)); Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get("Torch")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Torch")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } else { return false; diff --git a/src/client/java/minicraft/level/tile/TreeTile.java b/src/client/java/minicraft/level/tile/TreeTile.java index a803b2c49..5bd5806c9 100644 --- a/src/client/java/minicraft/level/tile/TreeTile.java +++ b/src/client/java/minicraft/level/tile/TreeTile.java @@ -20,8 +20,11 @@ import minicraft.level.Level; import minicraft.screen.AchievementsDisplay; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class TreeTile extends Tile { + private static final int MAX_HEALTH = 20; + private static final LinkedSprite oakSprite = new LinkedSprite(SpriteType.Tile, "oak"); private static final LinkedSprite oakSpriteFull = new LinkedSprite(SpriteType.Tile, "oak_full"); private static final LinkedSprite spruceSprite = new LinkedSprite(SpriteType.Tile, "spruce"); @@ -121,24 +124,21 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - hurt(level, x, y, dmg); - return true; - } + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, MAX_HEALTH); + return true; // Go directly to hurt method + } - @Override - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative")) - return false; // Go directly to hurt method - if (item instanceof ToolItem) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Axe) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - hurt(level, xt, yt, tool.getDamage()); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + hurt(level, x, y, source, item, attackDir, tool.getDamage()); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -146,19 +146,17 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } - public void hurt(Level level, int x, int y, int dmg) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { if (random.nextInt(100) == 0) level.dropItem(x * 16 + 8, y * 16 + 8, Items.get("Apple")); int damage = level.getData(x, y) + dmg; - int treeHealth = 20; - if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = treeHealth; - level.add(new SmashParticle(x * 16, y * 16)); Sound.play("monsterhurt"); level.add(new TextParticle("" + dmg, x * 16 + 8, y * 16 + 8, Color.RED)); - if (damage >= treeHealth) { + if (damage >= MAX_HEALTH) { level.dropItem(x * 16 + 8, y * 16 + 8, 1, 3, Items.get("Wood")); level.dropItem(x * 16 + 8, y * 16 + 8, 0, 2, Items.get("Acorn")); level.setTile(x, y, Tiles.get("Grass")); diff --git a/src/client/java/minicraft/level/tile/WallTile.java b/src/client/java/minicraft/level/tile/WallTile.java index 7405f669f..6a1a90e03 100644 --- a/src/client/java/minicraft/level/tile/WallTile.java +++ b/src/client/java/minicraft/level/tile/WallTile.java @@ -18,8 +18,11 @@ import minicraft.item.ToolItem; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class WallTile extends Tile { + private static final int MAX_HEALTH = 100; + private static SpriteAnimation wood = new SpriteAnimation(SpriteType.Tile, "wood_wall") .setConnectionChecker((level, x, y, tile, side) -> tile instanceof WallTile); private static SpriteAnimation stone = new SpriteAnimation(SpriteType.Tile, "stone_wall") @@ -55,49 +58,44 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative") || level.depth != -3 || type != Material.Obsidian || AirWizard.beaten) { - hurt(level, x, y, 0); + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + handleDamage(level, x, y, source, item, MAX_HEALTH); return true; - } else { - Game.notifications.add(Localization.getLocalized(obrickMsg)); - return false; } - } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (Game.isMode("minicraft.settings.mode.creative")) - return false; // Go directly to hurt method - if (item instanceof ToolItem) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { if (level.depth != -3 || type != Material.Obsidian || AirWizard.beaten) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - hurt(level, xt, yt, tool.getDamage()); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + hurt(level, x, y, source, item, attackDir, tool.getDamage()); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } else { Game.notifications.add(obrickMsg); + handleDamage(level, x, y, source, item, 0); } } + } else { + handleDamage(level, x, y, source, item, 0); } + return false; } - public void hurt(Level level, int x, int y, int dmg) { + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { int damage = level.getData(x, y) + dmg; - int sbwHealth = 100; - if (Game.isMode("minicraft.settings.mode.creative")) dmg = damage = sbwHealth; - level.add(new SmashParticle(x << 4, y << 4)); Sound.play("monsterhurt"); level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); - if (damage >= sbwHealth) { + if (damage >= MAX_HEALTH) { String itemName = "", tilename = ""; switch (type) { // Get what tile to set and what item to drop case Wood: { diff --git a/src/client/java/minicraft/level/tile/WaterTile.java b/src/client/java/minicraft/level/tile/WaterTile.java index cf99612e0..f5597b6c8 100644 --- a/src/client/java/minicraft/level/tile/WaterTile.java +++ b/src/client/java/minicraft/level/tile/WaterTile.java @@ -4,7 +4,9 @@ import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; +import minicraft.item.Item; import minicraft.level.Level; +import org.jetbrains.annotations.Nullable; public class WaterTile extends Tile { private static SpriteAnimation sprite = new SpriteAnimation(SpriteType.Tile, "water") @@ -31,6 +33,9 @@ public boolean mayPass(Level level, int x, int y, Entity e) { return e.canSwim(); } + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + @Override public boolean tick(Level level, int xt, int yt) { int xn = xt; diff --git a/src/client/java/minicraft/level/tile/WoolTile.java b/src/client/java/minicraft/level/tile/WoolTile.java index d219956c2..8c8774d9f 100644 --- a/src/client/java/minicraft/level/tile/WoolTile.java +++ b/src/client/java/minicraft/level/tile/WoolTile.java @@ -12,6 +12,7 @@ import minicraft.item.ToolType; import minicraft.level.Level; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; public class WoolTile extends Tile { @@ -19,18 +20,19 @@ public WoolTile(WoolType woolType) { super(woolType.name, woolType.sprite); } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shears) { - if (player.payStamina(3 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Hole")); + if (((Player) source).payStamina(3 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Hole")); Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get(name)); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get(name)); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } @@ -38,6 +40,11 @@ public boolean attack(Level level, int xt, int yt, Player player, Item item, Dir return false; } + @Override + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + + } + public boolean mayPass(Level level, int x, int y, Entity e) { return e.canWool(); } diff --git a/src/client/java/minicraft/level/tile/entity/SignTileEntity.java b/src/client/java/minicraft/level/tile/entity/SignTileEntity.java index f7b73a854..01fbf3ba9 100644 --- a/src/client/java/minicraft/level/tile/entity/SignTileEntity.java +++ b/src/client/java/minicraft/level/tile/entity/SignTileEntity.java @@ -9,6 +9,7 @@ import minicraft.level.Level; import minicraft.level.tile.Tile; import minicraft.screen.SignDisplayMenu; +import minicraft.util.DamageSource; import org.jetbrains.annotations.Nullable; public class SignTileEntity extends Entity { @@ -40,7 +41,12 @@ public boolean isUsable() { } @Override - protected void hurt(int damage, Direction attackDir) {} + protected void handleDamage(DamageSource source, Direction attackDir, int damage) {} + + @Override + public boolean hurt(DamageSource source, Direction attackDir, int damage) { + return false; + } @Override public void tick() { diff --git a/src/client/java/minicraft/level/tile/farming/CropTile.java b/src/client/java/minicraft/level/tile/farming/CropTile.java index 6291fa75b..af2d6c1b6 100644 --- a/src/client/java/minicraft/level/tile/farming/CropTile.java +++ b/src/client/java/minicraft/level/tile/farming/CropTile.java @@ -30,8 +30,13 @@ protected CropTile(String name, @Nullable String seed) { } @Override - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { harvest(level, x, y, source); + } + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + handleDamage(level, x, y, source, item, damage); return true; } @@ -102,7 +107,7 @@ public boolean tick(Level level, int xt, int yt) { private static final SpriteLinker.LinkedSprite particleSprite = new SpriteLinker.LinkedSprite(SpriteLinker.SpriteType.Entity, "glint"); @Override - public boolean interact(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { + public boolean use(Level level, int xt, int yt, Player player, @Nullable Item item, Direction attackDir) { if (item instanceof StackableItem && item.getName().equalsIgnoreCase("Fertilizer")) { ((StackableItem) item).count--; Random random = new Random(); @@ -127,7 +132,7 @@ public boolean interact(Level level, int xt, int yt, Player player, Item item, D return true; } - return super.interact(level, xt, yt, player, item, attackDir); + return false; } /** diff --git a/src/client/java/minicraft/level/tile/farming/FarmTile.java b/src/client/java/minicraft/level/tile/farming/FarmTile.java index 6517bc732..d3fea69b1 100644 --- a/src/client/java/minicraft/level/tile/farming/FarmTile.java +++ b/src/client/java/minicraft/level/tile/farming/FarmTile.java @@ -2,6 +2,7 @@ import minicraft.core.io.Sound; import minicraft.entity.Direction; +import minicraft.entity.Entity; import minicraft.entity.mob.Player; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; @@ -14,6 +15,7 @@ import minicraft.level.tile.Tiles; import minicraft.level.tile.WaterTile; import minicraft.util.AdvancementElement; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -30,17 +32,20 @@ protected FarmTile(String name, SpriteAnimation sprite) { } @Override - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Dirt")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Dirt")); Sound.play("monsterhurt"); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } diff --git a/src/client/java/minicraft/util/DamageSource.java b/src/client/java/minicraft/util/DamageSource.java index 21090f8a1..cbe460afc 100644 --- a/src/client/java/minicraft/util/DamageSource.java +++ b/src/client/java/minicraft/util/DamageSource.java @@ -5,6 +5,7 @@ package minicraft.util; +import minicraft.core.Game; import minicraft.entity.Entity; import minicraft.gfx.Point; import minicraft.item.Item; @@ -13,116 +14,121 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public abstract class DamageSource { - @NotNull - public abstract Level getLevel(); - - /** Get position of damage source based on entity coordinates. */ - @NotNull - public abstract Point getPosition(); - - public static class TileDamageSource extends DamageSource { - private final @NotNull Tile tile; - private final @NotNull Level level; - private final int x, y; - - public TileDamageSource(@NotNull Tile tile, @NotNull Level level, int x, int y) { - this.tile = tile; - this.level = level; - this.x = x; - this.y = y; - } - - public @NotNull Tile getTile() { - return tile; - } - - @Override - public @NotNull Level getLevel() { - return level; - } - - @Override - public @NotNull Point getPosition() { - return new Point((x << 4) + 8, (y << 4) + 8); +public class DamageSource { + /* + * If the source with a particular type has certain data info available, then the instances must have + * such data info available, may be not null, except item, but other info must be null, otherwise there could + * be unexpected errors. + * The position is either of tile or directEntity, but all in entity coordinates (center of tile for tiles). + * Available data info: + * - tile: the tile type as the source + * - causingEntity: the entity causing the damage, aiming the target + * - directEntity: the entity directly causes damage to the target + * - item: the item the direct entity was holding to cause damage + */ + + public enum DamageType { + /** Data: tile or (item, causingEntity and directEntity) */ + GENERIC, + /** Fire tile; Data: tile */ + IN_FIRE, + /** When on fire, original source must refer to last attack source; Data: (causingEntity+directEntity) or tile */ + ON_FIRE, + /** Lava tile; Data: tile */ + LAVA, + /** Data: causingEntity and directEntity */ + EXPLOSION, + /** Data: N/A */ + DROWN, + /** Data: N/A */ + STARVE, + /** Data: (causingEntity or tile) and directEntity */ + ARROW, + /** Data: causingEntity and directEntity */ + SPARK, + /** Heat damage by floor tile; Data: tile */ + HOT_FLOOR, + /** Data: tile */ + CACTUS; + + public boolean isFireRelated() { + return this == IN_FIRE || this == ON_FIRE || this == LAVA || this == HOT_FLOOR; } } - public static class EntityDamageSource extends DamageSource { - private final @NotNull Entity entity; - private final @Nullable Item item; - - public EntityDamageSource(@NotNull Entity entity, @Nullable Item item) { - this.entity = entity; - this.item = item; - } + private final @NotNull DamageType damageType; + private final @NotNull Level level; + private final int x, y; + private final @Nullable Tile tile; + private final @Nullable Entity causingEntity, directEntity; + private final @Nullable Item item; + + public DamageSource(@NotNull DamageType damageType, @NotNull Level level, int x, int y, @Nullable Tile tile, + @Nullable Entity causingEntity, @Nullable Entity directEntity, @Nullable Item item) { + this.damageType = damageType; + this.level = level; + this.x = x; + this.y = y; + this.tile = tile; + this.causingEntity = causingEntity; + this.directEntity = directEntity; + this.item = item; + } - public @NotNull Entity getEntity() { - return entity; - } + public DamageSource(DamageType damageType, @NotNull Level level, int x, int y, + @NotNull Tile tile, @NotNull Entity directEntity, @Nullable Item item) { + this(damageType, level, x, y, tile, null, directEntity, item); + } - /** Gets the item the entity is holding */ - public @Nullable Item getItem() { - return item; - } + public DamageSource(@NotNull DamageType damageType, @NotNull Level level, int x, int y, @NotNull Tile tile) { + this(damageType, level, x, y, tile, null, null, null); + } - @Override - public @NotNull Level getLevel() { - return entity.getLevel(); - } + public DamageSource(@NotNull DamageType damageType, @NotNull Entity causingEntity, + @NotNull Entity directEntity, @Nullable Item item) { + this(damageType, directEntity.getLevel(), directEntity.x, directEntity.y, null, causingEntity, directEntity, item); + } - @Override - public @NotNull Point getPosition() { - return new Point(entity.x, entity.y); - } + public DamageSource(@NotNull DamageType damageType, @NotNull Entity entity, @Nullable Item item) { + this(damageType, entity, entity, item); } - public static class OtherDamageSource extends DamageSource { - private final @NotNull Level level; - private final int x, y; - private final @NotNull DamageType damageType; - private final @Nullable Entity causingEntity; + public DamageSource(@NotNull DamageType damageType) { + this(damageType, Game.player, null); // placeholder + } - public enum DamageType { - IN_FIRE, ON_FIRE, LAVA, EXPLOSION, DRONE, STARVE, ARROW, SPARK, LAVA_BRICK; + public @NotNull DamageType getDamageType() { + return damageType; + } - public boolean isFireRelated() { - return this == IN_FIRE || this == ON_FIRE || this == LAVA || this == LAVA_BRICK; - } - } + @NotNull + public Level getLevel() { + return level; + }; - public OtherDamageSource(@NotNull DamageType damageType, @NotNull Level level, int x, int y) { - this.damageType = damageType; - this.level = level; - this.x = x; - this.y = y; - this.causingEntity = null; - } + public Point getTilePosition() { + return new Point(x >> 4, y >> 4); + } - public OtherDamageSource(@NotNull DamageType damageType, @NotNull Entity causingEntity) { - this.damageType = damageType; - this.causingEntity = causingEntity; - this.level = causingEntity.getLevel(); - this.x = causingEntity.x; - this.y = causingEntity.y; - } + /** Get position of damage source based on entity coordinates. */ + @NotNull + public Point getPosition() { + return new Point(x, y); + }; - public @Nullable Entity getCausingEntity() { - return causingEntity; - } + public @Nullable Tile getTile() { + return tile; + } - public @NotNull DamageType getDamageType() { - return damageType; - } + public @Nullable Entity getCausingEntity() { + return causingEntity; + } - @Override - public @NotNull Level getLevel() { - return level; - } + public @Nullable Entity getDirectEntity() { + return directEntity; + } - @Override - public @NotNull Point getPosition() { - return new Point(x, y); - } + public @Nullable Item getItem() { + return item; } } From 4017d5d2b023305aeca710bb6858120abe7b29b1 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sat, 17 Aug 2024 04:54:58 +0800 Subject: [PATCH 11/14] Apply tile zero damage policy --- .../java/minicraft/level/tile/CloudTile.java | 12 +++++-- .../java/minicraft/level/tile/DecorTile.java | 12 +++++-- .../java/minicraft/level/tile/DirtTile.java | 34 ++++++++++++------- .../java/minicraft/level/tile/DoorTile.java | 12 +++++-- .../java/minicraft/level/tile/FenceTile.java | 28 ++++++++------- .../java/minicraft/level/tile/FloorTile.java | 12 +++++-- .../java/minicraft/level/tile/FlowerTile.java | 3 -- .../java/minicraft/level/tile/GrassTile.java | 12 +++++-- .../minicraft/level/tile/HardRockTile.java | 4 ++- .../minicraft/level/tile/LavaBrickTile.java | 12 +++++-- .../minicraft/level/tile/MaterialTile.java | 12 +++++-- .../java/minicraft/level/tile/OreTile.java | 4 ++- .../java/minicraft/level/tile/PathTile.java | 12 +++++-- .../java/minicraft/level/tile/RockTile.java | 3 +- .../java/minicraft/level/tile/SandTile.java | 12 +++++-- .../java/minicraft/level/tile/SignTile.java | 11 ++++-- .../java/minicraft/level/tile/Tile.java | 5 ++- .../java/minicraft/level/tile/TorchTile.java | 32 +++++++++-------- .../java/minicraft/level/tile/TreeTile.java | 4 ++- .../java/minicraft/level/tile/WallTile.java | 5 ++- .../java/minicraft/level/tile/WoolTile.java | 10 ++++-- .../level/tile/farming/FarmTile.java | 12 +++++-- 22 files changed, 187 insertions(+), 76 deletions(-) diff --git a/src/client/java/minicraft/level/tile/CloudTile.java b/src/client/java/minicraft/level/tile/CloudTile.java index 34dcbd544..cf3d18653 100644 --- a/src/client/java/minicraft/level/tile/CloudTile.java +++ b/src/client/java/minicraft/level/tile/CloudTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -28,7 +31,10 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -46,6 +52,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite return true; } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/DecorTile.java b/src/client/java/minicraft/level/tile/DecorTile.java index 17861df3f..8d0f0a617 100644 --- a/src/client/java/minicraft/level/tile/DecorTile.java +++ b/src/client/java/minicraft/level/tile/DecorTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -57,7 +60,10 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -94,7 +100,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } public boolean mayPass(Level level, int x, int y, Entity e) { diff --git a/src/client/java/minicraft/level/tile/DirtTile.java b/src/client/java/minicraft/level/tile/DirtTile.java index cf2e7259c..26f4ba026 100644 --- a/src/client/java/minicraft/level/tile/DirtTile.java +++ b/src/client/java/minicraft/level/tile/DirtTile.java @@ -4,6 +4,8 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; @@ -57,35 +59,41 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } - public boolean attack(Level level, int xt, int yt, Player player, Item item, Direction attackDir) { - if (item instanceof ToolItem) { + @Override + public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Hole")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Hole")); Sound.play("monsterhurt"); - level.dropItem((xt << 4) + 8, (yt << 4) + 8, Items.get("Dirt")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } if (tool.type == ToolType.Hoe) { - if (player.payStamina(4 - tool.level) && tool.payDurability()) { - int data = level.getData(xt, yt); - level.setTile(xt, yt, Tiles.get("Farmland")); + if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get("Farmland")); Sound.play("monsterhurt"); AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, xt, yt, level.depth)); + item, this, data, x, y, level.depth)); return true; } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/DoorTile.java b/src/client/java/minicraft/level/tile/DoorTile.java index 1c1ebfb20..00d15879a 100644 --- a/src/client/java/minicraft/level/tile/DoorTile.java +++ b/src/client/java/minicraft/level/tile/DoorTile.java @@ -5,6 +5,9 @@ import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -51,7 +54,10 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -70,7 +76,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/FenceTile.java b/src/client/java/minicraft/level/tile/FenceTile.java index 8dd7d6c3b..fb83d0b92 100644 --- a/src/client/java/minicraft/level/tile/FenceTile.java +++ b/src/client/java/minicraft/level/tile/FenceTile.java @@ -7,6 +7,8 @@ import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -102,13 +104,20 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { - if (Game.isMode("minicraft.settings.mode.creative")) - return false; // Go directly to hurt method - if (item instanceof ToolItem && source instanceof Player) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.add(new SmashParticle(x * 16, y * 16)); + Sound.play("monsterhurt"); + level.dropItem(x * 16 + 8, y * 16 + 8, Items.get(name)); + level.setTile(x, y, Tiles.get((short) level.getData(x, y))); + return true; + } else if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { if (((Player) source).payStamina(4 - tool.level) && tool.payDurability()) { @@ -123,15 +132,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; - } - public void hurt(Level level, int x, int y, int dmg) { - if (Game.isMode("minicraft.settings.mode.creative")) { - level.add(new SmashParticle(x * 16, y * 16)); - Sound.play("monsterhurt"); - level.dropItem(x * 16 + 8, y * 16 + 8, Items.get(name)); - level.setTile(x, y, Tiles.get((short) level.getData(x, y))); - } + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/FloorTile.java b/src/client/java/minicraft/level/tile/FloorTile.java index ca13448a2..b79fc74e5 100644 --- a/src/client/java/minicraft/level/tile/FloorTile.java +++ b/src/client/java/minicraft/level/tile/FloorTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -67,7 +70,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } public boolean mayPass(Level level, int x, int y, Entity e) { @@ -75,5 +80,8 @@ public boolean mayPass(Level level, int x, int y, Entity e) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } } diff --git a/src/client/java/minicraft/level/tile/FlowerTile.java b/src/client/java/minicraft/level/tile/FlowerTile.java index 59e3f2ea9..5903ac649 100644 --- a/src/client/java/minicraft/level/tile/FlowerTile.java +++ b/src/client/java/minicraft/level/tile/FlowerTile.java @@ -74,10 +74,7 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; - } - public boolean hurt(Level level, int x, int y, Mob source, int dmg, Direction attackDir) { level.dropItem((x << 4) + 8, (y << 4) + 8, 0, 1, Items.get("Flower")); level.dropItem((x << 4) + 8, (y << 4) + 8, 0, 1, Items.get("Rose")); level.setTile(x, y, Tiles.get("Grass")); diff --git a/src/client/java/minicraft/level/tile/GrassTile.java b/src/client/java/minicraft/level/tile/GrassTile.java index 080a90c01..7d91f4caf 100644 --- a/src/client/java/minicraft/level/tile/GrassTile.java +++ b/src/client/java/minicraft/level/tile/GrassTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -53,7 +56,10 @@ public void render(Screen screen, Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -94,6 +100,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/HardRockTile.java b/src/client/java/minicraft/level/tile/HardRockTile.java index 239e529c7..50854caed 100644 --- a/src/client/java/minicraft/level/tile/HardRockTile.java +++ b/src/client/java/minicraft/level/tile/HardRockTile.java @@ -60,7 +60,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite Game.notifications.add("minicraft.notification.gem_pickaxe_required"); } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index 34d2bb17e..ac2fcaa0c 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -5,6 +5,9 @@ import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -21,7 +24,10 @@ protected LavaBrickTile(String name) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -39,7 +45,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } public void bumpedInto(Level level, int x, int y, Entity entity) { diff --git a/src/client/java/minicraft/level/tile/MaterialTile.java b/src/client/java/minicraft/level/tile/MaterialTile.java index aad31b76b..61e68cbf6 100644 --- a/src/client/java/minicraft/level/tile/MaterialTile.java +++ b/src/client/java/minicraft/level/tile/MaterialTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -32,7 +35,10 @@ protected MaterialTile(Material type) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -66,7 +72,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } public boolean mayPass(Level level, int x, int y, Entity e) { diff --git a/src/client/java/minicraft/level/tile/OreTile.java b/src/client/java/minicraft/level/tile/OreTile.java index 7c8d79c99..39ecc77a5 100644 --- a/src/client/java/minicraft/level/tile/OreTile.java +++ b/src/client/java/minicraft/level/tile/OreTile.java @@ -82,7 +82,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } public Item getOre() { diff --git a/src/client/java/minicraft/level/tile/PathTile.java b/src/client/java/minicraft/level/tile/PathTile.java index 96c240d94..44d83cc38 100644 --- a/src/client/java/minicraft/level/tile/PathTile.java +++ b/src/client/java/minicraft/level/tile/PathTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -28,7 +31,10 @@ public boolean connectsToGrass(Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -47,6 +53,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/RockTile.java b/src/client/java/minicraft/level/tile/RockTile.java index 21a0d8941..ff838d3dc 100644 --- a/src/client/java/minicraft/level/tile/RockTile.java +++ b/src/client/java/minicraft/level/tile/RockTile.java @@ -68,7 +68,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } - return false; + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/SandTile.java b/src/client/java/minicraft/level/tile/SandTile.java index 6920e5de8..11033bb58 100644 --- a/src/client/java/minicraft/level/tile/SandTile.java +++ b/src/client/java/minicraft/level/tile/SandTile.java @@ -6,6 +6,9 @@ import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; import minicraft.entity.particle.SandParticle; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -63,7 +66,10 @@ public void steppedOn(Level level, int x, int y, Entity entity) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -82,6 +88,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/SignTile.java b/src/client/java/minicraft/level/tile/SignTile.java index 2d0273c36..7c5b2e029 100644 --- a/src/client/java/minicraft/level/tile/SignTile.java +++ b/src/client/java/minicraft/level/tile/SignTile.java @@ -7,6 +7,9 @@ import minicraft.entity.Entity; import minicraft.entity.mob.Mob; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker; @@ -54,7 +57,10 @@ public boolean use(Level level, int xt, int yt, Player player, @Nullable Item it } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -70,7 +76,8 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite return true; } - return false; + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/Tile.java b/src/client/java/minicraft/level/tile/Tile.java index 05bfbb069..8f7d2ad99 100644 --- a/src/client/java/minicraft/level/tile/Tile.java +++ b/src/client/java/minicraft/level/tile/Tile.java @@ -150,10 +150,13 @@ public boolean use(Level level, int xt, int yt, Player player, @Nullable Item it /** * Picks up this tile + * @param level + * @param x + * @param y * @param player The player interacting * @return the item picked up; {@code null} if picking up failed */ - public @Nullable Item take(Player player) { + public @Nullable Item take(Level level, int x, int y, Player player) { return null; } diff --git a/src/client/java/minicraft/level/tile/TorchTile.java b/src/client/java/minicraft/level/tile/TorchTile.java index 309531a79..bdb139c30 100644 --- a/src/client/java/minicraft/level/tile/TorchTile.java +++ b/src/client/java/minicraft/level/tile/TorchTile.java @@ -4,14 +4,15 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; import minicraft.item.Items; -import minicraft.item.PowerGloveItem; import minicraft.level.Level; -import minicraft.util.AdvancementElement; import org.jetbrains.annotations.Nullable; public class TorchTile extends Tile { @@ -44,21 +45,22 @@ public int getLightRadius(Level level, int x, int y) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } + + @Override + public @Nullable Item take(Level level, int x, int y, Player player) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) data)); + Sound.play("monsterhurt"); + return Items.get("Torch"); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { - if (item instanceof PowerGloveItem) { - int data = level.getData(x, y); - level.setTile(x, y, Tiles.get((short) data)); - Sound.play("monsterhurt"); - level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Torch")); - AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( - new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, x, y, level.depth)); - return true; - } else { - return false; - } + handleDamage(level, x, y, source, item, 0); + return true; } } diff --git a/src/client/java/minicraft/level/tile/TreeTile.java b/src/client/java/minicraft/level/tile/TreeTile.java index 5bd5806c9..1a0e09fd6 100644 --- a/src/client/java/minicraft/level/tile/TreeTile.java +++ b/src/client/java/minicraft/level/tile/TreeTile.java @@ -143,7 +143,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/WallTile.java b/src/client/java/minicraft/level/tile/WallTile.java index 6a1a90e03..998c5e90f 100644 --- a/src/client/java/minicraft/level/tile/WallTile.java +++ b/src/client/java/minicraft/level/tile/WallTile.java @@ -81,11 +81,10 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite handleDamage(level, x, y, source, item, 0); } } - } else { - handleDamage(level, x, y, source, item, 0); } - return false; + handleDamage(level, x, y, source, item, 0); + return true; } @Override diff --git a/src/client/java/minicraft/level/tile/WoolTile.java b/src/client/java/minicraft/level/tile/WoolTile.java index 8c8774d9f..cfce55d5e 100644 --- a/src/client/java/minicraft/level/tile/WoolTile.java +++ b/src/client/java/minicraft/level/tile/WoolTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; @@ -37,12 +40,15 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } @Override protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { - + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); } public boolean mayPass(Level level, int x, int y, Entity e) { diff --git a/src/client/java/minicraft/level/tile/farming/FarmTile.java b/src/client/java/minicraft/level/tile/farming/FarmTile.java index d3fea69b1..2b3afdb82 100644 --- a/src/client/java/minicraft/level/tile/farming/FarmTile.java +++ b/src/client/java/minicraft/level/tile/farming/FarmTile.java @@ -4,6 +4,9 @@ import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.mob.Player; +import minicraft.entity.particle.SmashParticle; +import minicraft.entity.particle.TextParticle; +import minicraft.gfx.Color; import minicraft.gfx.Screen; import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; @@ -32,7 +35,10 @@ protected FarmTile(String name, SpriteAnimation sprite) { } @Override - protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} + protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) { + level.add(new SmashParticle(x << 4, y << 4)); + level.add(new TextParticle("" + dmg, (x << 4) + 8, (y << 4) + 8, Color.RED)); + } @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { @@ -50,7 +56,9 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } } - return false; + + handleDamage(level, x, y, source, item, 0); + return true; } @Override From b6c912aeed08784d470a06021346b387516a12ce Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sat, 17 Aug 2024 05:09:40 +0800 Subject: [PATCH 12/14] Let creative mode break most solid tiles --- .../java/minicraft/level/tile/CloudTile.java | 10 ++++++- .../java/minicraft/level/tile/DecorTile.java | 26 +++++++++++++++++++ .../java/minicraft/level/tile/DirtTile.java | 8 ++++++ .../java/minicraft/level/tile/DoorTile.java | 8 ++++++ .../java/minicraft/level/tile/FloorTile.java | 21 +++++++++++++++ .../java/minicraft/level/tile/FlowerTile.java | 9 +++++++ .../java/minicraft/level/tile/GrassTile.java | 10 +++++++ .../minicraft/level/tile/LavaBrickTile.java | 7 +++++ .../minicraft/level/tile/MaterialTile.java | 23 ++++++++++++++++ .../java/minicraft/level/tile/PathTile.java | 8 ++++++ .../java/minicraft/level/tile/SandTile.java | 8 ++++++ .../java/minicraft/level/tile/SignTile.java | 9 +++++++ .../java/minicraft/level/tile/TorchTile.java | 10 +++++++ .../java/minicraft/level/tile/WallTile.java | 1 - .../java/minicraft/level/tile/WoolTile.java | 8 ++++++ .../level/tile/farming/FarmTile.java | 9 +++++++ 16 files changed, 173 insertions(+), 2 deletions(-) diff --git a/src/client/java/minicraft/level/tile/CloudTile.java b/src/client/java/minicraft/level/tile/CloudTile.java index cf3d18653..6a7cf6e48 100644 --- a/src/client/java/minicraft/level/tile/CloudTile.java +++ b/src/client/java/minicraft/level/tile/CloudTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -38,7 +39,14 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { - // We don't want the tile to break when attacked with just anything, even in creative mode + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Infinite Fall")); // Would allow you to shovel cloud, I think. + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, 1, 3, Items.get("Cloud")); + return true; + } + + // We don't want the tile to break when attacked with just anything if (source instanceof Player && item instanceof ToolItem) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel && ((Player) source).payStamina(5)) { diff --git a/src/client/java/minicraft/level/tile/DecorTile.java b/src/client/java/minicraft/level/tile/DecorTile.java index 8d0f0a617..0d2bdeaa2 100644 --- a/src/client/java/minicraft/level/tile/DecorTile.java +++ b/src/client/java/minicraft/level/tile/DecorTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -67,6 +68,31 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + if (level.depth == 1) { + level.setTile(x, y, Tiles.get("Cloud")); + } else { + level.setTile(x, y, Tiles.get("Hole")); + } + Item drop; + switch (thisType) { + case ORNATE_STONE: + drop = Items.get("Ornate Stone"); + break; + case ORNATE_OBSIDIAN: + drop = Items.get("Ornate Obsidian"); + break; + case ORNATE_WOOD: + drop = Items.get("Ornate Wood"); + break; + default: + throw new IllegalStateException("Unexpected value: " + thisType); + } + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == mType.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/DirtTile.java b/src/client/java/minicraft/level/tile/DirtTile.java index 26f4ba026..6d801a5ec 100644 --- a/src/client/java/minicraft/level/tile/DirtTile.java +++ b/src/client/java/minicraft/level/tile/DirtTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -66,6 +67,13 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Hole")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/DoorTile.java b/src/client/java/minicraft/level/tile/DoorTile.java index 00d15879a..769e69bd7 100644 --- a/src/client/java/minicraft/level/tile/DoorTile.java +++ b/src/client/java/minicraft/level/tile/DoorTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -61,6 +62,13 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get((short) (id + 3))); // Will get the corresponding floor tile. + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get(type.name() + " Door")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/FloorTile.java b/src/client/java/minicraft/level/tile/FloorTile.java index b79fc74e5..4da592330 100644 --- a/src/client/java/minicraft/level/tile/FloorTile.java +++ b/src/client/java/minicraft/level/tile/FloorTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -42,6 +43,26 @@ protected FloorTile(Material type, String name) { @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + if (level.depth == 1) { + level.setTile(x, y, Tiles.get("Cloud")); + } else { + level.setTile(x, y, Tiles.get("Hole")); + } + Item drop; + switch (type) { + case Wood: + drop = Items.get("Plank"); + break; + default: + drop = Items.get(type.name() + " Brick"); + break; + } + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/FlowerTile.java b/src/client/java/minicraft/level/tile/FlowerTile.java index 5903ac649..13690abf7 100644 --- a/src/client/java/minicraft/level/tile/FlowerTile.java +++ b/src/client/java/minicraft/level/tile/FlowerTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -58,6 +59,14 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Grass")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Flower")); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Rose")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/GrassTile.java b/src/client/java/minicraft/level/tile/GrassTile.java index 7d91f4caf..62fe9bdd1 100644 --- a/src/client/java/minicraft/level/tile/GrassTile.java +++ b/src/client/java/minicraft/level/tile/GrassTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -63,6 +64,15 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Dirt")); + Sound.play("monsterhurt"); + if (random.nextInt(5) == 0) { // 20% chance to drop Grass seeds + level.dropItem((x << 4) + 8, (y << 4) + 8, 1, Items.get("Grass Seeds")); + } + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/LavaBrickTile.java b/src/client/java/minicraft/level/tile/LavaBrickTile.java index ac2fcaa0c..89da886fb 100644 --- a/src/client/java/minicraft/level/tile/LavaBrickTile.java +++ b/src/client/java/minicraft/level/tile/LavaBrickTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -31,6 +32,12 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Lava")); + Sound.play("monsterhurt"); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Pickaxe) { diff --git a/src/client/java/minicraft/level/tile/MaterialTile.java b/src/client/java/minicraft/level/tile/MaterialTile.java index 61e68cbf6..75786bac5 100644 --- a/src/client/java/minicraft/level/tile/MaterialTile.java +++ b/src/client/java/minicraft/level/tile/MaterialTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -42,6 +43,28 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + if (level.depth == 1) { + level.setTile(x, y, Tiles.get("Cloud")); + } else { + level.setTile(x, y, Tiles.get("Hole")); + } + Item drop; + switch (type) { + case Stone: + drop = Items.get("Stone"); + break; + case Obsidian: + drop = Items.get("Raw Obsidian"); + break; + default: + throw new IllegalStateException("Unexpected value: " + type); + } + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, drop); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == type.getRequiredTool()) { diff --git a/src/client/java/minicraft/level/tile/PathTile.java b/src/client/java/minicraft/level/tile/PathTile.java index 44d83cc38..9b924d8f2 100644 --- a/src/client/java/minicraft/level/tile/PathTile.java +++ b/src/client/java/minicraft/level/tile/PathTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -38,6 +39,13 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Hole")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/SandTile.java b/src/client/java/minicraft/level/tile/SandTile.java index 11033bb58..0674ffc32 100644 --- a/src/client/java/minicraft/level/tile/SandTile.java +++ b/src/client/java/minicraft/level/tile/SandTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -73,6 +74,13 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Hole")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Sand")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { diff --git a/src/client/java/minicraft/level/tile/SignTile.java b/src/client/java/minicraft/level/tile/SignTile.java index 7c5b2e029..92f4efdad 100644 --- a/src/client/java/minicraft/level/tile/SignTile.java +++ b/src/client/java/minicraft/level/tile/SignTile.java @@ -64,6 +64,15 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) data)); + SignDisplay.removeSign(level.depth, x, y); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Sign")); + return true; + } + if (item instanceof ToolItem && ((ToolItem) item).type == ToolType.Axe) { int data = level.getData(x, y); level.setTile(x, y, Tiles.get((short) data)); diff --git a/src/client/java/minicraft/level/tile/TorchTile.java b/src/client/java/minicraft/level/tile/TorchTile.java index bdb139c30..a900526b2 100644 --- a/src/client/java/minicraft/level/tile/TorchTile.java +++ b/src/client/java/minicraft/level/tile/TorchTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -60,6 +61,15 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + int data = level.getData(x, y); + level.setTile(x, y, Tiles.get((short) data)); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Torch")); + return true; + } + + // Hard torch? handleDamage(level, x, y, source, item, 0); return true; } diff --git a/src/client/java/minicraft/level/tile/WallTile.java b/src/client/java/minicraft/level/tile/WallTile.java index 998c5e90f..ce1bea91a 100644 --- a/src/client/java/minicraft/level/tile/WallTile.java +++ b/src/client/java/minicraft/level/tile/WallTile.java @@ -78,7 +78,6 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite } } else { Game.notifications.add(obrickMsg); - handleDamage(level, x, y, source, item, 0); } } } diff --git a/src/client/java/minicraft/level/tile/WoolTile.java b/src/client/java/minicraft/level/tile/WoolTile.java index cfce55d5e..995290c14 100644 --- a/src/client/java/minicraft/level/tile/WoolTile.java +++ b/src/client/java/minicraft/level/tile/WoolTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -25,6 +26,13 @@ public WoolTile(WoolType woolType) { @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Hole")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get(name)); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shears) { diff --git a/src/client/java/minicraft/level/tile/farming/FarmTile.java b/src/client/java/minicraft/level/tile/farming/FarmTile.java index 2b3afdb82..95e60b42c 100644 --- a/src/client/java/minicraft/level/tile/farming/FarmTile.java +++ b/src/client/java/minicraft/level/tile/farming/FarmTile.java @@ -1,5 +1,6 @@ package minicraft.level.tile.farming; +import minicraft.core.Game; import minicraft.core.io.Sound; import minicraft.entity.Direction; import minicraft.entity.Entity; @@ -11,6 +12,7 @@ import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; +import minicraft.item.Items; import minicraft.item.ToolItem; import minicraft.item.ToolType; import minicraft.level.Level; @@ -42,6 +44,13 @@ protected void handleDamage(Level level, int x, int y, Entity source, @Nullable @Override public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + if (Game.isMode("minicraft.settings.mode.creative")) { + level.setTile(x, y, Tiles.get("Hole")); + Sound.play("monsterhurt"); + level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); + return true; + } + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { From 51e5e7d7699ec55fafd3148e9e450fdda12385a9 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:22:24 +0800 Subject: [PATCH 13/14] Update player interaction methods --- .../java/minicraft/entity/mob/Player.java | 252 +++++++----------- src/client/java/minicraft/item/ArmorItem.java | 7 +- src/client/java/minicraft/item/BookItem.java | 7 +- .../java/minicraft/item/BucketItem.java | 2 +- .../java/minicraft/item/ClothingItem.java | 7 +- .../java/minicraft/item/FishingRodItem.java | 2 +- src/client/java/minicraft/item/FoodItem.java | 7 +- .../java/minicraft/item/FurnitureItem.java | 2 +- src/client/java/minicraft/item/HeartItem.java | 7 +- src/client/java/minicraft/item/Item.java | 6 +- .../java/minicraft/item/PotionItem.java | 7 +- .../java/minicraft/item/SummonItem.java | 7 +- src/client/java/minicraft/item/TileItem.java | 2 +- src/client/java/minicraft/item/ToolItem.java | 9 +- .../java/minicraft/item/WateringCanItem.java | 2 +- .../java/minicraft/level/tile/StairsTile.java | 15 +- .../java/minicraft/level/tile/Tile.java | 2 +- .../level/tile/farming/FarmTile.java | 2 +- 18 files changed, 116 insertions(+), 229 deletions(-) diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index bb0ba6126..4f395eb20 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -91,11 +91,8 @@ public class Player extends Mob implements ItemHolder, ClientTickable { private final Inventory inventory; public Item activeItem; - Item attackItem; // attackItem is useful again b/c of the power glove. - private Item prevItem; // Holds the item held before using the POW glove. int attackTime; - public Direction attackDir; private int onStairDelay; // The delay before changing levels. private int onFallDelay; // The delay before falling b/c we're on an InfiniteFallTile @@ -194,7 +191,6 @@ public void updateInv(String items) { regentick = 0; questExpanding = 0; - attackDir = dir; armor = 0; curArmor = null; armorDamageBuffer = 0; @@ -509,28 +505,29 @@ public void tick() { level.dropItem(x, y, drop); } - if ((activeItem == null) && (input.inputPressed("attack")) && stamina != 0 && onFallDelay <= 0) { // This only allows attacks when such action is possible. + if (input.inputPressed("attack") && stamina != 0 && onFallDelay <= 0) { // This only allows attacks when such action is possible. if (!potioneffects.containsKey(PotionType.Energy)) stamina--; staminaRecharge = 0; attack(); } - if ((activeItem == null) && (input.inputPressed("USE")) && stamina != 0 && onFallDelay <= 0) { // This only allows interactions when such action is possible. + if (input.inputPressed("USE") && stamina != 0 && onFallDelay <= 0) { // This only allows interactions when such action is possible. if (!potioneffects.containsKey(PotionType.Energy)) stamina--; staminaRecharge = 0; - interact(); + use(); } - if ((input.inputPressed("INVENTORY") || input.inputPressed("craft")) && activeItem != null) { - tryAddToInvOrDrop(activeItem); + if (input.inputPressed("pickup") && (activeItem == null) && stamina != 0 && onFallDelay <= 0) { + if (!potioneffects.containsKey(PotionType.Energy)) stamina--; + staminaRecharge = 0; - activeItem = null; - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } + pickup(); + } + + if ((input.inputPressed("INVENTORY") || input.inputPressed("craft")) && activeItem != null) { + resolveHoldingItem(); } if (Game.getDisplay() == null) { @@ -559,44 +556,24 @@ public void tick() { PotionItem.applyPotion(this, potionType, false); } } - - if (input.inputPressed("pickup") && (activeItem == null)) { - if (!(activeItem instanceof PowerGloveItem)) { // If you are not already holding a power glove (aka in the middle of a separate interaction)... - prevItem = activeItem; // Then save the current item... - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } - activeItem = new PowerGloveItem(); // and replace it with a power glove. - } - attack(); // Attack (with the power glove) - resolveHeldItem(); - } } if (attackTime > 0) { attackTime--; - if (attackTime == 0) attackItem = null; // null the attackItem once we are done attacking. } } } /** - * Removes an held item and places it back into the inventory. - * Looks complicated to so it can handle the powerglove. + * Removes a holding item and places it back into the inventory. */ - public void resolveHeldItem() { - if (!(activeItem instanceof PowerGloveItem)) { // If you are now holding something other than a power glove... - if (prevItem != null) { // and you had a previous item that we should care about... - tryAddToInvOrDrop(prevItem); // Then add that previous item to your inventory so it isn't lost. - } // If something other than a power glove is being held, but the previous item is null, then nothing happens; nothing added to inventory, and current item remains as the new one. - } else - activeItem = prevItem; // Otherwise, if you're holding a power glove, then the held item didn't change, so we can remove the power glove and make it what it was before. - - prevItem = null; // This is no longer of use. - - if (activeItem instanceof PowerGloveItem) // If, for some odd reason, you are still holding a power glove at this point, then null it because it's useless and shouldn't remain in hand. - activeItem = null; + public void resolveHoldingItem() { + tryAddToInvOrDrop(activeItem); + activeItem = null; // Removed + if (isFishing) { + isFishing = false; + fishingTicks = maxFishingTicks; + } } /** @@ -606,10 +583,7 @@ protected void attack() { // walkDist is not synced, so this can happen for both the client and server. walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) - attackDir = dir; // Make the attack direction equal the current direction - attackItem = activeItem; // Make attackItem equal activeItem - - attackTime = 10; + attackTime = activeItem == null ? 5 : 10; // If the interaction between you and an entity is successful, then return. if (attack(getInteractionBox(INTERACT_DIST))) { @@ -621,67 +595,34 @@ protected void attack() { } } return; - } - - // If we are holding an item. - if (activeItem != null) { - boolean done = false; + } // Then there is no entity hitbox blocking the player hitting the tile. - // Attempt to interact with the tile. - Point t = getInteractionTile(); - - // If the target coordinates are a valid tile. - if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { - - // Get any entities (except dropped items and particles) on the tile. - List tileEntities = level.getEntitiesInTiles(t.x, t.y, t.x, t.y, false, ItemEntity.class, Particle.class); + // Attempt to interact with the tile. + Point t = getInteractionTile(); - // If there are no other entities than us on the tile. - if (tileEntities.size() == 0 || tileEntities.size() == 1 && tileEntities.get(0) == this) { - Tile tile = level.getTile(t.x, t.y); - - // If the item successfully interacts with the target tile. - if (activeItem.attackOn(tile, level, t.x, t.y, this, attackDir)) { - done = true; - - // Returns true if the target tile successfully interacts with the item. - } else if (tile.hurt(level, t.x, t.y, this, activeItem, attackDir, 1)) { - done = true; - } - } + // If the target coordinates are a valid tile. + if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { + Tile tile = level.getTile(t.x, t.y); + boolean successful = false; + if (activeItem != null && activeItem.attackOn(tile, level, t.x, t.y, this, dir)) + successful = true; + if (tile.hurt(level, t.x, t.y, this, activeItem, dir, random.nextInt(baseDamage() + 1))) + successful = true; + if (successful) + Logging.PLAYER.info("Attacked tile {} at ({}, {}, {}) with {}", tile, level.depth, t.x, t.y, activeItem); - if (activeItem.isDepleted()) { - // If the activeItem has 0 items left, then "destroy" it. - activeItem = null; - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } + if (successful && activeItem.isDepleted()) { + // If the activeItem has 0 items left, then "destroy" it. + activeItem = null; + if (isFishing) { + isFishing = false; + fishingTicks = maxFishingTicks; } } - if (done) return; // Skip the rest if interaction was handled - } - - if (activeItem == null) { // If there is no active item, OR if the item can be used to attack... - attackTime = 5; - // Attacks the enemy in the appropriate direction. - boolean used = attack(getInteractionBox(ATTACK_DIST)); - - // Attempts to hurt the tile in the appropriate direction. - Point t = getInteractionTile(); - - // Check if tile is in bounds of the map. - if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { - Tile tile = level.getTile(t.x, t.y); - used = tile.hurt(level, t.x, t.y, this, null, attackDir, random.nextInt(3) + 1) || used; - } - - if (used && activeItem instanceof ToolItem) - ((ToolItem) activeItem).payDurability(); } } - protected void interact() { + protected void use() { // walkDist is not synced, so this can happen for both the client and server. walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) @@ -690,57 +631,52 @@ protected void interact() { fishingTicks = maxFishingTicks; } - if (activeItem != null && !activeItem.interactsWithWorld()) { - if (activeItem.interactOn(Tiles.get((short) 0), level, x >> 4, y >> 4, this, attackDir)) { - if (activeItem.isDepleted()) { - activeItem = null; - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } + // If the interaction between you and an entity is successful, then return. + if (use(getInteractionBox(INTERACT_DIST))) return; + + // Attempt to interact with the tile. + Point t = getInteractionTile(); + + // If the target coordinates are a valid tile. + if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { + Tile tile = level.getTile(t.x, t.y); + boolean successful = false; + if (activeItem.useOn(tile, level, t.x, t.y, this, dir)) + successful = true; + if (tile.use(level, t.x, t.y, this, activeItem, dir)) + successful = true; + if (successful) + Logging.PLAYER.info("Used item {} on tile ({}, {}, {}).", activeItem, level.depth, t.x, t.y); + + if (successful && activeItem.isDepleted()) { + // If the activeItem has 0 items left, then "destroy" it. + activeItem = null; + if (isFishing) { + isFishing = false; + fishingTicks = maxFishingTicks; } - return; } } + } - // If the interaction between you and an entity is successful, then return. - if (use(getInteractionBox(INTERACT_DIST))) return; - - // If we are holding an item. - if (activeItem != null) { - boolean done = false; + protected void pickup() { + List entities = level.getEntitiesInRect(getInteractionBox(INTERACT_DIST)); // Gets the entities within the 4 points + boolean blocked = false; + for (Entity e : entities) + if (e != this) { + blocked |= !(e instanceof ItemEntity || e instanceof Particle); + if ((activeItem = e.take(this)) != null) + return; + } + if (!blocked) { // Attempt to interact with the tile. Point t = getInteractionTile(); // If the target coordinates are a valid tile. if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { - - // Get any entities (except dropped items and particles) on the tile. - List tileEntities = level.getEntitiesInTiles(t.x, t.y, t.x, t.y, false, ItemEntity.class, Particle.class); - - // If there are no other entities than us on the tile. - if (tileEntities.size() == 0 || tileEntities.size() == 1 && tileEntities.get(0) == this) { - Tile tile = level.getTile(t.x, t.y); - - // If the item successfully interacts with the target tile. - if (activeItem.interactOn(tile, level, t.x, t.y, this, attackDir)) { - done = true; - - // Returns true if the target tile successfully interacts with the item. - } else if (tile.use(level, t.x, t.y, this, activeItem, attackDir)){ - done = true; - } - } - - if (done && activeItem.isDepleted()) { - // If the activeItem has 0 items left, then "destroy" it. - activeItem = null; - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; - } - } + Tile tile = level.getTile(t.x, t.y); + activeItem = tile.take(level, t.x, t.y, this); } } } @@ -828,8 +764,8 @@ private void goFishing() { private boolean use(Rectangle area) { List entities = level.getEntitiesInRect(area); // Gets the entities within the 4 points for (Entity e : entities) { - if (e instanceof Furniture && e.use(this, activeItem, dir)) - return true; // If the entity is not the player, then call it's use method, and return the result. Only some furniture classes use this. + if (e != this && e.use(this, activeItem, dir)) + return true; // If the entity is not the player, then call it's use method, and return the result. } return false; } @@ -837,14 +773,18 @@ private boolean use(Rectangle area) { /** called by other attack method; this serves as a buffer in case there is no entity in front of the player. */ private boolean attack(Rectangle area) { List entities = level.getEntitiesInRect(area); - boolean sucessful = false; + boolean blocked = false; for (Entity e : entities) { - if (e != this && e.isAttackable(this, activeItem, attackDir) && + if (e != this && e.isAttackable(this, activeItem, dir) && !e.isInvulnerableTo(new DamageSource(DamageSource.DamageType.GENERIC, this, activeItem))) { - sucessful |= attack(e); + blocked |= !(e instanceof ItemEntity || e instanceof Particle); + if (attack(e)) { + Logging.PLAYER.info("Attacked {} with {}.", e, activeItem); + } } } - return sucessful; + // Returns whether there is any entity hitbox blocking interaction on target tile + return blocked; } @Override @@ -853,7 +793,7 @@ public boolean attack(Entity entity) { if (activeItem != null && activeItem instanceof ToolItem) { dmg += ((ToolItem) activeItem).getAttackDamageBonus(entity); // Sword/Axe are more effective at dealing damage. } - return entity.hurt(new DamageSource(DamageSource.DamageType.GENERIC, this, activeItem), attackDir, dmg); + return entity.hurt(new DamageSource(DamageSource.DamageType.GENERIC, this, activeItem), dir, dmg); } /** @@ -937,33 +877,33 @@ public void render(Screen screen) { // Renders slashes: if (attackTime > 0) { - switch (attackDir) { + switch (dir) { case UP: // If currently attacking upwards... screen.render(xo + 0, yo - 4, 3, 0, 0, hudSheet.getSheet()); // Render left half-slash screen.render(xo + 8, yo - 4, 3, 0, 1, hudSheet.getSheet()); // Render right half-slash (mirror of left). - if (attackItem != null && !(attackItem instanceof PowerGloveItem)) { // If the player had an item when they last attacked... - screen.render(xo + 4, yo - 4, attackItem.sprite.getSprite(), 1, false); // Then render the icon of the item, mirrored + if (activeItem != null) { // If the player had an item when they last attacked... + screen.render(xo + 4, yo - 4, activeItem.sprite.getSprite(), 1, false); // Then render the icon of the item, mirrored } break; case LEFT: // Attacking to the left... (Same as above) screen.render(xo - 4, yo, 4, 0, 1, hudSheet.getSheet()); screen.render(xo - 4, yo + 8, 4, 0, 3, hudSheet.getSheet()); - if (attackItem != null && !(attackItem instanceof PowerGloveItem)) { - screen.render(xo - 4, yo + 4, attackItem.sprite.getSprite(), 1, false); + if (activeItem != null) { + screen.render(xo - 4, yo + 4, activeItem.sprite.getSprite(), 1, false); } break; case RIGHT: // Attacking to the right (Same as above) screen.render(xo + 8 + 4, yo, 4, 0, 0, hudSheet.getSheet()); screen.render(xo + 8 + 4, yo + 8, 4, 0, 2, hudSheet.getSheet()); - if (attackItem != null && !(attackItem instanceof PowerGloveItem)) { - screen.render(xo + 8 + 4, yo + 4, attackItem.sprite.getSprite()); + if (activeItem != null) { + screen.render(xo + 8 + 4, yo + 4, activeItem.sprite.getSprite()); } break; case DOWN: // Attacking downwards (Same as above) screen.render(xo + 0, yo + 8 + 4, 3, 0, 2, hudSheet.getSheet()); screen.render(xo + 8, yo + 8 + 4, 3, 0, 3, hudSheet.getSheet()); - if (attackItem != null && !(attackItem instanceof PowerGloveItem)) { - screen.render(xo + 4, yo + 8 + 4, attackItem.sprite.getSprite()); + if (activeItem != null) { + screen.render(xo + 4, yo + 8 + 4, activeItem.sprite.getSprite()); } break; case NONE: diff --git a/src/client/java/minicraft/item/ArmorItem.java b/src/client/java/minicraft/item/ArmorItem.java index 80304ef3f..829e49c94 100644 --- a/src/client/java/minicraft/item/ArmorItem.java +++ b/src/client/java/minicraft/item/ArmorItem.java @@ -39,7 +39,7 @@ private ArmorItem(String name, LinkedSprite sprite, int count, float health, int staminaCost = 9; } - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { boolean success = false; if (player.curArmor == null && player.payStamina(staminaCost)) { player.curArmor = this; // Set the current armor being worn to this. @@ -50,11 +50,6 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return super.interactOn(success); } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull ArmorItem copy() { return new ArmorItem(getName(), sprite, count, armor, level); } diff --git a/src/client/java/minicraft/item/BookItem.java b/src/client/java/minicraft/item/BookItem.java index 2a3b8bf4d..9f9bafff2 100644 --- a/src/client/java/minicraft/item/BookItem.java +++ b/src/client/java/minicraft/item/BookItem.java @@ -41,16 +41,11 @@ private BookItem(String title, LinkedSprite sprite, BookContent book, boolean ha this.hasTitlePage = hasTitlePage; } - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { Game.setDisplay(new BookDisplay(book.collect(), hasTitlePage)); return true; } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull BookItem copy() { return new BookItem(getName(), sprite, book, hasTitlePage); } diff --git a/src/client/java/minicraft/item/BucketItem.java b/src/client/java/minicraft/item/BucketItem.java index 608c6e8c2..5b21e5bd8 100644 --- a/src/client/java/minicraft/item/BucketItem.java +++ b/src/client/java/minicraft/item/BucketItem.java @@ -57,7 +57,7 @@ private BucketItem(Fill fill, int count) { this.filling = fill; } - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { Fill fill = getFilling(tile); if (fill == null) return false; diff --git a/src/client/java/minicraft/item/ClothingItem.java b/src/client/java/minicraft/item/ClothingItem.java index 49711a92a..6e1e1b7e3 100644 --- a/src/client/java/minicraft/item/ClothingItem.java +++ b/src/client/java/minicraft/item/ClothingItem.java @@ -42,7 +42,7 @@ private ClothingItem(String name, int count, LinkedSprite sprite, int pcol) { } // Put on clothes - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (player.shirtColor == playerCol) { return false; } else { @@ -60,11 +60,6 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, } } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull ClothingItem copy() { return new ClothingItem(getName(), count, sprite, playerCol); } diff --git a/src/client/java/minicraft/item/FishingRodItem.java b/src/client/java/minicraft/item/FishingRodItem.java index f7d7b9be7..4f5148965 100644 --- a/src/client/java/minicraft/item/FishingRodItem.java +++ b/src/client/java/minicraft/item/FishingRodItem.java @@ -58,7 +58,7 @@ public static int getChance(int idx, int level) { } @Override - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (tile == Tiles.get("water") && !player.isSwimming()) { // Make sure not to use it if swimming uses++; player.isFishing = true; diff --git a/src/client/java/minicraft/item/FoodItem.java b/src/client/java/minicraft/item/FoodItem.java index 1be9c9e81..58c0e88e7 100644 --- a/src/client/java/minicraft/item/FoodItem.java +++ b/src/client/java/minicraft/item/FoodItem.java @@ -44,7 +44,7 @@ private FoodItem(String name, LinkedSprite sprite, int count, int feed) { /** * What happens when the player uses the item on a tile */ - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { boolean success = false; if (count > 0 && player.hunger < Player.maxHunger && player.payStamina(staminaCost)) { // If the player has hunger to fill, and stamina to pay... player.hunger = Math.min(player.hunger + feed, Player.maxHunger); // Restore the hunger @@ -54,11 +54,6 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return super.interactOn(success); } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull FoodItem copy() { return new FoodItem(getName(), sprite, count, feed); } diff --git a/src/client/java/minicraft/item/FurnitureItem.java b/src/client/java/minicraft/item/FurnitureItem.java index 86325c48a..cc979ff70 100644 --- a/src/client/java/minicraft/item/FurnitureItem.java +++ b/src/client/java/minicraft/item/FurnitureItem.java @@ -73,7 +73,7 @@ public FurnitureItem(Furniture furniture) { } /** What happens when you press the "Attack" key with the furniture in your hands */ - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (tile.mayPass(level, xt, yt, furniture)) { // If the furniture can go on the tile Sound.play("craft"); diff --git a/src/client/java/minicraft/item/HeartItem.java b/src/client/java/minicraft/item/HeartItem.java index 632d5d2b3..ffda1e028 100644 --- a/src/client/java/minicraft/item/HeartItem.java +++ b/src/client/java/minicraft/item/HeartItem.java @@ -36,7 +36,7 @@ private HeartItem(String name, SpriteLinker.LinkedSprite sprite, int count, int /** * What happens when the player uses the item on a tile */ - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { boolean success = false; if ((Player.baseHealth + Player.extraHealth) < Player.maxHealth) { @@ -51,11 +51,6 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return super.interactOn(success); } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull HeartItem copy() { return new HeartItem(getName(), sprite, count, health); } diff --git a/src/client/java/minicraft/item/Item.java b/src/client/java/minicraft/item/Item.java index 3a48608f1..4605f0b31 100644 --- a/src/client/java/minicraft/item/Item.java +++ b/src/client/java/minicraft/item/Item.java @@ -46,7 +46,7 @@ public boolean attackOn(Tile tile, Level level, int xt, int yt, Player player, D } /** Determines what happens when the player interacts with a tile */ - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { return false; } @@ -102,8 +102,4 @@ public final String getName() { public String getDisplayName() { return " " + Localization.getLocalized(getName()); } - - public boolean interactsWithWorld() { - return true; - } } diff --git a/src/client/java/minicraft/item/PotionItem.java b/src/client/java/minicraft/item/PotionItem.java index 55ca3775e..e3e0316fb 100644 --- a/src/client/java/minicraft/item/PotionItem.java +++ b/src/client/java/minicraft/item/PotionItem.java @@ -35,7 +35,7 @@ private PotionItem(PotionType type, int count) { } // The return value is used to determine if the potion was used, which means being discarded. - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (type.equals(PotionType.Lava)) { AchievementsDisplay.setAchievement("minicraft.achievement.lava", true); } @@ -78,11 +78,6 @@ public int hashCode() { return super.hashCode() + type.name.hashCode(); } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull PotionItem copy() { return new PotionItem(type, count); } diff --git a/src/client/java/minicraft/item/SummonItem.java b/src/client/java/minicraft/item/SummonItem.java index bf0d73df0..04280660b 100644 --- a/src/client/java/minicraft/item/SummonItem.java +++ b/src/client/java/minicraft/item/SummonItem.java @@ -43,7 +43,7 @@ private SummonItem(String name, LinkedSprite sprite, int count, String mob) { /** * What happens when the player uses the item on a tile */ - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { boolean success = false; switch (mob) { @@ -109,11 +109,6 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return super.interactOn(success); } - @Override - public boolean interactsWithWorld() { - return false; - } - public @NotNull SummonItem copy() { return new SummonItem(getName(), sprite, count, mob); } diff --git a/src/client/java/minicraft/item/TileItem.java b/src/client/java/minicraft/item/TileItem.java index 4c4ea0d3e..48519bd23 100644 --- a/src/client/java/minicraft/item/TileItem.java +++ b/src/client/java/minicraft/item/TileItem.java @@ -144,7 +144,7 @@ public static int getTileData(@Nullable TileModel model, Tile tile, Tile target, } } - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { for (String tilename : validTiles) { if (tile.matches(level.getData(xt, yt), tilename)) { Tile t = TileModel.getTile(model); diff --git a/src/client/java/minicraft/item/ToolItem.java b/src/client/java/minicraft/item/ToolItem.java index 419df4254..53b4c8bcb 100644 --- a/src/client/java/minicraft/item/ToolItem.java +++ b/src/client/java/minicraft/item/ToolItem.java @@ -84,12 +84,7 @@ public boolean isDepleted() { } @Override - public boolean interactsWithWorld() { - return type != ToolType.Bow; - } - - @Override - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { Inventory inventory = player.getInventory(); // Fire a bow if the player has the stamina and an arrow. if (type == ToolType.Bow && player.payStamina(1) && inventory.count(Items.arrowItem) > 0) { @@ -100,7 +95,7 @@ public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, return true; } - return super.interactOn(tile, level, xt, yt, player, attackDir); + return super.useOn(tile, level, xt, yt, player, attackDir); } public boolean payDurability() { diff --git a/src/client/java/minicraft/item/WateringCanItem.java b/src/client/java/minicraft/item/WateringCanItem.java index 486d1c218..64daf140e 100644 --- a/src/client/java/minicraft/item/WateringCanItem.java +++ b/src/client/java/minicraft/item/WateringCanItem.java @@ -45,7 +45,7 @@ protected WateringCanItem(String name) { } @Override - public boolean interactOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { + public boolean useOn(Tile tile, Level level, int xt, int yt, Player player, Direction attackDir) { if (tile instanceof WaterTile) { content = CAPACITY; updateSprite(); diff --git a/src/client/java/minicraft/level/tile/StairsTile.java b/src/client/java/minicraft/level/tile/StairsTile.java index f72a0e70b..8871201a8 100644 --- a/src/client/java/minicraft/level/tile/StairsTile.java +++ b/src/client/java/minicraft/level/tile/StairsTile.java @@ -2,7 +2,6 @@ import minicraft.core.Game; import minicraft.core.io.Sound; -import minicraft.entity.Direction; import minicraft.entity.Entity; import minicraft.entity.furniture.Furniture; import minicraft.entity.mob.Player; @@ -10,9 +9,7 @@ import minicraft.gfx.SpriteAnimation; import minicraft.gfx.SpriteLinker.SpriteType; import minicraft.item.Item; -import minicraft.item.PowerGloveItem; import minicraft.level.Level; -import minicraft.util.AdvancementElement; import org.jetbrains.annotations.Nullable; public class StairsTile extends Tile { @@ -41,18 +38,12 @@ public boolean mayPass(Level level, int x, int y, Entity e) { protected void handleDamage(Level level, int x, int y, Entity source, @Nullable Item item, int dmg) {} @Override - public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item item, Direction attackDir, int damage) { + public @Nullable Item take(Level level, int x, int y, Player player) { // Makes it so you can remove the stairs if you are in creative and debug mode. - if (item instanceof PowerGloveItem && Game.isMode("minicraft.settings.mode.creative")) { - int data = level.getData(x, y); + if (Game.isMode("minicraft.settings.mode.creative")) { level.setTile(x, y, Tiles.get("Grass")); Sound.play("monsterhurt"); - AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.INSTANCE.trigger( - new AdvancementElement.AdvancementTrigger.ItemUsedOnTileTrigger.ItemUsedOnTileTriggerConditionHandler.ItemUsedOnTileTriggerConditions( - item, this, data, x, y, level.depth)); - return true; - } else { - return false; } + return null; } } diff --git a/src/client/java/minicraft/level/tile/Tile.java b/src/client/java/minicraft/level/tile/Tile.java index 8f7d2ad99..041063d06 100644 --- a/src/client/java/minicraft/level/tile/Tile.java +++ b/src/client/java/minicraft/level/tile/Tile.java @@ -196,7 +196,7 @@ public int getData(String data) { /** * @deprecated Similar to {@link #getData(String)}. Also, param {@code thisData} is unused. - * The current only usage is in {@link minicraft.item.TileItem#interactOn(Tile, Level, int, int, Player, Direction)}. + * The current only usage is in {@link minicraft.item.TileItem#useOn(Tile, Level, int, int, Player, Direction)}. */ @Deprecated public boolean matches(int thisData, String tileInfo) { diff --git a/src/client/java/minicraft/level/tile/farming/FarmTile.java b/src/client/java/minicraft/level/tile/farming/FarmTile.java index 95e60b42c..0931203f5 100644 --- a/src/client/java/minicraft/level/tile/farming/FarmTile.java +++ b/src/client/java/minicraft/level/tile/farming/FarmTile.java @@ -50,7 +50,7 @@ public boolean hurt(Level level, int x, int y, Entity source, @Nullable Item ite level.dropItem((x << 4) + 8, (y << 4) + 8, Items.get("Dirt")); return true; } - + if (item instanceof ToolItem && source instanceof Player) { ToolItem tool = (ToolItem) item; if (tool.type == ToolType.Shovel) { From 38270460335d6414471df0e3897fe631683b0a53 Mon Sep 17 00:00:00 2001 From: BenCheung0422 <74168521+BenCheung0422@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:33:14 +0800 Subject: [PATCH 14/14] Resolve interaction errors --- .../java/minicraft/entity/mob/Player.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/client/java/minicraft/entity/mob/Player.java b/src/client/java/minicraft/entity/mob/Player.java index 4f395eb20..bbcdaa89c 100644 --- a/src/client/java/minicraft/entity/mob/Player.java +++ b/src/client/java/minicraft/entity/mob/Player.java @@ -90,7 +90,7 @@ public class Player extends Mob implements ItemHolder, ClientTickable { private final Inventory inventory; - public Item activeItem; + public @Nullable Item activeItem; int attackTime; @@ -568,11 +568,13 @@ public void tick() { * Removes a holding item and places it back into the inventory. */ public void resolveHoldingItem() { - tryAddToInvOrDrop(activeItem); - activeItem = null; // Removed - if (isFishing) { - isFishing = false; - fishingTicks = maxFishingTicks; + if (activeItem != null) { + tryAddToInvOrDrop(activeItem); + activeItem = null; // Removed + if (isFishing) { + isFishing = false; + fishingTicks = maxFishingTicks; + } } } @@ -582,12 +584,11 @@ public void resolveHoldingItem() { protected void attack() { // walkDist is not synced, so this can happen for both the client and server. walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) - attackTime = activeItem == null ? 5 : 10; // If the interaction between you and an entity is successful, then return. if (attack(getInteractionBox(INTERACT_DIST))) { - if (activeItem.isDepleted()) { + if (activeItem != null && activeItem.isDepleted()) { activeItem = null; if (isFishing) { isFishing = false; @@ -611,7 +612,7 @@ protected void attack() { if (successful) Logging.PLAYER.info("Attacked tile {} at ({}, {}, {}) with {}", tile, level.depth, t.x, t.y, activeItem); - if (successful && activeItem.isDepleted()) { + if (successful && activeItem != null && activeItem.isDepleted()) { // If the activeItem has 0 items left, then "destroy" it. activeItem = null; if (isFishing) { @@ -625,6 +626,7 @@ protected void attack() { protected void use() { // walkDist is not synced, so this can happen for both the client and server. walkDist += 8; // Increase the walkDist (changes the sprite, like you moved your arm) + attackTime = activeItem == null ? 5 : 10; if (isFishing) { isFishing = false; @@ -641,14 +643,14 @@ protected void use() { if (t.x >= 0 && t.y >= 0 && t.x < level.w && t.y < level.h) { Tile tile = level.getTile(t.x, t.y); boolean successful = false; - if (activeItem.useOn(tile, level, t.x, t.y, this, dir)) + if (activeItem != null && activeItem.useOn(tile, level, t.x, t.y, this, dir)) successful = true; if (tile.use(level, t.x, t.y, this, activeItem, dir)) successful = true; if (successful) Logging.PLAYER.info("Used item {} on tile ({}, {}, {}).", activeItem, level.depth, t.x, t.y); - if (successful && activeItem.isDepleted()) { + if (successful && activeItem != null && activeItem.isDepleted()) { // If the activeItem has 0 items left, then "destroy" it. activeItem = null; if (isFishing) { @@ -912,7 +914,7 @@ public void render(Screen screen) { } // Renders the fishing rods when fishing - if (isFishing) { + if (isFishing && activeItem != null) { switch (dir) { case UP: screen.render(xo + 4, yo - 4, activeItem.sprite.getSprite(), 1, false); @@ -945,6 +947,7 @@ public void pickupItem(ItemEntity itemEntity) { boolean successful = false; // If there is any item successfully added to the player boolean remove = false; // Whether to remove the item entity (when empty) if (itemEntity.item instanceof StackableItem && ((StackableItem) itemEntity.item).stacksWith(activeItem)) { // Picked up item equals the one in your hand + assert activeItem != null; int toAdd = Math.min(((StackableItem) activeItem).count + ((StackableItem) itemEntity.item).count, ((StackableItem) activeItem).maxCount) - ((StackableItem) activeItem).count; if (toAdd > 0) {