Add support for throwing weapon
This commit is contained in:
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
@@ -6,7 +6,6 @@ import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class WeaponBasedAI implements AI {
|
||||
@@ -54,23 +53,32 @@ public class WeaponBasedAI implements AI {
|
||||
|
||||
var meleeWeapon = enemy.getMeleeWeapon();
|
||||
var rangedWeapon = enemy.getRangedWeapon();
|
||||
var throwingWeapon = enemy.getThrowingWeapon();
|
||||
|
||||
if (meleeWeapon == null && rangedWeapon == null) {
|
||||
if (meleeWeapon == null && rangedWeapon == null && throwingWeapon == null) {
|
||||
runawayAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rangedWeapon == null || enemy.manhattanDistance(target) == 1 || enemy.getAmmunition() == null) {
|
||||
if ((rangedWeapon == null && throwingWeapon == null) || (rangedWeapon != null && enemy.getAmmunition() == null && throwingWeapon == null) || enemy.manhattanDistance(target) == 1) {
|
||||
enemy.setWeapon(meleeWeapon);
|
||||
meleeAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enemy.getWeapon() instanceof MeleeWeapon) {
|
||||
meleeAI.nextActivity(layer, dt);
|
||||
if (throwingWeapon != null) {
|
||||
enemy.setWeapon(throwingWeapon);
|
||||
archerAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
enemy.setWeapon(rangedWeapon);
|
||||
archerAI.nextActivity(layer, dt);
|
||||
|
||||
// if (enemy.getWeapon() instanceof MeleeWeapon) {
|
||||
// meleeAI.nextActivity(layer, dt);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,10 @@ import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -38,6 +40,9 @@ public class Enemy extends Creature implements NPC {
|
||||
private MeleeWeapon meleeWeapon;
|
||||
@Getter
|
||||
private RangedWeapon rangedWeapon;
|
||||
@Getter
|
||||
@Setter
|
||||
private ThrowingWeapon throwingWeapon;
|
||||
|
||||
public Enemy(@NonNull String id) {
|
||||
this(DB.dao.enemy.find(id));
|
||||
@@ -55,6 +60,7 @@ public class Enemy extends Creature implements NPC {
|
||||
setBlocking(template.isBlocking());
|
||||
var meleeWeaponTemplate = template.getMeleeWeapon();
|
||||
var rangedWeaponTemplate = template.getRangedWeapon();
|
||||
var throwingWeaponTemplate = template.getThrowingWeapon();
|
||||
|
||||
if (meleeWeaponTemplate != null) {
|
||||
this.meleeWeapon = new MeleeWeapon(meleeWeaponTemplate);
|
||||
@@ -67,6 +73,11 @@ public class Enemy extends Creature implements NPC {
|
||||
setAmmunition(new Ammunition(split[1], DiceRoller.roll(split[2])));
|
||||
}
|
||||
|
||||
if (throwingWeaponTemplate != null) {
|
||||
var split = throwingWeaponTemplate.split(",");
|
||||
this.throwingWeapon = new ThrowingWeapon(split[0], DiceRoller.roll(split[1]));
|
||||
}
|
||||
|
||||
this.dieAnimation = new SimpleAnimationRunner(A.animations.get(template.getDieAnimation()).uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||
import lombok.NonNull;
|
||||
import org.joml.Vector2i;
|
||||
@@ -80,6 +81,13 @@ public class Player extends Creature {
|
||||
}
|
||||
}
|
||||
|
||||
if (item instanceof ThrowingWeapon weapons) {
|
||||
if (getWeapon() instanceof ThrowingWeapon currentWeapons && currentWeapons.getId().equals(weapons.getId())) {
|
||||
currentWeapons.increase(weapons.getCount());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (item instanceof ItemStack stack) {
|
||||
return pushItemStackToEquipment(stack);
|
||||
}
|
||||
@@ -148,18 +156,42 @@ public class Player extends Creature {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeapon(Weapon weapon) {
|
||||
public void setWeapon(Weapon newWeapon) {
|
||||
var currentWeapon = getWeapon();
|
||||
|
||||
if (weapon != null) {
|
||||
removeItemFromEquipment(weapon);
|
||||
if (newWeapon == null) {
|
||||
disarmWeapon(currentWeapon);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentWeapon instanceof ThrowingWeapon currentWeapons && newWeapon instanceof ThrowingWeapon weapons && currentWeapons.getId().equals(weapons.getId())) {
|
||||
updateStackableWeapon(currentWeapons, weapons);
|
||||
return;
|
||||
}
|
||||
|
||||
changeWeaponForWeapon(currentWeapon, newWeapon);
|
||||
}
|
||||
|
||||
private void disarmWeapon(Weapon currentWeapon) {
|
||||
if (!(currentWeapon instanceof ThrowingWeapon)) {
|
||||
pushItemToEquipment(currentWeapon);
|
||||
}
|
||||
|
||||
super.setWeapon(null);
|
||||
}
|
||||
|
||||
private void updateStackableWeapon(ThrowingWeapon currentWeapon, ThrowingWeapon newWeapon) {
|
||||
currentWeapon.increase(newWeapon.getCount());
|
||||
removeItemFromEquipment(newWeapon);
|
||||
}
|
||||
|
||||
private void changeWeaponForWeapon(Weapon currentWeapon, Weapon newWeapon) {
|
||||
super.setWeapon(newWeapon);
|
||||
removeItemFromEquipment(newWeapon);
|
||||
|
||||
if (currentWeapon != null) {
|
||||
pushItemToEquipment(currentWeapon);
|
||||
}
|
||||
|
||||
super.setWeapon(weapon);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.bartlomiejpluta.demo.world.item.Useable;
|
||||
import com.bartlomiejpluta.demo.world.potion.Medicament;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -182,6 +183,10 @@ public class EquipmentWindow extends DecoratedWindow {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof ThrowingWeapon weapon) {
|
||||
detailsLbl.setText(format("Damage: %s\nRange: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getRangeRoller(), weapon.getCooldown()));
|
||||
}
|
||||
|
||||
if (item instanceof Medicament medicament) {
|
||||
detailsLbl.setText(format("Restores: %s HP\n", medicament.getRoller()));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.bartlomiejpluta.demo.world.potion.Medicament;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -29,6 +30,7 @@ public class LootGenerator {
|
||||
);
|
||||
private static final Map<String, BiFunction<String, Integer, ItemStack>> stackableGenerator = Map.of(
|
||||
"ammo", Ammunition::new,
|
||||
"throwing", ThrowingWeapon::new,
|
||||
"med", Medicament::new
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.bartlomiejpluta.demo.world.weapon;
|
||||
|
||||
import DB.dao;
|
||||
import com.bartlomiejpluta.base.api.animation.Animation;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.move.Movable;
|
||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.BulletAnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||
import com.bartlomiejpluta.demo.world.item.StackableItem;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
public class ThrowingWeapon extends StackableItem implements Weapon {
|
||||
private final Context context;
|
||||
private final BulletAnimationRunner animation;
|
||||
private final String sound;
|
||||
private final AnimationRunner punchAnimation;
|
||||
private final String punchSound;
|
||||
private final AnimationRunner missAnimation;
|
||||
|
||||
private final String missSound;
|
||||
|
||||
@Getter
|
||||
private final String id;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final DiceRoller dmgRoller;
|
||||
|
||||
@Getter
|
||||
private final DiceRoller rangeRoller;
|
||||
|
||||
@Getter
|
||||
private final int cooldown;
|
||||
|
||||
public ThrowingWeapon(@NonNull String id, int count) {
|
||||
this(dao.throwing_weapon.find(id), count);
|
||||
}
|
||||
|
||||
public ThrowingWeapon(@NonNull DB.model.ThrowingWeaponModel template, int count) {
|
||||
super(template.getIcon(), count);
|
||||
|
||||
this.context = ContextHolder.INSTANCE.getContext();
|
||||
this.id = format("throwing:%s", template.getId());
|
||||
this.name = template.getName();
|
||||
this.dmgRoller = DiceRoller.of(template.getDamage());
|
||||
this.rangeRoller = DiceRoller.of(template.getRange());
|
||||
this.cooldown = template.getCooldown();
|
||||
this.animation = new BulletAnimationRunner(A.animations.get(template.getAnimation()).uid).infinite().offset(0, -15).onHit(this::onHit).onMiss(this::onMiss).speed(7f).animationSpeed(4f).scale(0.6f);
|
||||
this.sound = A.sounds.get(template.getSound()).uid;
|
||||
this.punchAnimation = new SimpleAnimationRunner(A.animations.get(template.getPunchAnimation()).uid);
|
||||
this.punchSound = A.sounds.get(template.getPunchSound()).uid;
|
||||
this.missAnimation = new SimpleAnimationRunner(A.animations.get(template.getMissAnimation()).uid).scale(0.4f);
|
||||
this.missSound = A.sounds.get(template.getMissSound()).uid;
|
||||
}
|
||||
|
||||
private void onHit(Movable attacker, Entity target) {
|
||||
if (target.isBlocking() && target instanceof Creature character) {
|
||||
var namedAttacker = (Creature) attacker;
|
||||
var damage = dmgRoller.roll();
|
||||
character.hit(namedAttacker, damage);
|
||||
punchAnimation.run(context, character.getLayer(), character);
|
||||
context.playSound(punchSound);
|
||||
context.fireEvent(new HitEvent(namedAttacker, character, damage));
|
||||
}
|
||||
}
|
||||
|
||||
private void onMiss(Movable attacker, Animation animation) {
|
||||
missAnimation.run(context, ((Creature) attacker).getLayer(), animation.getPosition());
|
||||
context.playSound(missSound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attack(Creature attacker) {
|
||||
if (--count == 0) {
|
||||
attacker.setWeapon(null);
|
||||
|
||||
if (attacker instanceof Enemy enemy) {
|
||||
enemy.setThrowingWeapon(null);
|
||||
}
|
||||
}
|
||||
|
||||
var direction = attacker.getFaceDirection();
|
||||
context.playSound(sound);
|
||||
animation.range(rangeRoller.roll())
|
||||
.direction(direction)
|
||||
.rotation(direction.xAngle - 180)
|
||||
.run(context, attacker.getLayer(), attacker);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Creature creature) {
|
||||
creature.setWeapon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String usageName() {
|
||||
return "Arm";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user