Skip to content

Commit

Permalink
Merge pull request #7 from AnvilloyDevStudio/plus-pr-552
Browse files Browse the repository at this point in the history
Explicitly separate rigidly definite player interaction actions
  • Loading branch information
BenCheung0422 authored Jan 20, 2025
2 parents 3c2c7df + 524046f commit 4100f74
Show file tree
Hide file tree
Showing 88 changed files with 1,641 additions and 866 deletions.
6 changes: 3 additions & 3 deletions src/client/java/minicraft/core/Renderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,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<PotionType, Integer>[] 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 {
Expand Down
25 changes: 13 additions & 12 deletions src/client/java/minicraft/core/io/InputHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,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("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.
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
Expand All @@ -166,12 +167,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");
}
Expand All @@ -194,16 +194,17 @@ private void initButtonMap() {
buttonMap.put("EXIT", ControllerButton.B);

buttonMap.put("ATTACK", ControllerButton.A);
buttonMap.put("MENU", ControllerButton.X);
buttonMap.put("USE", ControllerButton.B);
buttonMap.put("INVENTORY", ControllerButton.X);
buttonMap.put("CRAFT", ControllerButton.Y);
buttonMap.put("PICKUP", ControllerButton.LEFTBUMPER);
buttonMap.put("PICKUP", ControllerButton.LEFTSTICK);

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() {
Expand Down
35 changes: 33 additions & 2 deletions src/client/java/minicraft/entity/Arrow.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
import minicraft.gfx.Screen;
import minicraft.gfx.SpriteManager.SpriteLink;
import minicraft.gfx.SpriteManager.SpriteType;
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;

import javax.security.auth.DestroyFailedException;

import java.util.List;

Expand Down Expand Up @@ -82,8 +90,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.
damage = mob.calculateEntityDamage(this, damage);
mob.hurt(owner, damage, dir); //normal hurting to other mobs
mob.hurt(new DamageSource(DamageSource.DamageType.ARROW, owner, this, null),
dir, damage); // normal hurting to other mobs
}

if (!level.getTile(x >> 4, y >> 4).mayPass(level, x >> 4, y >> 4, this)
Expand All @@ -98,6 +106,29 @@ 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 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) {
screen.render(x - 4, y - 4, sprite);
Expand Down
4 changes: 4 additions & 0 deletions src/client/java/minicraft/entity/Direction.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ public static Direction getDirection(int dir) {
public int getDir() {
return ordinal() - 1;
}

public Direction getOpposite() {
return Direction.getDirection(getDir() ^ 0b11);
}
}
101 changes: 96 additions & 5 deletions src/client/java/minicraft/entity/Entity.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package minicraft.entity;

import minicraft.core.Action;
import minicraft.core.Game;
import minicraft.core.Updater;
import minicraft.entity.mob.Player;
import minicraft.gfx.Rectangle;
import minicraft.gfx.Screen;
import minicraft.item.Item;
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;

Expand All @@ -33,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
Expand Down Expand Up @@ -141,17 +157,92 @@ 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
*/
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 #hurt(DamageSource, 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 #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.getCausingEntity() instanceof Player && Game.isMode("minicraft.settings.mode.creative") ||
source.getDamageType().isFireRelated() && isFireImmune();
}

/**
* Interacts with the entity this method is called on
* @param player The player attacking
* @param item The item the player attacked with
* 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 #use(Player, Item, Direction)} 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.

/**
* Hurt the entity directly, based on only damage and a direction
* Usually this is invoked by {@link #hurt(DamageSource, Direction, int)}.<p>
* 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
*/
protected abstract void handleDamage(DamageSource source, Direction attackDir, int damage);

/**
* 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 interact(Player player, @Nullable Item item, Direction attackDir) {
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);
}

/**
* 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.
*/
Expand Down Expand Up @@ -309,7 +400,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();
}

Expand Down
26 changes: 26 additions & 0 deletions src/client/java/minicraft/entity/ExplosionTileTicker.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
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 minicraft.util.DamageSource;
import org.jetbrains.annotations.Nullable;

// This is a kind of tile entity. Maybe this should be savable.
public class ExplosionTileTicker extends Entity {
Expand Down Expand Up @@ -53,4 +56,27 @@ 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 handleDamage(DamageSource source, Direction attackDir, int damage) {}

@Override
public boolean hurt(DamageSource source, Direction attackDir, int damage) {
return false;
}
}
28 changes: 28 additions & 0 deletions src/client/java/minicraft/entity/FireSpark.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import minicraft.gfx.Color;
import minicraft.gfx.Screen;
import minicraft.gfx.SpriteManager;
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 {
private static final SpriteManager.SpriteLink sprite =
Expand Down Expand Up @@ -89,6 +94,29 @@ 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 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) {
int randmirror = 0;
Expand Down
Loading

0 comments on commit 4100f74

Please sign in to comment.