use of me.deecaad.core.file.Configuration in project MechanicsMain by WeaponMechanics.
the class DamageHandler method tryUseExplosion.
public void tryUseExplosion(WeaponProjectile projectile, Location origin, DoubleMap<LivingEntity> exposures) {
Configuration config = getConfigurations();
String weaponTitle = projectile.getWeaponTitle();
double damage = config.getDouble(weaponTitle + ".Damage.Base_Explosion_Damage");
if (damage == 0) {
// If explosion damage isn't used, use Base_Damage
damage = config.getDouble(weaponTitle + ".Damage.Base_Damage");
}
for (DoubleEntry<LivingEntity> entry : exposures.entrySet()) {
// Value = exposure
LivingEntity victim = entry.getKey();
Location victimLocation = victim.getLocation();
Vector explosionToVictimDirection = victimLocation.toVector().subtract(origin.toVector());
boolean backstab = victimLocation.getDirection().dot(explosionToVictimDirection) > 0.0;
tryUse(victim, projectile, damage * entry.getValue(), null, backstab);
}
}
use of me.deecaad.core.file.Configuration in project MechanicsMain by WeaponMechanics.
the class HitBox method getDamagePoint.
/**
* @param hitLocation the entity hit location
* @param normalizedMotion the normalized direction
* @return the damage point or null if tried to cast when living entity was not defined
*/
private DamagePoint getDamagePoint(Vector hitLocation, Vector normalizedMotion, LivingEntity livingEntity) {
if (livingEntity == null)
return null;
Configuration basicConfiguration = WeaponMechanics.getBasicConfigurations();
EntityType type = livingEntity.getType();
double entityHeight = maxY - minY;
double hitY = hitLocation.getY();
// Check HEAD
double head = basicConfiguration.getDouble("Entity_Hitboxes." + type.name() + "." + DamagePoint.HEAD.name());
if (head > 0.0 && maxY - (entityHeight * head) < hitY) {
return DamagePoint.HEAD;
}
// Check BODY
double body = basicConfiguration.getDouble("Entity_Hitboxes." + type.name() + "." + DamagePoint.BODY.name());
if (body >= 1.0 || body > 0.0 && maxY - (entityHeight * (head + body)) < hitY) {
boolean horizontalEntity = basicConfiguration.getBool("Entity_Hitboxes." + type.name() + ".Horizontal_Entity", false);
boolean arms = basicConfiguration.getBool("Entity_Hitboxes." + type.name() + "." + DamagePoint.ARMS.name(), false);
if (horizontalEntity || arms) {
Vector normalizedEntityDirection = livingEntity.getLocation().getDirection();
if (horizontalEntity && !new HitBox(minX, minY, minZ, maxX, maxY, maxZ).expand(normalizedEntityDirection, FRONT_HIT).collides(hitLocation)) {
// Basically removes directionally 0.2 from this entity hitbox and check if the hit location is still in the hitbox
return DamagePoint.HEAD;
}
if (arms && Math.abs(normalizedMotion.clone().setY(0).dot(normalizedEntityDirection.setY(0))) < 0.5) {
return DamagePoint.ARMS;
}
}
return DamagePoint.BODY;
}
// Check LEGS
double legs = basicConfiguration.getDouble("Entity_Hitboxes." + type.name() + "." + DamagePoint.LEGS.name());
if (legs > 0.0 && maxY - (entityHeight * (head + body + legs)) < hitY) {
return DamagePoint.LEGS;
}
// Check FEET
double feet = basicConfiguration.getDouble("Entity_Hitboxes." + type.name() + "." + DamagePoint.FEET.name());
if (feet > 0.0) {
// No need for actual check since it can't be HEAD, BODY or LEGS anymore so only option left is FEET
return DamagePoint.FEET;
}
debug.log(LogLevel.WARN, "Something unexpected happened and HEAD, BODY, LEGS or FEET wasn't valid", "This should never happen. Using BODY as default value...", "This happened with entity type " + type + ".");
return DamagePoint.BODY;
}
use of me.deecaad.core.file.Configuration in project MechanicsMain by WeaponMechanics.
the class ReloadHandler method startReloadWithoutTriggerAndWithoutTiming.
private boolean startReloadWithoutTriggerAndWithoutTiming(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, EquipmentSlot slot, boolean dualWield, boolean isReloadLoop) {
// Don't try to reload if either one of the hands is already reloading / full autoing
HandData mainHandData = entityWrapper.getMainHandData();
HandData offHandData = entityWrapper.getOffHandData();
if (mainHandData.isReloading() || mainHandData.isUsingFullAuto() || mainHandData.isUsingBurst() || offHandData.isReloading() || offHandData.isUsingFullAuto() || offHandData.isUsingBurst()) {
return false;
}
WeaponPreReloadEvent preReloadEvent = new WeaponPreReloadEvent(weaponTitle, weaponStack, entityWrapper.getEntity());
Bukkit.getPluginManager().callEvent(preReloadEvent);
if (preReloadEvent.isCancelled())
return false;
Configuration config = getConfigurations();
int reloadDuration = config.getInt(weaponTitle + ".Reload.Reload_Duration");
int tempMagazineSize = config.getInt(weaponTitle + ".Reload.Magazine_Size");
if (tempMagazineSize <= 0 || reloadDuration <= 0) {
// This ensures that non intended reloads doesn't occur from ShootHandler for example
return false;
}
int ammoLeft = getAmmoLeft(weaponStack, weaponTitle);
if (ammoLeft == -1) {
// This shouldn't be -1 at this point since reload should be used, perhaps ammo was added for weapon in configs later in server...
CustomTag.AMMO_LEFT.setInteger(weaponStack, 0);
ammoLeft = 0;
}
// On reload force zoom out
entityWrapper.getMainHandData().ifZoomingForceZoomOut();
entityWrapper.getOffHandData().ifZoomingForceZoomOut();
boolean mainhand = slot == EquipmentSlot.HAND;
HandData handData = mainhand ? entityWrapper.getMainHandData() : entityWrapper.getOffHandData();
int ammoPerReload = config.getInt(weaponTitle + ".Reload.Ammo_Per_Reload", -1);
// Check how much ammo should be added during this reload iteration
int tempAmmoToAdd;
if (ammoPerReload != -1) {
tempAmmoToAdd = ammoPerReload;
if (ammoLeft + tempAmmoToAdd > tempMagazineSize) {
tempAmmoToAdd = tempMagazineSize - ammoLeft;
}
} else {
tempAmmoToAdd = tempMagazineSize - ammoLeft;
}
LivingEntity shooter = entityWrapper.getEntity();
WeaponInfoDisplay weaponInfoDisplay = shooter.getType() != EntityType.PLAYER ? null : getConfigurations().getObject(weaponTitle + ".Info.Weapon_Info_Display", WeaponInfoDisplay.class);
PlayerWrapper playerWrapper = weaponInfoDisplay == null ? null : (PlayerWrapper) entityWrapper;
FirearmAction firearmAction = config.getObject(weaponTitle + ".Firearm_Action", FirearmAction.class);
FirearmState state = null;
boolean isRevolver = false;
boolean isPump = false;
int firearmOpenTime = 0;
int firearmCloseTime = 0;
if (firearmAction != null) {
state = firearmAction.getState(weaponStack);
isRevolver = firearmAction.getFirearmType() == FirearmType.REVOLVER;
isPump = firearmAction.getFirearmType() == FirearmType.PUMP;
// Is revolver or ammo is 0
if (!isReloadLoop && (isRevolver || ammoLeft <= 0)) {
firearmOpenTime = firearmAction.getOpenTime();
firearmCloseTime = firearmAction.getCloseTime();
switch(state) {
case OPEN:
if (isPump)
reloadDuration = 0;
break;
case CLOSE:
firearmOpenTime = 0;
reloadDuration = 0;
break;
default:
break;
}
}
}
WeaponReloadEvent reloadEvent = new WeaponReloadEvent(weaponTitle, weaponStack, entityWrapper.getEntity(), reloadDuration, tempAmmoToAdd, tempMagazineSize, firearmOpenTime, firearmCloseTime);
Bukkit.getPluginManager().callEvent(reloadEvent);
reloadDuration = reloadEvent.getReloadTime();
tempAmmoToAdd = reloadEvent.getReloadAmount();
tempMagazineSize = reloadEvent.getMagazineSize();
firearmOpenTime = reloadEvent.getFirearmOpenTime();
firearmCloseTime = reloadEvent.getFirearmCloseTime();
final int finalAmmoToAdd = tempAmmoToAdd;
final int magazineSize = tempMagazineSize;
if (ammoLeft >= magazineSize || reloadDuration == 0) {
if (state != null && state != FirearmState.READY) {
if (!isPump) {
// Since with pump we want to first OPEN and then CLOSE
if (state != FirearmState.CLOSE)
firearmAction.changeState(weaponStack, FirearmState.CLOSE);
}
// Simply CLOSE weapon or OPEN CLOSE if pump
weaponHandler.getShootHandler().doShootFirearmActions(entityWrapper, weaponTitle, weaponStack, handData, slot);
// Here true because firearm actions started
return true;
}
return false;
}
AmmoTypes ammoTypes = playerWrapper != null ? config.getObject(weaponTitle + ".Reload.Ammo.Ammo_Types", AmmoTypes.class) : null;
if (ammoTypes != null && !ammoTypes.hasAmmo(weaponTitle, weaponStack, playerWrapper)) {
Mechanics outOfAmmoMechanics = getConfigurations().getObject(weaponTitle + ".Reload.Ammo.Out_Of_Ammo", Mechanics.class);
if (outOfAmmoMechanics != null)
outOfAmmoMechanics.use(new CastData(entityWrapper, weaponTitle, weaponStack));
return false;
}
boolean unloadAmmoOnReload = config.getBool(weaponTitle + ".Reload.Unload_Ammo_On_Reload");
// This is necessary for events to be used correctly
handData.setReloadData(weaponTitle, weaponStack);
ChainTask reloadTask = new ChainTask(reloadDuration) {
private int unloadedAmount;
@Override
public void task() {
ItemStack taskReference = mainhand ? entityWrapper.getEntity().getEquipment().getItemInMainHand() : entityWrapper.getEntity().getEquipment().getItemInOffHand();
if (taskReference == weaponStack) {
taskReference = weaponStack;
} else {
handData.setReloadData(weaponTitle, taskReference);
}
int ammoLeft = getAmmoLeft(taskReference, weaponTitle);
// Here creating this again since this may change if there isn't enough ammo...
int ammoToAdd = finalAmmoToAdd + unloadedAmount;
if (ammoTypes != null) {
int removedAmount = ammoTypes.removeAmmo(taskReference, playerWrapper, ammoToAdd, magazineSize);
// Just check if for some reason ammo disappeared from entity before reaching reload "complete" state
if (removedAmount <= 0) {
Mechanics outOfAmmoMechanics = getConfigurations().getObject(weaponTitle + ".Reload.Ammo.Out_Of_Ammo", Mechanics.class);
if (outOfAmmoMechanics != null)
outOfAmmoMechanics.use(new CastData(entityWrapper, weaponTitle, taskReference));
// Remove next task as reload can't be finished
setNextTask(null);
handData.stopReloadingTasks();
return;
}
// Else simply set ammo to add value to removed amount
// Removed amount will be less than ammo to add amount IF player didn't have that much ammo
ammoToAdd = removedAmount;
}
int finalAmmoSet = ammoLeft + ammoToAdd;
handleWeaponStackAmount(entityWrapper, taskReference);
CustomTag.AMMO_LEFT.setInteger(taskReference, finalAmmoSet);
finishReload(entityWrapper, weaponTitle, taskReference, handData, slot);
if (ammoPerReload != -1) {
// Start the loop
startReloadWithoutTrigger(entityWrapper, weaponTitle, taskReference, slot, dualWield, true);
}
}
@Override
public void setup() {
handData.addReloadTask(getTaskId());
int ammoLeft = CustomTag.AMMO_LEFT.getInteger(weaponStack);
if (unloadAmmoOnReload && ammoLeft > 0) {
if (ammoTypes != null)
ammoTypes.giveAmmo(weaponStack, playerWrapper, ammoLeft, magazineSize);
unloadedAmount = ammoLeft;
handleWeaponStackAmount(entityWrapper, weaponStack);
CustomTag.AMMO_LEFT.setInteger(weaponStack, 0);
}
CastData castData = new CastData(entityWrapper, weaponTitle, weaponStack);
// Set the extra data so SoundMechanic knows to save task id to hand's reload tasks
castData.setData(ReloadSound.getDataKeyword(), mainhand ? ReloadSound.MAIN_HAND.getId() : ReloadSound.OFF_HAND.getId());
Mechanics reloadStartMechanics = config.getObject(weaponTitle + ".Reload.Start_Mechanics", Mechanics.class);
if (reloadStartMechanics != null)
reloadStartMechanics.use(castData);
weaponInfoDisplay.send(playerWrapper, slot);
weaponHandler.getSkinHandler().tryUse(entityWrapper, weaponTitle, weaponStack, slot);
}
};
if (getConfigurations().getBool(weaponTitle + ".Info.Show_Cooldown.Reload_Time") && entityWrapper.getEntity().getType() == EntityType.PLAYER) {
CompatibilityAPI.getEntityCompatibility().setCooldown((Player) entityWrapper.getEntity(), weaponStack.getType(), reloadEvent.getReloadCompleteTime());
}
// OR ammo left is above 0 and revolver isn't used (when using revolver firearm actions should always occur)
if (isReloadLoop || state == null || (ammoLeft > 0 && !isRevolver)) {
reloadTask.startChain();
return true;
}
ChainTask closeTask = getCloseTask(firearmCloseTime, firearmAction, weaponStack, handData, entityWrapper, weaponTitle, mainhand, slot);
if (state == FirearmState.CLOSE) {
closeTask.startChain();
return true;
}
ChainTask openTask = getOpenTask(firearmOpenTime, firearmAction, weaponStack, handData, entityWrapper, weaponTitle, mainhand, slot);
if (isPump) {
firearmAction.changeState(weaponStack, FirearmState.OPEN);
if (ammoPerReload != -1) {
reloadTask.startChain();
} else {
reloadTask.setNextTask(openTask).setNextTask(closeTask);
reloadTask.startChain();
}
} else {
if (ammoPerReload != -1) {
openTask.setNextTask(reloadTask);
openTask.startChain();
} else {
openTask.setNextTask(reloadTask).setNextTask(closeTask);
openTask.startChain();
}
}
return true;
}
use of me.deecaad.core.file.Configuration in project MechanicsMain by WeaponMechanics.
the class ShootHandler method fullAutoShot.
private boolean fullAutoShot(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, HandData handData, EquipmentSlot slot, TriggerType triggerType, boolean dualWield) {
Configuration config = getConfigurations();
int fullyAutomaticShotsPerSecond = config.getInt(weaponTitle + ".Shoot.Fully_Automatic_Shots_Per_Second");
// Not used
if (fullyAutomaticShotsPerSecond == 0)
return false;
int baseAmountPerTick = fullyAutomaticShotsPerSecond / 20;
int extra = fullyAutomaticShotsPerSecond % 20;
boolean mainhand = slot == EquipmentSlot.HAND;
boolean consumeItemOnShoot = getConfigurations().getBool(weaponTitle + ".Shoot.Consume_Item_On_Shoot");
ReloadHandler reloadHandler = weaponHandler.getReloadHandler();
handData.setFullAutoTask(new BukkitRunnable() {
int tick = 0;
public void run() {
ItemStack taskReference = mainhand ? entityWrapper.getEntity().getEquipment().getItemInMainHand() : entityWrapper.getEntity().getEquipment().getItemInOffHand();
if (taskReference == weaponStack)
taskReference = weaponStack;
if (entityWrapper.getMainHandData().isReloading() || entityWrapper.getOffHandData().isReloading()) {
handData.setFullAutoTask(0);
cancel();
return;
}
int ammoLeft = reloadHandler.getAmmoLeft(taskReference, weaponTitle);
if (!keepFullAutoOn(entityWrapper, triggerType)) {
handData.setFullAutoTask(0);
cancel();
if (ammoLeft == 0) {
reloadHandler.startReloadWithoutTrigger(entityWrapper, weaponTitle, taskReference, slot, dualWield, false);
} else {
doShootFirearmActions(entityWrapper, weaponTitle, taskReference, handData, slot);
}
return;
}
int shootAmount;
if (extra != 0) {
shootAmount = (baseAmountPerTick + AUTO[extra - 1][tick]);
} else {
shootAmount = baseAmountPerTick;
}
if (ammoLeft != -1) {
// Check whether shoot amount of this tick should be changed
if (ammoLeft - shootAmount < 0) {
shootAmount = ammoLeft;
}
if (!reloadHandler.consumeAmmo(taskReference, weaponTitle, shootAmount)) {
handData.setFullAutoTask(0);
cancel();
reloadHandler.startReloadWithoutTrigger(entityWrapper, weaponTitle, taskReference, slot, dualWield, false);
return;
}
}
if (shootAmount == 1) {
shoot(entityWrapper, weaponTitle, taskReference, getShootLocation(entityWrapper.getEntity(), dualWield, mainhand), mainhand, true, false);
if (consumeItemOnShoot && handleConsumeItemOnShoot(taskReference)) {
handData.setFullAutoTask(0);
cancel();
return;
}
} else if (shootAmount > 1) {
// Don't try to shoot in this tick if shoot amount is 0
for (int i = 0; i < shootAmount; ++i) {
shoot(entityWrapper, weaponTitle, taskReference, getShootLocation(entityWrapper.getEntity(), dualWield, mainhand), mainhand, true, false);
if (consumeItemOnShoot && handleConsumeItemOnShoot(taskReference)) {
handData.setFullAutoTask(0);
cancel();
return;
}
}
}
if (++tick >= 20) {
tick = 0;
}
}
}.runTaskTimer(WeaponMechanics.getPlugin(), 0, 0).getTaskId());
return true;
}
use of me.deecaad.core.file.Configuration in project MechanicsMain by WeaponMechanics.
the class ShootHandler method shootWithoutTrigger.
/**
* @return true if was able to shoot
*/
public boolean shootWithoutTrigger(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, EquipmentSlot slot, TriggerType triggerType, boolean dualWield) {
HandData handData = slot == EquipmentSlot.HAND ? entityWrapper.getMainHandData() : entityWrapper.getOffHandData();
// Don't even try if slot is already being used for full auto or burst
if (handData.isUsingFullAuto() || handData.isUsingBurst())
return false;
Configuration config = getConfigurations();
WeaponPreShootEvent preShootEvent = new WeaponPreShootEvent(weaponTitle, weaponStack, entityWrapper.getEntity());
Bukkit.getPluginManager().callEvent(preShootEvent);
if (preShootEvent.isCancelled())
return false;
// Cancel shooting if we can only shoot while scoped.
if (config.getBool(weaponTitle + ".Shoot.Only_Shoot_While_Scoped") && !handData.getZoomData().isZooming())
return false;
boolean isMelee = triggerType == TriggerType.MELEE;
// Handle worldguard flags
WorldGuardCompatibility worldGuard = CompatibilityAPI.getWorldGuardCompatibility();
Location loc = entityWrapper.getEntity().getLocation();
if (!worldGuard.testFlag(loc, entityWrapper instanceof PlayerWrapper ? ((PlayerWrapper) entityWrapper).getPlayer() : null, "weapon-shoot")) {
Object obj = worldGuard.getValue(loc, "weapon-shoot-message");
if (obj != null && !obj.toString().isEmpty()) {
entityWrapper.getEntity().sendMessage(StringUtil.color(obj.toString()));
}
return false;
}
ReloadHandler reloadHandler = weaponHandler.getReloadHandler();
if (!getConfigurations().getBool(weaponTitle + ".Shoot.Consume_Item_On_Shoot")) {
reloadHandler.handleWeaponStackAmount(entityWrapper, weaponStack);
}
int ammoLeft = reloadHandler.getAmmoLeft(weaponStack, weaponTitle);
// Check if other hand is reloading and deny shooting if it is
if (slot == EquipmentSlot.HAND) {
if (entityWrapper.getOffHandData().isReloading()) {
return false;
}
} else if (entityWrapper.getMainHandData().isReloading()) {
return false;
}
// FIREARM START
FirearmAction firearmAction = config.getObject(weaponTitle + ".Firearm_Action", FirearmAction.class);
if (firearmAction != null) {
FirearmState state = firearmAction.getState(weaponStack);
if (state != FirearmState.READY) {
if (ammoLeft > 0) {
// Since weapon still has ammo, only CLOSE weapon and let it shoot AFTER that
// Cancel reload if its running
handData.stopReloadingTasks();
// Call shoot firearm actions, so they can complete firearm actions
doShootFirearmActions(entityWrapper, weaponTitle, weaponStack, handData, slot);
} else {
// Else continue to reload from where it left on...
reloadHandler.startReloadWithoutTrigger(entityWrapper, weaponTitle, weaponStack, slot, dualWield, false);
}
// Return false since firearm state wasn't ready, and they need to be completed
return false;
}
}
// If no ammo left, start reloading
if (ammoLeft == 0) {
reloadHandler.startReloadWithoutTrigger(entityWrapper, weaponTitle, weaponStack, slot, dualWield, false);
return false;
} else if (handData.isReloading()) {
// Else if reloading, cancel it
handData.stopReloadingTasks();
}
// RELOAD END
boolean usesSelectiveFire = config.getObject(weaponTitle + ".Shoot.Selective_Fire.Trigger", Trigger.class) != null;
boolean isSelectiveFireAuto = false;
int selectiveFire = 0;
if (usesSelectiveFire) {
selectiveFire = CustomTag.SELECTIVE_FIRE.getInteger(weaponStack);
if (CustomTag.SELECTIVE_FIRE.hasInteger(weaponStack) && selectiveFire == SelectiveFireState.AUTO.getId()) {
isSelectiveFireAuto = true;
}
}
// Only check if selective fire doesn't have auto selected and it isn't melee
if (!isSelectiveFireAuto && !isMelee) {
int delayBetweenShots = config.getInt(weaponTitle + ".Shoot.Delay_Between_Shots");
if (delayBetweenShots != 0 && !NumberUtil.hasMillisPassed(handData.getLastShotTime(), delayBetweenShots))
return false;
}
int weaponEquipDelay = config.getInt(weaponTitle + ".Info.Weapon_Equip_Delay");
if (weaponEquipDelay != 0 && !NumberUtil.hasMillisPassed(handData.getLastEquipTime(), weaponEquipDelay))
return false;
int shootDelayAfterScope = config.getInt(weaponTitle + ".Scope.Shoot_Delay_After_Scope");
if (shootDelayAfterScope != 0 && !NumberUtil.hasMillisPassed(handData.getLastScopeTime(), shootDelayAfterScope))
return false;
if (isMelee) {
return singleShot(entityWrapper, weaponTitle, weaponStack, handData, slot, dualWield, isMelee);
}
if (usesSelectiveFire) {
switch(selectiveFire) {
case // 1 = burst, can't use SelectiveFireState.BURST.getId() here
(1):
return burstShot(entityWrapper, weaponTitle, weaponStack, handData, slot, dualWield);
case // 2 = auto, can't use SelectiveFireState.AUTO.getId() here
(2):
return fullAutoShot(entityWrapper, weaponTitle, weaponStack, handData, slot, triggerType, dualWield);
default:
return singleShot(entityWrapper, weaponTitle, weaponStack, handData, slot, dualWield, isMelee);
}
}
// First try full auto, then burst then single fire
return fullAutoShot(entityWrapper, weaponTitle, weaponStack, handData, slot, triggerType, dualWield) || burstShot(entityWrapper, weaponTitle, weaponStack, handData, slot, dualWield) || singleShot(entityWrapper, weaponTitle, weaponStack, handData, slot, dualWield, isMelee);
}
Aggregations