use of me.deecaad.weaponmechanics.mechanics.CastData in project MechanicsMain by WeaponMechanics.
the class InfoHandler method giveOrDropWeapon.
/**
* If weapon title is invalid, its silently ignored.
* All general weapon get actions are used.
*
* @param weaponTitle the weapon to give
* @param player the player for who to give
* @param amount the amount of weapons to give
*/
public void giveOrDropWeapon(String weaponTitle, Player player, int amount) {
ItemStack weaponStack = getConfigurations().getObject(weaponTitle + ".Info.Weapon_Item", ItemStack.class);
if (weaponStack == null)
return;
weaponStack = weaponStack.clone();
weaponStack.setAmount(amount);
ItemMeta weaponMeta = weaponStack.getItemMeta();
weaponMeta.setDisplayName(PlaceholderAPI.applyPlaceholders(weaponMeta.getDisplayName(), player, weaponStack, weaponTitle, null));
weaponMeta.setLore(PlaceholderAPI.applyPlaceholders(weaponMeta.getLore(), player, weaponStack, weaponTitle, null));
weaponStack.setItemMeta(weaponMeta);
// Apply default skin
Map skins = getConfigurations().getObject(weaponTitle + ".Skin", Map.class);
Skin defaultSkin = (Skin) (skins == null ? null : skins.get("Default"));
if (defaultSkin != null) {
defaultSkin.apply(weaponStack);
}
Inventory inventory = player.getInventory();
// Check if inventory doesn't have any free slots
if (inventory.firstEmpty() == -1) {
player.getWorld().dropItemNaturally(player.getLocation().add(0.0, 1.0, 0.0), weaponStack);
return;
}
inventory.addItem(weaponStack);
Mechanics.use(weaponTitle + ".Info.Weapon_Get_Mechanics", new CastData(WeaponMechanics.getEntityWrapper(player), weaponTitle, weaponStack));
}
use of me.deecaad.weaponmechanics.mechanics.CastData in project MechanicsMain by WeaponMechanics.
the class ShootHandler method shoot.
/**
* Shoots using weapon.
* Does not use ammo nor check for it.
* Does not apply recoil nor anything that would require EntityWrapper.
*/
public void shoot(LivingEntity livingEntity, String weaponTitle, Vector normalizedDirection) {
Configuration config = getConfigurations();
Mechanics shootMechanics = config.getObject(weaponTitle + ".Shoot.Mechanics", Mechanics.class);
if (shootMechanics != null)
shootMechanics.use(new CastData(livingEntity, weaponTitle, null));
Projectile projectile = config.getObject(weaponTitle + ".Projectile", Projectile.class);
if (projectile == null)
return;
Location shootLocation = getShootLocation(livingEntity, false, true);
double projectileSpeed = config.getDouble(weaponTitle + ".Shoot.Projectile_Speed");
for (int i = 0; i < config.getInt(weaponTitle + ".Shoot.Projectiles_Per_Shot"); ++i) {
// Only create bullet first if WeaponShootEvent changes
WeaponProjectile bullet = projectile.create(livingEntity, shootLocation, normalizedDirection.clone().multiply(projectileSpeed), null, weaponTitle);
WeaponShootEvent shootEvent = new WeaponShootEvent(bullet);
Bukkit.getPluginManager().callEvent(shootEvent);
bullet = shootEvent.getProjectile();
// Shoot the given bullet
projectile.shoot(bullet, shootLocation);
}
}
use of me.deecaad.weaponmechanics.mechanics.CastData in project MechanicsMain by WeaponMechanics.
the class ClusterBomb method trigger.
public void trigger(WeaponProjectile projectile, LivingEntity shooter, Location splitLocation) {
int currentDepth = projectile.getIntTag("cluster-split-level");
// Checking to see if we have split the proper number of times
if (currentDepth >= splits) {
return;
}
debug.debug("Splitting cluster bomb");
if (mechanics != null)
mechanics.use(new CastData(shooter, projectile.getWeaponTitle(), projectile.getWeaponStack()));
for (int i = 0; i < bombs; i++) {
Vector vector = VectorUtil.random(speed);
vector.setY(Math.abs(vector.getY()));
// Either use the projectile settings from the "parent" projectile,
// or use the projectile settings for this cluster bomb
Projectile projectileHandler = getProjectile() != null ? getProjectile() : getConfigurations().getObject(projectile.getWeaponTitle() + ".Projectile", Projectile.class);
if (projectileHandler != null) {
WeaponProjectile newProjectile = getProjectile() != null ? projectileHandler.create(shooter, splitLocation, vector, projectile.getWeaponStack(), projectile.getWeaponTitle()) : projectile.clone(splitLocation, vector);
newProjectile.setIntTag("cluster-split-level", currentDepth + 1);
projectileHandler.shoot(newProjectile, splitLocation);
}
}
// Remove the parent split
projectile.remove();
}
use of me.deecaad.weaponmechanics.mechanics.CastData in project MechanicsMain by WeaponMechanics.
the class Explosion method explode.
public void explode(LivingEntity cause, Location origin, WeaponProjectile projectile) {
// Handle worldguard flags
WorldGuardCompatibility worldGuard = CompatibilityAPI.getWorldGuardCompatibility();
EntityWrapper entityWrapper = WeaponMechanics.getEntityWrapper(cause);
if (!worldGuard.testFlag(origin, entityWrapper instanceof PlayerWrapper ? ((PlayerWrapper) entityWrapper).getPlayer() : null, "weapon-explode")) {
Object obj = worldGuard.getValue(origin, "weapon-explode-message");
if (obj != null && !obj.toString().isEmpty()) {
entityWrapper.getEntity().sendMessage(StringUtil.color(obj.toString()));
}
return;
}
// triggered instead of the explosion.
if (projectile != null && airStrike != null && projectile.getIntTag("airstrike-bomb") == 0) {
airStrike.trigger(origin, cause, projectile);
return;
}
List<Block> blocks;
BlockRegenSorter sorter;
DoubleMap<LivingEntity> entities;
if (projectile != null) {
// This event is not cancellable. If developers want to cancel
// explosions, they should use ProjectilePreExplodeEvent
ProjectileExplodeEvent event = new ProjectileExplodeEvent(projectile, shape.getBlocks(origin), new LayerDistanceSorter(origin, this), exposure.mapExposures(origin, shape));
Bukkit.getPluginManager().callEvent(event);
blocks = event.getBlocks();
sorter = event.getSorter();
entities = event.getEntities();
} else {
blocks = shape.getBlocks(origin);
sorter = new LayerDistanceSorter(origin, this);
entities = exposure.mapExposures(origin, shape);
}
int initialCapacity = Math.max(blocks.size(), 10);
List<Block> transparent = new ArrayList<>(initialCapacity);
List<Block> solid = new ArrayList<>(initialCapacity);
// redstone contraptions.
for (Block block : blocks) {
if (block.getType().isSolid()) {
solid.add(block);
} else if (!block.isEmpty()) {
transparent.add(block);
}
}
// regenerate in a random order.
try {
if (sorter == null) {
debug.debug("Null sorter used while regenerating explosion... Was this intentional?");
} else {
solid.sort(sorter);
}
} catch (IllegalArgumentException e) {
debug.log(LogLevel.ERROR, "A plugin modified the explosion block sorter with an illegal sorter! " + "Please report this error to the developers of that plugin. Sorter: " + sorter.getClass(), e);
}
// spawn falling blocks. We also don't need to worry about regeneration.
if (blockDamage != null) {
int timeOffset = regeneration == null ? -1 : (solid.size() * regeneration.getInterval() / regeneration.getMaxBlocksPerUpdate());
damageBlocks(transparent, true, origin, timeOffset);
damageBlocks(solid, false, origin, 0);
}
if (projectile != null && projectile.getWeaponTitle() != null) {
WeaponMechanics.getWeaponHandler().getDamageHandler().tryUseExplosion(projectile, origin, entities);
// higher your exposure, the greater the knockback.
if (isKnockback) {
Vector originVector = origin.toVector();
for (DoubleEntry<LivingEntity> entry : entities.entrySet()) {
LivingEntity entity = entry.getKey();
double exposure = entry.getValue();
// Normalized vector between the explosion and entity involved
Vector between = VectorUtil.setLength(entity.getLocation().toVector().subtract(originVector), exposure);
Vector motion = entity.getVelocity().add(between);
entity.setVelocity(motion);
}
}
if (cluster != null)
cluster.trigger(projectile, cause, origin);
} else {
// size explosion they may want
for (DoubleEntry<LivingEntity> entry : entities.entrySet()) {
LivingEntity entity = entry.getKey();
double impact = entry.getValue();
entity.sendMessage(StringUtil.color("&cYou suffered " + impact * 100 + "% of the impact"));
}
}
if (flashbang != null)
flashbang.trigger(exposure, projectile, origin);
if (mechanics != null)
mechanics.use(new CastData(entityWrapper, origin, projectile == null ? null : projectile.getWeaponTitle(), projectile == null ? null : projectile.getWeaponStack()));
}
use of me.deecaad.weaponmechanics.mechanics.CastData in project MechanicsMain by WeaponMechanics.
the class WeaponHandler method tryUses.
/**
* Tries all uses in this exact order
* <pre>{@code
* 1) Shoot
* 2) Reload
* 3) Scope
* 4) Selective fire
* 5) Ammo type switch
* }</pre>
*
* @param entityWrapper the entity which caused trigger
* @param weaponTitle the weapon title involved
* @param weaponStack the weapon stack involved
* @param slot the weapon slot used
* @param triggerType the trigger which caused this
* @param dualWield whether or not this was dual wield
*/
public void tryUses(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, EquipmentSlot slot, TriggerType triggerType, boolean dualWield, @Nullable LivingEntity victim) {
if (!weaponStack.hasItemMeta())
return;
// Try shooting (and melee)
if (shootHandler.tryUse(entityWrapper, weaponTitle, weaponStack, slot, triggerType, dualWield, victim)) {
if (triggerType.isSprintType())
getSkinHandler().tryUse(triggerType, entityWrapper, weaponTitle, weaponStack, slot);
return;
}
// Shooting wasn't valid, try reloading
if (reloadHandler.tryUse(entityWrapper, weaponTitle, weaponStack, slot, triggerType, dualWield)) {
if (triggerType.isSprintType())
getSkinHandler().tryUse(triggerType, entityWrapper, weaponTitle, weaponStack, slot);
return;
}
// Reloading wasn't valid, try scoping
if (scopeHandler.tryUse(entityWrapper, weaponTitle, weaponStack, slot, triggerType, dualWield)) {
if (triggerType.isSprintType())
getSkinHandler().tryUse(triggerType, entityWrapper, weaponTitle, weaponStack, slot);
return;
}
if (triggerType.isSprintType())
getSkinHandler().tryUse(triggerType, entityWrapper, weaponTitle, weaponStack, slot);
// Scoping wasn't valid, try selective fire
Configuration config = getConfigurations();
Trigger selectiveFireTrigger = config.getObject(weaponTitle + ".Shoot.Selective_Fire.Trigger", Trigger.class);
if (selectiveFireTrigger != null && selectiveFireTrigger.check(triggerType, slot, entityWrapper)) {
boolean hasBurst = config.getInt(weaponTitle + ".Shoot.Burst.Shots_Per_Burst") != 0 && config.getInt(weaponTitle + ".Shoot.Burst.Ticks_Between_Each_Shot") != 0;
boolean hasAuto = config.getInt(weaponTitle + ".Shoot.Fully_Automatic_Shots_Per_Second") != 0;
// 3) Auto
if (!CustomTag.SELECTIVE_FIRE.hasInteger(weaponStack)) {
if (hasBurst) {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, BURST.getId());
} else if (hasAuto) {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, AUTO.getId());
}
} else {
int currentSelectiveFire = CustomTag.SELECTIVE_FIRE.getInteger(weaponStack);
switch(currentSelectiveFire) {
case // 1 = burst, can't use SelectiveFireState.BURST.getId() here
(1):
if (hasAuto) {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, AUTO.getId());
} else {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, SINGLE.getId());
}
break;
case // 2 = auto, can't use SelectiveFireState.AUTO.getId() here
(2):
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, SINGLE.getId());
break;
default:
if (hasBurst) {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, BURST.getId());
} else if (hasAuto) {
CustomTag.SELECTIVE_FIRE.setInteger(weaponStack, AUTO.getId());
}
break;
}
}
Mechanics selectiveFireMechanics = config.getObject(weaponTitle + ".Shoot.Selective_Fire.Mechanics", Mechanics.class);
if (selectiveFireMechanics != null)
selectiveFireMechanics.use(new CastData(entityWrapper, weaponTitle, weaponStack));
WeaponInfoDisplay weaponInfoDisplay = getConfigurations().getObject(weaponTitle + ".Info.Weapon_Info_Display", WeaponInfoDisplay.class);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send((PlayerWrapper) entityWrapper, slot);
entityWrapper.getMainHandData().cancelTasks();
entityWrapper.getOffHandData().cancelTasks();
return;
}
// Selective fire wasn't valid, try ammo type switch
Trigger ammoTypeSwitchTrigger = config.getObject(weaponTitle + ".Reload.Ammo.Ammo_Type_Switch.Trigger", Trigger.class);
if (ammoTypeSwitchTrigger != null && entityWrapper instanceof PlayerWrapper && ammoTypeSwitchTrigger.check(triggerType, slot, entityWrapper)) {
AmmoTypes ammoTypes = config.getObject(weaponTitle + ".Reload.Ammo.Ammo_Types", AmmoTypes.class);
if (ammoTypes != null) {
// First empty the current ammo
int ammoLeft = CustomTag.AMMO_LEFT.getInteger(weaponStack);
if (ammoLeft > 0) {
ammoTypes.giveAmmo(weaponStack, (PlayerWrapper) entityWrapper, ammoLeft, config.getInt(weaponTitle + ".Reload.Magazine_Size"));
CustomTag.AMMO_LEFT.setInteger(weaponStack, 0);
}
// Then do the switch
ammoTypes.updateToNextAmmoType(weaponStack);
Mechanics ammoTypeSwitchMechanics = getConfigurations().getObject(weaponTitle + ".Reload.Ammo.Ammo_Type_Switch.Mechanics", Mechanics.class);
if (ammoTypeSwitchMechanics != null)
ammoTypeSwitchMechanics.use(new CastData(entityWrapper, weaponTitle, weaponStack));
WeaponInfoDisplay weaponInfoDisplay = getConfigurations().getObject(weaponTitle + ".Info.Weapon_Info_Display", WeaponInfoDisplay.class);
if (weaponInfoDisplay != null)
weaponInfoDisplay.send((PlayerWrapper) entityWrapper, slot);
entityWrapper.getMainHandData().cancelTasks();
entityWrapper.getOffHandData().cancelTasks();
// Here has to be return if new triggers gets added
}
}
}
Aggregations