use of jackiecrazy.wardance.api.CombatDamageSource in project WarDance by Jackiecrazy.
the class ShadowlessKick method kick.
private boolean kick(LivingEntity caster, SkillData stats) {
LivingEntity target = GeneralUtils.raytraceLiving(caster, distance());
if (target != null) {
CombatData.getCap(target).consumePosture(caster, 2);
if (caster instanceof PlayerEntity && caster.level instanceof ServerWorld) {
double d0 = (double) (-MathHelper.sin(caster.yRot * ((float) Math.PI / 180F)));
double d1 = (double) MathHelper.cos(caster.yRot * ((float) Math.PI / 180F));
((ServerWorld) caster.level).sendParticles(ParticleTypes.EXPLOSION, caster.getX() + d0, caster.getY(0.5D), caster.getZ() + d1, 0, d0, 0.0D, d1, 0.0D);
}
target.hurt(new CombatDamageSource("fallingBlock", caster).setDamageTyping(CombatDamageSource.TYPE.PHYSICAL).setProcSkillEffects(true).setProcNormalEffects(false).setProcAttackEffects(true).setKnockbackPercentage(0.7f), 1);
if (target.getLastHurtByMob() == null)
target.setLastHurtByMob(caster);
stats.setArbitraryFloat(stats.getArbitraryFloat() + 1);
if (stats.getArbitraryFloat() >= 6) {
markUsed(caster);
caster.level.playSound(null, caster.getX(), caster.getY(), caster.getZ(), SoundEvents.DRAGON_FIREBALL_EXPLODE, SoundCategory.PLAYERS, 0.5f + WarDance.rand.nextFloat() * 0.5f, 0.5f + WarDance.rand.nextFloat() * 0.5f);
return false;
}
caster.level.playSound(null, caster.getX(), caster.getY(), caster.getZ(), SoundEvents.ZOMBIE_ATTACK_WOODEN_DOOR, SoundCategory.PLAYERS, 0.25f + WarDance.rand.nextFloat() * 0.5f, 0.5f + WarDance.rand.nextFloat() * 0.5f);
return true;
}
return false;
}
use of jackiecrazy.wardance.api.CombatDamageSource in project WarDance by Jackiecrazy.
the class CombatHandler method pain.
@SubscribeEvent(priority = EventPriority.HIGHEST)
public static void pain(LivingHurtEvent e) {
if (GeneralConfig.debug)
WarDance.LOGGER.debug("damage from " + e.getSource() + " received with amount " + e.getAmount());
LivingEntity uke = e.getEntityLiving();
uke.removeEffect(WarEffects.DISTRACTION.get());
uke.removeEffect(WarEffects.FEAR.get());
uke.removeEffect(WarEffects.SLEEP.get());
LivingEntity kek = null;
DamageSource ds = e.getSource();
if (uke.hasEffect(WarEffects.VULNERABLE.get()) && !CombatUtils.isPhysicalAttack(ds))
e.setAmount(e.getAmount() + uke.getEffect(WarEffects.VULNERABLE.get()).getAmplifier() + 1);
if (ds.getDirectEntity() instanceof LivingEntity) {
kek = (LivingEntity) ds.getDirectEntity();
}
uke.getAttribute(Attributes.ARMOR).removeModifier(uuid);
uke.getAttribute(Attributes.ARMOR).removeModifier(uuid2);
if (ds instanceof CombatDamageSource) {
float mult = -((CombatDamageSource) ds).getArmorReductionPercentage();
if (mult != 0) {
AttributeModifier armor = new AttributeModifier(uuid2, "temporary armor multiplier", mult, AttributeModifier.Operation.MULTIPLY_TOTAL);
uke.getAttribute(Attributes.ARMOR).addTransientModifier(armor);
}
}
ItemStack ukemain = uke.getMainHandItem();
ItemStack ukeoff = uke.getOffhandItem();
if (ukemain.getCapability(CombatManipulator.CAP).isPresent()) {
ICombatItemCapability icic = ukemain.getCapability(CombatManipulator.CAP).resolve().get();
e.setAmount(icic.onBeingHurt(e.getSource(), uke, ukemain, e.getAmount()));
}
if (ukeoff.getCapability(CombatManipulator.CAP).isPresent()) {
ICombatItemCapability icic = ukeoff.getCapability(CombatManipulator.CAP).resolve().get();
e.setAmount(icic.onBeingHurt(e.getSource(), uke, ukeoff, e.getAmount()));
}
ICombatCapability cap = CombatData.getCap(uke);
cap.setSpiritGrace(ResourceConfig.spiritCD);
cap.setAdrenalineCooldown(CombatConfig.adrenaline);
SubtleBonusHandler.update = true;
StealthUtils.Awareness awareness = StealthUtils.getAwareness(kek, uke);
if (ds.getEntity() instanceof LivingEntity) {
LivingEntity seme = ((LivingEntity) ds.getEntity());
if (seme.getMainHandItem().getCapability(CombatManipulator.CAP).isPresent()) {
ICombatItemCapability icic = seme.getMainHandItem().getCapability(CombatManipulator.CAP).resolve().get();
e.setAmount(icic.hurtStart(e.getSource(), seme, uke, seme.getMainHandItem(), e.getAmount()) * icic.damageMultiplier(seme, uke, seme.getMainHandItem()));
AttributeModifier armor = new AttributeModifier(uuid, "temporary armor removal", -icic.armorIgnoreAmount(e.getSource(), seme, uke, seme.getMainHandItem(), e.getAmount()), AttributeModifier.Operation.ADDITION);
uke.getAttribute(Attributes.ARMOR).addTransientModifier(armor);
}
if (CombatUtils.isPhysicalAttack(e.getSource())) {
if (awareness != StealthUtils.Awareness.ALERT) {
e.setAmount((float) (e.getAmount() * CombatUtils.getDamageMultiplier(awareness, CombatUtils.getAttackingItemStack(ds))));
}
cap.setMightGrace(0);
}
double luckDiff = WarDance.rand.nextFloat() * (GeneralUtils.getAttributeValueSafe(seme, Attributes.LUCK)) - WarDance.rand.nextFloat() * (GeneralUtils.getAttributeValueSafe(uke, Attributes.LUCK));
e.setAmount(e.getAmount() + (float) luckDiff * GeneralConfig.luck);
}
if (cap.getStaggerTime() > 0 && !cap.isFirstStaggerStrike()) {
e.setAmount(e.getAmount() * CombatConfig.staggerDamage);
// fatality!
if (ds.getEntity() instanceof LivingEntity) {
LivingEntity seme = ((LivingEntity) ds.getEntity());
if (seme.level instanceof ServerWorld) {
((ServerWorld) seme.level).sendParticles(ParticleTypes.ANGRY_VILLAGER, uke.getX(), uke.getY(), uke.getZ(), 5, uke.getBbWidth(), uke.getBbHeight(), uke.getBbWidth(), 0.5f);
}
seme.level.playSound(null, uke.getX(), uke.getY(), uke.getZ(), SoundEvents.GENERIC_BIG_FALL, SoundCategory.PLAYERS, 0.25f + WarDance.rand.nextFloat() * 0.5f, 0.75f + WarDance.rand.nextFloat() * 0.5f);
}
} else {
// unfatality!
e.setAmount(e.getAmount() * CombatConfig.unStaggerDamage);
}
}
use of jackiecrazy.wardance.api.CombatDamageSource in project WarDance by Jackiecrazy.
the class ShieldBash method performEffect.
protected void performEffect(LivingEntity caster, LivingEntity target) {
final ICombatCapability cap = CombatData.getCap(caster);
SkillUtils.auxAttack(caster, target, new CombatDamageSource("player", caster).setProcNormalEffects(false).setProcAttackEffects(true).setProcSkillEffects(true).setAttackingHand(Hand.OFF_HAND).setDamageTyping(CombatDamageSource.TYPE.PHYSICAL).setDamageDealer(caster.getMainHandItem()), 0, cap.consumeBarrier(cap.getBarrier()));
cap.setBarrierCooldown(cap.getBarrierCooldown() / 2);
}
use of jackiecrazy.wardance.api.CombatDamageSource in project WarDance by Jackiecrazy.
the class CombatHandler method parry.
// because compat with BHT...
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void parry(final LivingAttackEvent e) {
if (!e.getEntityLiving().level.isClientSide && e.getSource() != null && CombatUtils.isPhysicalAttack(e.getSource())) {
LivingEntity uke = e.getEntityLiving();
if (MovementUtils.hasInvFrames(uke)) {
e.setCanceled(true);
}
ICombatCapability ukeCap = CombatData.getCap(uke);
ItemStack attack = CombatUtils.getAttackingItemStack(e.getSource());
if (CombatUtils.isMeleeAttack(e.getSource()) && e.getSource().getEntity() instanceof LivingEntity && attack != null && e.getAmount() > 0) {
LivingEntity seme = (LivingEntity) e.getSource().getEntity();
if (StealthConfig.inv)
seme.removeEffect(Effects.INVISIBILITY);
ICombatCapability semeCap = CombatData.getCap(seme);
Hand attackingHand = semeCap.isOffhandAttack() ? Hand.OFF_HAND : Hand.MAIN_HAND;
// hand bound or staggered, no attack
if (semeCap.getStaggerTime() > 0 || semeCap.getHandBind(attackingHand) > 0) {
e.setCanceled(true);
return;
}
boolean sweeping = false;
// capability handler
seme.getMainHandItem().getCapability(CombatManipulator.CAP).ifPresent((i) -> i.attackStart(e.getSource(), seme, uke, seme.getMainHandItem(), e.getAmount()));
// add stats if it's the first attack this tick and cooldown is sufficient
if (semeCap.getSweepTick() != seme.tickCount) {
// first hit of a potential sweep attack
semeCap.addRank(0.1f);
float might = CombatUtils.getAttackMight(seme, uke);
semeCap.addMight(might);
semeCap.setSweepTick(seme.tickCount);
} else {
// hitting twice in a sweep attack, disqualified from parry refund
sweeping = true;
}
// blocking, reset posture cooldown without resetting combo cooldown, bypass parry
if (uke.isBlocking()) {
ukeCap.consumePosture(0);
return;
}
// manual parry toggle
// why does everyone want this feature...
boolean failManualParry = CombatConfig.sneakParry > 0 && (ukeCap.getParryingTick() > uke.tickCount || ukeCap.getParryingTick() < uke.tickCount - CombatConfig.sneakParry);
failManualParry |= CombatConfig.sneakParry < 0 && ukeCap.getParryingTick() == -1;
failManualParry &= uke instanceof PlayerEntity;
boolean canParry = GeneralUtils.isFacingEntity(uke, seme, 120);
boolean useDeflect = (uke instanceof PlayerEntity || WarDance.rand.nextFloat() < CombatConfig.mobDeflectChance) && GeneralUtils.isFacingEntity(uke, seme, 120 + 2 * (int) GeneralUtils.getAttributeValueSafe(uke, WarAttributes.DEFLECTION.get())) && !GeneralUtils.isFacingEntity(uke, seme, 120) && !canParry;
// staggered, no parry
if (ukeCap.getStaggerTime() > 0) {
downingHit = false;
return;
}
// parry code start, grab attack multiplier
float atkMult = CombatUtils.getPostureAtk(seme, seme, attackingHand, e.getAmount(), attack);
// store atkMult at this stage for event
float original = atkMult;
downingHit = true;
// stabby bonus
StealthUtils.Awareness awareness = StealthUtils.getAwareness(seme, uke);
atkMult *= CombatUtils.getDamageMultiplier(awareness, attack);
// crit bonus
if (e.getSource() instanceof CombatDamageSource && ((CombatDamageSource) e.getSource()).isCrit())
atkMult *= ((CombatDamageSource) e.getSource()).getCritDamage();
// grab defending stack
ItemStack defend = null;
Hand parryHand = null;
if (canParry) {
float posMod = 1337;
boolean isShield = false;
if (CombatUtils.canParry(uke, seme, uke.getOffhandItem(), atkMult)) {
defend = uke.getOffhandItem();
posMod = CombatUtils.getPostureDef(seme, uke, uke.getOffhandItem(), e.getAmount());
isShield = CombatUtils.isShield(uke, uke.getOffhandItem());
parryHand = Hand.OFF_HAND;
}
if (!isShield && CombatUtils.canParry(uke, seme, uke.getMainHandItem(), atkMult) && CombatUtils.getPostureDef(seme, uke, uke.getMainHandItem(), e.getAmount()) < posMod) {
defend = uke.getMainHandItem();
parryHand = Hand.MAIN_HAND;
}
}
float defMult = CombatUtils.getPostureDef(seme, uke, defend, e.getAmount());
// special mob parry overrides
if (atkMult >= 0 && awareness != StealthUtils.Awareness.UNAWARE && CombatUtils.parryMap.containsKey(GeneralUtils.getResourceLocationFromEntity(uke))) {
CombatUtils.MobInfo stats = CombatUtils.parryMap.get(GeneralUtils.getResourceLocationFromEntity(uke));
if (WarDance.rand.nextFloat() < stats.chance) {
if (stats.mult < 0) {
// cannot parry
defend = null;
canParry = false;
defMult = (float) -stats.mult;
} else if (stats.omnidirectional || canParry) {
if (defMult > stats.mult) {
if (!canParry) {
parryHand = CombatUtils.getCooledAttackStrength(uke, Hand.MAIN_HAND, 0.5f) > CombatUtils.getCooledAttackStrength(uke, Hand.OFF_HAND, 0.5f) ? Hand.MAIN_HAND : Hand.OFF_HAND;
}
defend = ItemStack.EMPTY;
defMult = (float) Math.min(stats.mult, defMult);
canParry = true;
}
}
}
}
// accounting for negative posture damage, used to mark an item as ignoring parries
float finalPostureConsumption = Math.abs(atkMult * defMult);
// updating this quickly, it's basically the above without crit and stab multipliers, which were necessary for calculating canParry so they couldn't be eliminated cleanly...
float originalPostureConsumption = Math.abs(original * defMult);
ParryEvent pe = new ParryEvent(uke, seme, ((canParry && defend != null) || useDeflect), attackingHand, attack, parryHand, defend, finalPostureConsumption, originalPostureConsumption, e.getAmount());
if (failManualParry)
pe.setResult(Event.Result.DENY);
MinecraftForge.EVENT_BUS.post(pe);
if (pe.isCanceled()) {
e.setCanceled(true);
return;
}
if (ukeCap.getStaggerTime() == 0) {
// overflow posture
float consumption = pe.getPostureConsumption();
/*
barrier reduction if appropriate
this is so ugly oh my god
*/
if (pe.canParry() && !useDeflect && CombatUtils.isShield(uke, defend)) {
consumption -= ukeCap.consumeBarrier(consumption);
}
/*
end ugliness
*/
float knockback = ukeCap.consumePosture(seme, consumption);
// no parries if stabby
if (StealthConfig.ignore && awareness == StealthUtils.Awareness.UNAWARE)
return;
if (pe.canParry()) {
e.setCanceled(true);
downingHit = false;
ukeCap.addRank(0);
if (useDeflect) {
// deflect
uke.level.playSound(null, uke.getX(), uke.getY(), uke.getZ(), SoundEvents.IRON_TRAPDOOR_OPEN, SoundCategory.PLAYERS, 0.75f + WarDance.rand.nextFloat() * 0.5f, (1 - (ukeCap.getPosture() / ukeCap.getMaxPosture())) + WarDance.rand.nextFloat() * 0.5f);
return;
}
// shield disabling
boolean disshield = false;
parryHand = uke.getOffhandItem() == defend ? Hand.OFF_HAND : Hand.MAIN_HAND;
// barrier has already been handled. Subsequent binding and cooldown are handled by the capability.
if (CombatUtils.isShield(uke, defend)) {
Tuple<Integer, Float> stat = CombatUtils.getShieldStats(defend);
if (attack.canDisableShield(defend, uke, seme)) {
// shield is disabled
if (uke instanceof PlayerEntity) {
((PlayerEntity) uke).getCooldowns().addCooldown(defend.getItem(), stat.getA());
} else
ukeCap.setHandBind(parryHand, stat.getA());
disshield = true;
}
}
// knockback based on posture consumed
// this will return negative if the defmult is greater, and positive if the atkmult is greater. Larger abs val=larger difference
double kb = Math.sqrt(atkMult) - 0.18 - (1 / Math.max(defMult, 0.1));
// sigmoid curve again!
// this is the knockback to be applied to the defender
kb = 1d / (1d + Math.exp(-kb));
CombatUtils.knockBack(uke, seme, Math.min(uke instanceof PlayerEntity ? 1.6f : 1.3f, 0.2f + (pe.getPostureConsumption() + knockback) * (float) kb * (uke instanceof PlayerEntity ? 6 : 4) / ukeCap.getMaxPosture()), true, false);
kb = 1 - kb;
CombatUtils.knockBack(seme, uke, Math.min(uke instanceof PlayerEntity ? 1.6f : 1.3f, 0.1f + pe.getPostureConsumption() * (float) kb * (seme instanceof PlayerEntity ? 3 : 2) / semeCap.getMaxPosture()), true, false);
uke.level.playSound(null, uke.getX(), uke.getY(), uke.getZ(), disshield ? SoundEvents.SHIELD_BLOCK : SoundEvents.ANVIL_PLACE, SoundCategory.PLAYERS, 0.25f + WarDance.rand.nextFloat() * 0.5f, (1 - (ukeCap.getPosture() / ukeCap.getMaxPosture())) + WarDance.rand.nextFloat() * 0.5f);
// reset cooldown
if (defMult != 0) {
// shield time
// (posture consumption+1)*5 ticks of cooldown
int ticks = (int) ((consumption + 1) * 5);
// attack cooldown ticks
float cd = CombatUtils.getCooldownPeriod(uke, parryHand);
if (// if attack speed is lower, refund partial cooldown
cd > ticks)
CombatUtils.setHandCooldownDirect(uke, parryHand, ticks, true);
else
// otherwise bind hand
ukeCap.setHandBind(parryHand, (ticks - (int) cd));
}
if (sweeping) {
CombatUtils.setHandCooldown(seme, attackingHand, 0, true);
} else
CombatUtils.setHandCooldown(seme, attackingHand, (float) (1 - kb), true);
// sword on sword is 1.4, sword on shield is 1.12
if (defend != null) {
ItemStack finalDefend = defend;
defend.getCapability(CombatManipulator.CAP).ifPresent((i) -> i.onParry(seme, uke, finalDefend, e.getAmount()));
Hand other = uke.getMainHandItem() == defend ? Hand.OFF_HAND : Hand.MAIN_HAND;
ItemStack finalDefend1 = uke.getItemInHand(other);
finalDefend1.getCapability(CombatManipulator.CAP).ifPresent((i) -> i.onOtherHandParry(seme, uke, finalDefend1, e.getAmount()));
}
}
}
if (!(seme instanceof PlayerEntity)) {
semeCap.setHandBind(attackingHand, CombatUtils.getCooldownPeriod(seme, attackingHand) + 7);
}
}
// shatter, at the rock bottom of the attack event, saving your protected butt.
if (!uke.isBlocking() && !e.isCanceled()) {
if (CombatUtils.isPhysicalAttack(e.getSource()) && StealthUtils.getAwareness(e.getSource().getDirectEntity() instanceof LivingEntity ? (LivingEntity) e.getSource().getDirectEntity() : null, uke) != StealthUtils.Awareness.UNAWARE) {
if (CombatData.getCap(uke).consumeShatter(e.getAmount())) {
e.setCanceled(true);
uke.level.playSound(null, uke.getX(), uke.getY(), uke.getZ(), SoundEvents.GLASS_BREAK, SoundCategory.PLAYERS, 0.25f + WarDance.rand.nextFloat() * 0.5f, 0.75f + WarDance.rand.nextFloat() * 0.5f);
}
// otherwise the rest of the damage goes through and is handled later down the line anyway
}
}
}
}
use of jackiecrazy.wardance.api.CombatDamageSource in project WarDance by Jackiecrazy.
the class CombatHandler method otherKnockbackHooks.
@SubscribeEvent
public static void otherKnockbackHooks(DamageKnockbackEvent e) {
if (e.getDamageSource() instanceof CombatDamageSource) {
CombatDamageSource cds = (CombatDamageSource) e.getDamageSource();
e.setStrength(e.getStrength() * cds.getKnockbackPercentage());
}
}
Aggregations