From 1d5afb0530604c2670dedd6f8755690b3234c2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sat, 3 Sep 2022 00:12:21 +0200 Subject: [PATCH] Add support for throwing weapon --- data.mv.db | Bin 57344 -> 28672 bytes .../demo/ai/WeaponBasedAI.java | 18 ++- .../bartlomiejpluta/demo/entity/Enemy.java | 11 ++ .../bartlomiejpluta/demo/entity/Player.java | 42 ++++++- .../demo/gui/EquipmentWindow.java | 5 + .../demo/util/LootGenerator.java | 2 + .../demo/world/weapon/ThrowingWeapon.java | 113 ++++++++++++++++++ 7 files changed, 181 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/bartlomiejpluta/demo/world/weapon/ThrowingWeapon.java diff --git a/data.mv.db b/data.mv.db index 1f6bfef39e22e0cc21a7b00bf72f820ac3f533cb..f53e8cf3e774e67d16f865ac304952b6d31044e7 100644 GIT binary patch delta 4694 zcmZoTz})bFQPsoBNGB;LKRMgV6ha4QR;5}Q8WJ;VYmslAZS|%nN7#J8>q!<~P>Xc;WrdpYr8XKCV znxyEIr4|)u=I4RjoisV2AY$?X1y&|EyUE8DCa_67i@(9FIr(IPw4o5I2&*WoB&!sw zG^-4&EUP@L0;?jc600(+3acus8ml_12CF8k7OOU^4y!J!9;^Ol{=zRDlaF}$ZSM6+ zX51`P|B-3)ZX-1oPC*tHbp-|9t;~}JedRbpJc9hgJ^kD#HjrWmlbO?Gc|SQ;Jq1p|MwCkGg1urV+&=*84cj#kuRiV2zAsTjf(^L6rlMR~E9`6t*J84MW&nG`*Y z4Gatz7#OT$mP{5=vSf;lnC!14#T5H>a<68W*J*7#PZ#m0mM_fiMkywfrz;uT1-Pf? zr50r->saU*g1jmfdHpjxBZD9ll4e5&1_lPE{%Do2>>Lb+#wMl^|1b#hOs-T`P-S2U zL0F_?m|~)Biwk22FXgfNLHhi%1AD-!0H0Hjl_pR z;$#C|#myg6wlYpO3{#w(I8CnJBr#b5lp?G$^HNeP^h^wNl8aIkOH$#%2v-0}GA2ft z3Q|x^FeaqH6iERGxK1%iOqm?NT%Os~(r9wya(O0G%gKRZl57kNjMwvCPJVyRZ?fNX zel1AKg}D=jXNz=L}6nKb7rGN6K3NyV`k$tGiKv7^U40R#iflc%$SW5 zjhT%s4VaBnO_`08Ef^S>Cgxvbke%E(TZRu}9L&d)=gzj9{B3q^eX1!3sHW62PBVfr zjA0D8lo?FKoE@y#G6_m2GaIKFF&kMVG8?CvG8>r~Gg&4v8>d+?8>dU|?>XY>;f zS#g?yA(EplERB<);Q{i$fkl!Tie^K@WMs39Qj<*#49rm|Q&TgL`4&dt){Pm|TP%g~rFfKIEVO*%oVO*%opW@gEg`PW@MCVVhK(0$x!8H;NBVb6pu5gk@8eB zEXAj|O@*X*25c!Fcgydza~!UgUm_y$CxMeJ6lPMLz5La3DdvDmpFOi zWVjo!w)m*m-a=|~qGtJe@Yn#Xe-6s#c=9}Qc%ifriR!sy&GI}*=_qMP<;KZ|=d6c9 f>veOxdkqu5QUg&8AjL&8Qax#8nrf5+E;alC%4m8l literal 57344 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 stackableGenerator = Map.of( "ammo", Ammunition::new, + "throwing", ThrowingWeapon::new, "med", Medicament::new ); diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/ThrowingWeapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/ThrowingWeapon.java new file mode 100644 index 0000000..4019ade --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/ThrowingWeapon.java @@ -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"; + } +} \ No newline at end of file