use of me.deecaad.weaponmechanics.weapon.firearm.FirearmState in project MechanicsMain by WeaponMechanics.
the class PFirearmState method onRequest.
@Nullable
@Override
public String onRequest(@Nullable Player player, @Nullable ItemStack itemStack, @Nullable String weaponTitle, @Nullable EquipmentSlot slot) {
if (itemStack == null || weaponTitle == null)
return null;
FirearmAction firearmAction = getConfigurations().getObject(weaponTitle + ".Firearm_Action", FirearmAction.class);
if (firearmAction == null)
return null;
FirearmState state = firearmAction.getState(itemStack);
switch(state) {
case OPEN:
return getBasicConfigurations().getString("Placeholder_Symbols." + firearmAction.getFirearmType().name() + ".Open", " □");
case CLOSE:
return getBasicConfigurations().getString("Placeholder_Symbols." + firearmAction.getFirearmType().name() + ".Close", " ■");
default:
return "";
}
}
use of me.deecaad.weaponmechanics.weapon.firearm.FirearmState 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.weaponmechanics.weapon.firearm.FirearmState 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);
}
use of me.deecaad.weaponmechanics.weapon.firearm.FirearmState in project MechanicsMain by WeaponMechanics.
the class ShootHandler method doShootFirearmActions.
public void doShootFirearmActions(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, HandData handData, EquipmentSlot slot) {
FirearmAction firearmAction = getConfigurations().getObject(weaponTitle + ".Firearm_Action", FirearmAction.class);
if (firearmAction == null || handData.hasRunningFirearmAction())
return;
FirearmState state = firearmAction.getState(weaponStack);
// If state is ready, check if this shot should not cause firearm actions
if (state == FirearmState.READY && (weaponHandler.getReloadHandler().getAmmoLeft(weaponStack, weaponTitle) % firearmAction.getFirearmActionFrequency() != 0 || !firearmAction.getFirearmType().hasShootActions())) {
return;
}
boolean mainhand = slot == EquipmentSlot.HAND;
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;
// Initiate CLOSE task
BukkitRunnable closeRunnable = new BukkitRunnable() {
@Override
public void run() {
ItemStack taskReference = mainhand ? entityWrapper.getEntity().getEquipment().getItemInMainHand() : entityWrapper.getEntity().getEquipment().getItemInOffHand();
if (taskReference == weaponStack) {
taskReference = weaponStack;
}
firearmAction.changeState(taskReference, FirearmState.READY);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send(playerWrapper, slot);
handData.stopFirearmActionTasks();
}
};
// Init cast data
CastData castData = new CastData(entityWrapper, weaponTitle, weaponStack);
castData.setData(FirearmSound.getDataKeyword(), mainhand ? FirearmSound.MAIN_HAND.getId() : FirearmSound.OFF_HAND.getId());
// Check if OPEN state was already completed
if (state == FirearmState.CLOSE) {
// Only do CLOSE state
// Set the extra data so SoundMechanic knows to save task id to hand's firearm action tasks
firearmAction.useMechanics(castData, false);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send(playerWrapper, slot);
if (getConfigurations().getBool(weaponTitle + ".Info.Show_Cooldown.Firearm_Actions_Time") && playerWrapper != null) {
CompatibilityAPI.getEntityCompatibility().setCooldown(playerWrapper.getPlayer(), weaponStack.getType(), firearmAction.getCloseTime());
}
handData.addFirearmActionTask(closeRunnable.runTaskLater(WeaponMechanics.getPlugin(), firearmAction.getCloseTime()).getTaskId());
// Return since we only want to do close state
return;
}
// Update state
if (state != FirearmState.OPEN)
firearmAction.changeState(weaponStack, FirearmState.OPEN);
// Set the extra data so SoundMechanic knows to save task id to hand's firearm action tasks
firearmAction.useMechanics(castData, true);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send(playerWrapper, slot);
if (getConfigurations().getBool(weaponTitle + ".Info.Show_Cooldown.Firearm_Actions_Time") && playerWrapper != null) {
CompatibilityAPI.getEntityCompatibility().setCooldown(playerWrapper.getPlayer(), weaponStack.getType(), firearmAction.getOpenTime() + firearmAction.getCloseTime());
}
// Add the task to shoot firearm action tasks
handData.addFirearmActionTask(new BukkitRunnable() {
@Override
public void run() {
ItemStack taskReference = mainhand ? entityWrapper.getEntity().getEquipment().getItemInMainHand() : entityWrapper.getEntity().getEquipment().getItemInOffHand();
if (taskReference == weaponStack)
taskReference = weaponStack;
firearmAction.changeState(taskReference, FirearmState.CLOSE);
// Set the extra data so SoundMechanic knows to save task id to hand's firearm action tasks
CastData castData = new CastData(entityWrapper, weaponTitle, taskReference);
castData.setData(FirearmSound.getDataKeyword(), mainhand ? FirearmSound.MAIN_HAND.getId() : FirearmSound.OFF_HAND.getId());
firearmAction.useMechanics(castData, false);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send(playerWrapper, slot);
handData.addFirearmActionTask(closeRunnable.runTaskLater(WeaponMechanics.getPlugin(), firearmAction.getCloseTime()).getTaskId());
}
}.runTaskLater(WeaponMechanics.getPlugin(), firearmAction.getOpenTime()).getTaskId());
}
Aggregations