mirror of
https://github.com/SimplexDevelopment/ArcanumOcculta.git
synced 2024-12-21 19:57:38 +00:00
API completed, Implementation required (#1)
New API, ready to go. Implementations required.
This commit is contained in:
parent
a84bbeea94
commit
0648b51c96
19
LICENSE.MD
Normal file
19
LICENSE.MD
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2023 Simplex Development Group
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to deal with the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -19,6 +19,7 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
compileOnly "org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT"
|
||||
compileOnly "org.reflections:reflections:0.10.2"
|
||||
}
|
||||
|
||||
def targetJavaVersion = 17
|
||||
|
@ -2,16 +2,15 @@ package app.simplexdev.arcanumocculta;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public final class ArcanumOcculta extends JavaPlugin {
|
||||
|
||||
public class ArcanumOcculta extends JavaPlugin
|
||||
{
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Plugin startup logic
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
public static ArcanumOcculta getInstance()
|
||||
{
|
||||
return JavaPlugin.getPlugin(ArcanumOcculta.class);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.book;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SpellBook {
|
||||
String getBookName();
|
||||
|
||||
void setBookName(final String name);
|
||||
|
||||
String getBookDescription();
|
||||
|
||||
void setBookDescription(final String description);
|
||||
|
||||
ItemStack getBookItem();
|
||||
|
||||
void setBookItem(final ItemStack itemStack);
|
||||
|
||||
List<Spell> getSpells();
|
||||
|
||||
void addSpell(Spell spell);
|
||||
|
||||
void removeSpell(Spell spell);
|
||||
|
||||
Spell getSpell(final String name);
|
||||
|
||||
Spell getSpell(final int index);
|
||||
|
||||
int getSpellCount();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.book;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface SpellTome {
|
||||
String getTomeName();
|
||||
|
||||
String getTomeDescription();
|
||||
|
||||
ItemStack getTomeItem();
|
||||
|
||||
Spell getContainedSpell();
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package app.simplexdev.arcanumocculta.api.caster;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class AbstractCaster implements Caster
|
||||
{
|
||||
private final SpellBook spellBook;
|
||||
private final UUID playerUUID;
|
||||
private final String name;
|
||||
private Wand wand;
|
||||
private CasterLevel level;
|
||||
private double currentExperience;
|
||||
private double currentMana;
|
||||
private double maxMana;
|
||||
|
||||
protected AbstractCaster(final Player player, final Wand wand, final SpellBook spellBook, final CasterLevel level)
|
||||
{
|
||||
this.spellBook = spellBook;
|
||||
this.playerUUID = player.getUniqueId();
|
||||
this.name = player.getName();
|
||||
this.wand = wand;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wand getWand()
|
||||
{
|
||||
return this.wand;
|
||||
}
|
||||
|
||||
public void setWand(final Wand wand)
|
||||
{
|
||||
this.wand = wand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellBook getSpellBook()
|
||||
{
|
||||
return this.spellBook;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId()
|
||||
{
|
||||
return this.playerUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CasterLevel getCurrentLevel()
|
||||
{
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public void setCurrentLevel(final CasterLevel level)
|
||||
{
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCurrentExperience()
|
||||
{
|
||||
return this.currentExperience;
|
||||
}
|
||||
|
||||
public void setCurrentExperience(final double experience)
|
||||
{
|
||||
this.currentExperience = experience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCurrentMana()
|
||||
{
|
||||
return this.currentMana;
|
||||
}
|
||||
|
||||
public void setCurrentMana(final double mana)
|
||||
{
|
||||
this.currentMana = mana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxMana()
|
||||
{
|
||||
return this.maxMana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxMana(final double mana)
|
||||
{
|
||||
this.maxMana = mana;
|
||||
}
|
||||
|
||||
public void addExperience(final double experience)
|
||||
{
|
||||
this.currentExperience = this.currentExperience + experience;
|
||||
}
|
||||
|
||||
public void removeExperience(final double experience)
|
||||
{
|
||||
this.currentExperience = this.currentExperience - experience;
|
||||
}
|
||||
|
||||
public void addMana(final double mana)
|
||||
{
|
||||
this.currentMana = this.currentMana + mana;
|
||||
}
|
||||
|
||||
public void removeMana(final double mana)
|
||||
{
|
||||
this.currentMana = this.currentMana - mana;
|
||||
}
|
||||
|
||||
public void setManaToMax()
|
||||
{
|
||||
this.currentMana = this.maxMana;
|
||||
}
|
||||
|
||||
public void setExperienceToZero()
|
||||
{
|
||||
this.currentExperience = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player bukkit()
|
||||
{
|
||||
return Bukkit.getPlayer(this.playerUUID);
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package app.simplexdev.arcanumocculta.api.caster;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractSpellBook implements SpellBook
|
||||
{
|
||||
private final List<Spell> spells = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean hasSpell(final Spell spell)
|
||||
{
|
||||
return getSpells().contains(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Spell> getSpells()
|
||||
{
|
||||
return this.spells;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpell(Spell spell)
|
||||
{
|
||||
this.spells.add(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSpell(Spell spell)
|
||||
{
|
||||
this.spells.remove(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getSpell(String id)
|
||||
{
|
||||
return getSpells().stream()
|
||||
.filter(spell -> spell.getId().equalsIgnoreCase(id))
|
||||
.findFirst()
|
||||
.orElse(getSpells().get(0));
|
||||
}
|
||||
|
||||
public Spell getSpell(UUID uuid)
|
||||
{
|
||||
return getSpells().stream()
|
||||
.filter(spell -> spell.getUniqueId().equals(uuid))
|
||||
.findFirst()
|
||||
.orElse(getSpells().get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getSpell(int index)
|
||||
{
|
||||
if (index < 0 || index > getSpells().size() - 1)
|
||||
return getSpells().get(0);
|
||||
return getSpells().get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCount()
|
||||
{
|
||||
return getSpells().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpell(int index, Spell spell)
|
||||
{
|
||||
this.spells.set(index, spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpell(String name, Spell spell)
|
||||
{
|
||||
this.spells.set(getSpells().indexOf(getSpell(name)), spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSpells()
|
||||
{
|
||||
this.spells.clear();
|
||||
}
|
||||
|
||||
public void addAll(Collection<? extends Spell> spells) {
|
||||
this.spells.addAll(spells);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell randomSpell()
|
||||
{
|
||||
final SplittableRandom random = new SplittableRandom();
|
||||
return getSpells().get(random.nextInt(getSpells().size()));
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package app.simplexdev.arcanumocculta.api.caster;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Caster
|
||||
{
|
||||
Wand getWand();
|
||||
|
||||
void setWand(Wand wand);
|
||||
|
||||
SpellBook getSpellBook();
|
||||
|
||||
String getName();
|
||||
|
||||
UUID getUniqueId();
|
||||
|
||||
double getCurrentMana();
|
||||
|
||||
void setCurrentMana(double mana);
|
||||
|
||||
double getMaxMana();
|
||||
|
||||
void setMaxMana(double maxMana);
|
||||
|
||||
CasterLevel getCurrentLevel();
|
||||
|
||||
void setCurrentLevel(CasterLevel level);
|
||||
|
||||
double getCurrentExperience();
|
||||
|
||||
void setCurrentExperience(double experience);
|
||||
|
||||
void addMana(double mana);
|
||||
|
||||
void removeMana(double mana);
|
||||
|
||||
void addExperience(double experience);
|
||||
|
||||
void removeExperience(double experience);
|
||||
|
||||
Player bukkit();
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package app.simplexdev.arcanumocculta.api.caster;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.stream.Stream;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public enum CasterLevel
|
||||
{
|
||||
|
||||
APPRENTICE(1, 250D, "Apprentice", "an Apprentice", ChatColor.WHITE, "Lvl1"),
|
||||
PRIMARY(2, 500D, "Primary", "a Primary", ChatColor.RED, "Lvl2"),
|
||||
SCHOLAR(3, 750D, "Scholar", "a Scholar", ChatColor.AQUA, "Lvl3"),
|
||||
PREFECT(4, 1000D, "Prefect", "a Prefect", ChatColor.BLUE, "Lvl4"),
|
||||
GRADUATE(5, 1250D, "Graduate", "a Graduate", ChatColor.GRAY, "Lvl5"),
|
||||
ADEPT(6, 1500D, "Adept", "an Adept", ChatColor.DARK_PURPLE, "Lvl6"),
|
||||
MAGISTRATE(7, 1750D, "Magister", "a Magister", ChatColor.DARK_GREEN, "Lvl7"),
|
||||
HEADMASTER(8, 2000D, "Headmaster", "a Headmaster", ChatColor.GOLD, "Lvl8"),
|
||||
ARCH_MAGE(9, 4000D, "Arch-Mage", "an Arch-Mage", ChatColor.BLACK, "Lvl9");
|
||||
|
||||
private final int level;
|
||||
private final double experienceMarker;
|
||||
private final String name;
|
||||
private final String plural;
|
||||
private final ChatColor rankColor;
|
||||
private final String suffix;
|
||||
|
||||
CasterLevel(final int level, final double experienceMarker, final String name, final String plural,
|
||||
final ChatColor rankColor,
|
||||
final String suffix)
|
||||
{
|
||||
this.experienceMarker = experienceMarker;
|
||||
this.level = level;
|
||||
this.name = name;
|
||||
this.plural = plural;
|
||||
this.rankColor = rankColor;
|
||||
this.suffix = MessageFormat.format("{0}[{1}{2}{3}]{4}",
|
||||
ChatColor.DARK_GRAY,
|
||||
rankColor,
|
||||
suffix,
|
||||
ChatColor.DARK_GRAY,
|
||||
ChatColor.RESET);
|
||||
}
|
||||
|
||||
public static CasterLevel fromOrdinal(final int ordinal)
|
||||
{
|
||||
return Stream.of(CasterLevel.values())
|
||||
.filter(lvl -> lvl.getLevel() == ordinal)
|
||||
.findFirst()
|
||||
.orElse(CasterLevel.APPRENTICE);
|
||||
}
|
||||
|
||||
public int getLevel()
|
||||
{
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getPlural()
|
||||
{
|
||||
return this.plural;
|
||||
}
|
||||
|
||||
public ChatColor getRankColor()
|
||||
{
|
||||
return this.rankColor;
|
||||
}
|
||||
|
||||
public String getSuffix()
|
||||
{
|
||||
return this.suffix;
|
||||
}
|
||||
|
||||
public double getExperienceMarker()
|
||||
{
|
||||
return this.experienceMarker;
|
||||
}
|
||||
|
||||
public boolean isAtLeast(final CasterLevel level) {
|
||||
return this.getLevel() >= level.getLevel();
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package app.simplexdev.arcanumocculta.api.caster;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import java.util.List;
|
||||
|
||||
public interface SpellBook
|
||||
{
|
||||
List<Spell> getSpells();
|
||||
|
||||
void addSpell(Spell spell);
|
||||
|
||||
void removeSpell(Spell spell);
|
||||
|
||||
Spell getSpell(String name);
|
||||
|
||||
Spell getSpell(int index);
|
||||
|
||||
int getSpellCount();
|
||||
|
||||
void setSpell(int index, Spell spell);
|
||||
|
||||
void setSpell(String name, Spell spell);
|
||||
|
||||
void clearSpells();
|
||||
|
||||
Spell randomSpell();
|
||||
|
||||
boolean hasSpell(final Spell spell);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.display;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Display;
|
||||
|
||||
public interface SpellDisplay<T extends Display> {
|
||||
T getDisplay();
|
||||
|
||||
Location getLocation();
|
||||
|
||||
World getWorld();
|
||||
|
||||
Caster getWhoCast();
|
||||
|
||||
Spell getCastSpell();
|
||||
|
||||
Particle[] getParticles();
|
||||
|
||||
void display(boolean force);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public interface CompoundEffect extends Effect {
|
||||
PotionEffectType[] getEffectTypes();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public interface Effect
|
||||
{
|
||||
Duration getDuration();
|
||||
|
||||
float getAmplifier();
|
||||
|
||||
boolean isAmbient();
|
||||
|
||||
boolean forceDisplay();
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
public interface EffectProvider<T extends Effect> {
|
||||
T getEffect(Class<T> type);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
|
||||
public interface PassiveEffect extends Effect
|
||||
{
|
||||
Caster getWandHolder();
|
||||
|
||||
void onTick();
|
||||
|
||||
PassiveEffects getPassiveEffect();
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public enum PassiveEffects {
|
||||
MANA_REGEN(Duration.ofSeconds(10L), 2.0),
|
||||
LIFE_STEAL(Duration.ofSeconds(5L), 1.0),
|
||||
ABSORPTION(Duration.ofSeconds(30L), 4.0),
|
||||
SPELL_SHIELD(Duration.ofSeconds(5L), 5.0),
|
||||
IMMUNITY(Duration.ofSeconds(5L), 100.0),
|
||||
WITHER(Duration.ofSeconds(5L), 2.0),
|
||||
DAMAGE_BOOST(Duration.ofSeconds(5L), 2.75),
|
||||
IMPROVED_ACCURACY(Duration.ofSeconds(5L), 5.0);
|
||||
|
||||
private final Duration duration;
|
||||
private final double amount;
|
||||
|
||||
PassiveEffects(final Duration duration, final double amount) {
|
||||
this.duration = duration;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
Duration getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
double getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public interface SpecialEffect extends Effect {
|
||||
void applyEffect(final LivingEntity target);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.effect;
|
||||
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public interface SpellEffect extends Effect {
|
||||
PotionEffectType getEffectType();
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.player;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.book.SpellBook;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Caster {
|
||||
/**
|
||||
* @return The {@link UUID} of the caster.
|
||||
*/
|
||||
UUID getCasterUUID();
|
||||
|
||||
/**
|
||||
* @return The name of the caster.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* @return The {@link Player} associated with this caster.
|
||||
*/
|
||||
Player bukkit();
|
||||
|
||||
/**
|
||||
* @return The amount of maximum mana the caster is allowed to have.
|
||||
*/
|
||||
double getMaximumMana();
|
||||
|
||||
/**
|
||||
* Sets the maximum amount of mana the caster is allowed to have.
|
||||
*
|
||||
* @param mana The amount of mana to set the maximum to.
|
||||
*/
|
||||
void setMaximumMana(final double mana);
|
||||
|
||||
/**
|
||||
* @return The amount of mana the caster currently has.
|
||||
*/
|
||||
double getCurrentMana();
|
||||
|
||||
/**
|
||||
* Adds mana to the caster.
|
||||
*
|
||||
* @param mana The amount of mana to add.
|
||||
* @return The players updated {@link #getCurrentMana()}.
|
||||
*/
|
||||
double addMana(final double mana);
|
||||
|
||||
/**
|
||||
* Increases the amount of maximum mana this caster is allowed to have.
|
||||
*
|
||||
* @param mana The amount of mana to increase the maximum by.
|
||||
* @return The players updated {@link #getMaximumMana()}.
|
||||
*/
|
||||
double increaseMaximumMana(final double mana);
|
||||
|
||||
/**
|
||||
* Removes mana from the caster.
|
||||
*
|
||||
* @param mana The amount of mana to remove.
|
||||
* @return The players updated {@link #getCurrentMana()}.
|
||||
*/
|
||||
double removeMana(final double mana);
|
||||
|
||||
/**
|
||||
* Decreases the amount of maximum mana this caster is allowed to have.
|
||||
*
|
||||
* @param mana The amount of mana to decrease the maximum by.
|
||||
* @return The players updated {@link #getMaximumMana()}.
|
||||
*/
|
||||
double decreaseMaximumMana(final double mana);
|
||||
|
||||
/**
|
||||
* Sets the amount of mana the caster currently has.
|
||||
*
|
||||
* @param mana The amount of mana to set the user's current mana to.
|
||||
*/
|
||||
void setMana(final double mana);
|
||||
|
||||
/**
|
||||
* @return The {@link SpellBook} of the caster.
|
||||
*/
|
||||
SpellBook getSpellbook();
|
||||
|
||||
/**
|
||||
* @return A list of {@link SpellResistance}s the caster has.
|
||||
*/
|
||||
List<SpellResistance> getSpellResistances();
|
||||
|
||||
void addSpellResistance(SpellResistance resistance);
|
||||
|
||||
void removeSpellResistance(SpellResistance resistance);
|
||||
|
||||
boolean hasResistance(int spellOrdinal);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.player;
|
||||
|
||||
public interface SpellResistance {
|
||||
String getSpellName();
|
||||
|
||||
double getResistance();
|
||||
|
||||
int getOrdinal();
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.player;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.PassiveEffect;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Wand {
|
||||
String getWandName();
|
||||
|
||||
String getWandDescription();
|
||||
|
||||
ItemStack getWandItem();
|
||||
|
||||
double getManaPenalty();
|
||||
|
||||
List<PassiveEffect> getPassiveEffects();
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
package app.simplexdev.arcanumocculta.api.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Damages;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Durations;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.ManaCosts;
|
||||
import app.simplexdev.arcanumocculta.util.SpellUtils;
|
||||
import java.util.List;
|
||||
import java.util.SplittableRandom;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public abstract class AbstractSpell implements Spell
|
||||
{
|
||||
private final String name;
|
||||
private final String id;
|
||||
private final String description;
|
||||
private final CasterLevel levelRequirement;
|
||||
private final Damages baseDamage;
|
||||
private final Durations effectDuration;
|
||||
private final ManaCosts manaCost;
|
||||
private final long coolDown;
|
||||
private final SplittableRandom random = new SplittableRandom();
|
||||
|
||||
protected AbstractSpell(final String name, final String id,
|
||||
final String description, final CasterLevel levelRequirement,
|
||||
final Damages baseDamage, final Durations effectDuration,
|
||||
final ManaCosts manaCost, final long coolDown)
|
||||
{
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.levelRequirement = levelRequirement;
|
||||
this.baseDamage = baseDamage;
|
||||
this.effectDuration = effectDuration;
|
||||
this.manaCost = manaCost;
|
||||
this.coolDown = coolDown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CasterLevel getLevelRequirement()
|
||||
{
|
||||
return levelRequirement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Damages baseDamage()
|
||||
{
|
||||
return baseDamage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Durations effectDuration()
|
||||
{
|
||||
return effectDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaCosts manaCost()
|
||||
{
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long coolDown()
|
||||
{
|
||||
return coolDown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell dupe()
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.getClass()
|
||||
.getDeclaredConstructor()
|
||||
.newInstance();
|
||||
}
|
||||
catch (ReflectiveOperationException e)
|
||||
{
|
||||
Bukkit.getLogger().severe(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnlocked(Caster caster)
|
||||
{
|
||||
return caster.getSpellBook().hasSpell(this)
|
||||
&& caster.getCurrentLevel().isAtLeast(this.getLevelRequirement());
|
||||
}
|
||||
|
||||
protected SplittableRandom random()
|
||||
{
|
||||
return random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the caster has enough mana to cast this spell.
|
||||
*
|
||||
* @param caster The caster who is casting the spell
|
||||
* @return True if the caster has enough mana, false otherwise
|
||||
*/
|
||||
protected boolean checkManaCosts(final Caster caster)
|
||||
{
|
||||
boolean isValid = !manaCost().isMoreThan(caster.getCurrentMana());
|
||||
if (!isValid)
|
||||
caster.bukkit().sendMessage(ChatColor.RED + "You don't have enough mana to cast this spell!");
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
public void applyEffects(final List<Entity> targets, final Caster caster)
|
||||
{
|
||||
targets.stream()
|
||||
.filter(LivingEntity.class::isInstance)
|
||||
.map(LivingEntity.class::cast)
|
||||
.forEach(entity -> applyEffectsIndividually(
|
||||
getSpellEffects(),
|
||||
entity,
|
||||
caster));
|
||||
}
|
||||
|
||||
public Entity prepareProjectile(final Caster caster, final Material visual)
|
||||
{
|
||||
final double expMod = getLevelRequirement().getExperienceMarker();
|
||||
|
||||
final Player player = caster.bukkit();
|
||||
final Location location = player.getLocation().clone().add(0, player.getEyeHeight(), 0);
|
||||
final Vector velocity = player.getLocation().getDirection().multiply(2);
|
||||
final Entity projectile = createProjectile(visual, player.getWorld(), location,
|
||||
velocity);
|
||||
caster.removeMana(manaCost().getManaCost());
|
||||
caster.addExperience(random().nextDouble(expMod * 0.25));
|
||||
return projectile;
|
||||
}
|
||||
|
||||
public void tracer(final World world, final Location location, final Particle particle)
|
||||
{
|
||||
world.spawnParticle(particle,
|
||||
location,
|
||||
0,
|
||||
random().nextDouble(-2, 2),
|
||||
random().nextDouble(-2, 2),
|
||||
random().nextDouble(-2, 2));
|
||||
}
|
||||
|
||||
private void applyEffectsIndividually(final SpellEffect[] effects, final LivingEntity target,
|
||||
final Caster caster)
|
||||
{
|
||||
for (final SpellEffect effect : effects)
|
||||
effect.apply(target, caster);
|
||||
}
|
||||
|
||||
private static ItemDisplay createProjectile(final Material visual, final World world, final Location location,
|
||||
final Vector velocity)
|
||||
{
|
||||
final ItemDisplay display = (ItemDisplay) world.spawnEntity(location, EntityType.ITEM_DISPLAY);
|
||||
display.setItemStack(new ItemStack(visual));
|
||||
display.setGravity(true);
|
||||
display.setPersistent(false);
|
||||
display.setSilent(true);
|
||||
display.setShadowRadius(0);
|
||||
display.setShadowStrength(0);
|
||||
display.setVelocity(velocity);
|
||||
return display;
|
||||
}
|
||||
}
|
@ -1,23 +1,47 @@
|
||||
package app.simplexdev.arcanumocculta.api.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.Effect;
|
||||
import app.simplexdev.arcanumocculta.api.effect.EffectProvider;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Damages;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Durations;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.ManaCosts;
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import java.util.UUID;
|
||||
|
||||
import java.time.Duration;
|
||||
public interface Spell
|
||||
{
|
||||
String getName();
|
||||
|
||||
public interface Spell<T extends Effect> {
|
||||
String getSpellName();
|
||||
String getId();
|
||||
|
||||
String getSpellDescription();
|
||||
default UUID getUniqueId()
|
||||
{
|
||||
return UUID.nameUUIDFromBytes(this.getName().getBytes());
|
||||
}
|
||||
|
||||
double getManaCost();
|
||||
String getDescription();
|
||||
|
||||
Duration getCoolDown();
|
||||
CasterLevel getLevelRequirement();
|
||||
|
||||
int getSpellLevel();
|
||||
Damages baseDamage();
|
||||
|
||||
SpellProjectile<? extends Projectile> getSpellProjectile();
|
||||
SpellEffect[] getSpellEffects();
|
||||
|
||||
T getEffect();
|
||||
Durations effectDuration();
|
||||
|
||||
ManaCosts manaCost();
|
||||
|
||||
long coolDown();
|
||||
|
||||
boolean isUnlocked(final Caster caster);
|
||||
|
||||
void cast(final Caster caster, final Wand wand);
|
||||
|
||||
/**
|
||||
* Used to create a copy of the spell for player spell books.
|
||||
* Should only ever be used by the primary list when initializing a player's spell book.
|
||||
*
|
||||
* @return a copy of the spell.
|
||||
*/
|
||||
Spell dupe();
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package app.simplexdev.arcanumocculta.api.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SpellEffect
|
||||
{
|
||||
void apply(final LivingEntity target, final Caster caster);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.api.spell;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SpellProjectile<T extends Projectile> {
|
||||
Class<T> getProjectileType();
|
||||
|
||||
List<Particle> getParticles();
|
||||
|
||||
void cast(final Location target);
|
||||
|
||||
void cast(final LivingEntity target);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.api.spell.enums;
|
||||
|
||||
public enum Damages
|
||||
{
|
||||
MINIMAL(0.5),
|
||||
LIGHT(1.0),
|
||||
NEUTRAL(1.5),
|
||||
MODERATE(2.0),
|
||||
INTERMEDIATE(2.5),
|
||||
HEAVY(3.0),
|
||||
MAJOR(3.5),
|
||||
SEVERE(4.0),
|
||||
EXTREME(4.5),
|
||||
IMMENSE(5.0),
|
||||
CRITICAL(6.5),
|
||||
FATAL(10.0),
|
||||
OVERKILL(20.0),
|
||||
DEVASTATION(50.0);
|
||||
|
||||
private final double damage;
|
||||
|
||||
Damages(double damage)
|
||||
{
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public double getDamage()
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
public double multiply(double multiplier) {
|
||||
return damage * multiplier;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.api.spell.enums;
|
||||
|
||||
public enum Durations
|
||||
{
|
||||
INSTANT(1L),
|
||||
SHORT(20L),
|
||||
MEDIUM(20L * 5L),
|
||||
LONG(20L * 30L),
|
||||
VERY_LONG(20L * 60L),
|
||||
AGES(20L * 60L * 5L);
|
||||
|
||||
private final long ticks;
|
||||
|
||||
Durations(final long ticks)
|
||||
{
|
||||
this.ticks = ticks;
|
||||
}
|
||||
|
||||
public long getTicks()
|
||||
{
|
||||
return this.ticks;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.api.spell.enums;
|
||||
|
||||
public enum ManaCosts
|
||||
{
|
||||
MINIMAL_CAST(5.0),
|
||||
LIGHT_CAST(10.0),
|
||||
MODERATE_CAST(20.0),
|
||||
HEAVY_CAST(30.0),
|
||||
MAJOR_CAST(50.0),
|
||||
EXTREME_CAST(100.0),
|
||||
IMMENSE_CAST(200.0),
|
||||
MASTER_CAST(500.0);
|
||||
|
||||
private final double manaCost;
|
||||
|
||||
ManaCosts(final double manaCost) {
|
||||
this.manaCost = manaCost;
|
||||
}
|
||||
|
||||
public double getManaCost() {
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
public boolean isMoreThan(final double manaCost) {
|
||||
return this.manaCost > manaCost;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.api.spell.enums;
|
||||
|
||||
// Reference for implementation.
|
||||
public enum SpellTypes
|
||||
{
|
||||
SOUL_PEBBLE, SOUL_SHARD, LARGE_SOUL_SHARD, SOUL_COMET_SHARD, SOUL_COMET, SOUL_SHARD_SPIRAL, SOUL_STARS,
|
||||
SOUL_STAR_SHOWER, SOUL_ARC, SOUL_BARRAGE, SOUL_BURST, SOUL_CANNON, SOUL_HAMMER, SOUL_BLAST, SOUL_EXPLOSION,
|
||||
SOUL_LAMP, SOUL_PHALANX, GREAT_SOUL_PHALANX, SOUL_MIST, ARS_NOVA, ARS_ENIGMA, ARS_ULTIMA,
|
||||
|
||||
FLAME_SLING, FLAME_BURST, CATCH_FLAME, FLAME_BARRAGE, FIREBALL, METEORITE, METEOR, FLAME_WHIP, FLAME_FAN,
|
||||
FLAME_ORB, FLAME_PILLARS, FLAME_WHIRLWIND,
|
||||
|
||||
WITHER_BURST, WITHER_SHOT, WITHER_SHARD, WITHER_COMET, WITHER_METEORITE,
|
||||
|
||||
HEALING, GREATER_HEALING, HEAL_OTHER, HEALING_HANDS, HEALING_WAVE, GUARDIAN_PROTECTION, SAVIORS_BLESSING,
|
||||
DIVING_BLESSING, DIVINE_GRACE, ULTIMATE_HEALING, DIVINE_INTERVENTION, DIVINE_RETRIBUTION,
|
||||
|
||||
LIGHTNING_BOLT, LIGHTNING_STORM, STAR_SHOWER, STORM_CALL, LIGHTNING_BARRAGE;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package app.simplexdev.arcanumocculta.api.wand;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public abstract class AbstractWand implements Wand
|
||||
{
|
||||
private final ItemStack item;
|
||||
private final CapType capType;
|
||||
private final CoreType coreType;
|
||||
private final GemType gemType;
|
||||
private final String name;
|
||||
private final String description;
|
||||
|
||||
protected AbstractWand(String name,
|
||||
String description, ItemStack item, CapType capType,
|
||||
CoreType coreType, GemType gemType)
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.item = item;
|
||||
this.capType = capType;
|
||||
this.coreType = coreType;
|
||||
this.gemType = gemType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getSpellBonus()
|
||||
{
|
||||
return getCapType().getSpellBoost()
|
||||
+ getCoreType().getSpellBoost()
|
||||
+ getGemType().getSpellBoost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CapType getCapType()
|
||||
{
|
||||
return capType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoreType getCoreType()
|
||||
{
|
||||
return coreType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GemType getGemType()
|
||||
{
|
||||
return gemType;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package app.simplexdev.arcanumocculta.api.wand;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public enum CapType
|
||||
{
|
||||
IRON(Material.IRON_NUGGET, 1.0),
|
||||
GOLD(Material.GOLD_NUGGET, 2.5),
|
||||
DIAMOND(Material.DIAMOND, 3.0),
|
||||
OBSIDIAN(Material.OBSIDIAN, 4.5),
|
||||
NETHERITE(Material.NETHERITE_INGOT, 6.0);
|
||||
|
||||
private final Material material;
|
||||
private final double spellBoost;
|
||||
|
||||
CapType(final Material material, final double spellBoost) {
|
||||
this.material = material;
|
||||
this.spellBoost = spellBoost;
|
||||
}
|
||||
|
||||
public final Material getMaterial() {
|
||||
return this.material;
|
||||
}
|
||||
|
||||
public final double getSpellBoost() {
|
||||
return this.spellBoost;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package app.simplexdev.arcanumocculta.api.wand;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public enum CoreType
|
||||
{
|
||||
WOOD(Material.STICK, 1.0),
|
||||
IRON(Material.IRON_INGOT, 1.25),
|
||||
GOLD(Material.GOLD_INGOT, 1.5),
|
||||
OBSIDIAN(Material.OBSIDIAN, 1.75),
|
||||
BLAZE(Material.BLAZE_ROD, 2.0),
|
||||
ENDER(Material.END_ROD, 2.5);
|
||||
|
||||
private final Material material;
|
||||
private final double spellBoost;
|
||||
|
||||
CoreType(final Material material, final double spellBoost)
|
||||
{
|
||||
this.spellBoost = spellBoost;
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public Material getMaterial()
|
||||
{
|
||||
return this.material;
|
||||
}
|
||||
|
||||
public double getSpellBoost()
|
||||
{
|
||||
return spellBoost;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package app.simplexdev.arcanumocculta.api.wand;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public enum GemType
|
||||
{
|
||||
NONE(Material.AIR, 1.0),
|
||||
LAPIS(Material.LAPIS_LAZULI, 1.25),
|
||||
REDSTONE(Material.REDSTONE, 1.5),
|
||||
EMERALD(Material.EMERALD, 2.0),
|
||||
DIAMOND(Material.DIAMOND, 3.0),
|
||||
QUARTZ(Material.QUARTZ, 4.0);
|
||||
|
||||
private final Material material;
|
||||
private final double spellBoost;
|
||||
|
||||
GemType(final Material material, final double spellBoost)
|
||||
{
|
||||
this.spellBoost = spellBoost;
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public Material getMaterial()
|
||||
{
|
||||
return this.material;
|
||||
}
|
||||
|
||||
public double getSpellBoost()
|
||||
{
|
||||
return spellBoost;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package app.simplexdev.arcanumocculta.api.wand;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface Wand
|
||||
{
|
||||
String getName();
|
||||
|
||||
String getDescription();
|
||||
|
||||
ItemStack getItem();
|
||||
|
||||
double getSpellBonus();
|
||||
|
||||
CapType getCapType();
|
||||
|
||||
CoreType getCoreType();
|
||||
|
||||
GemType getGemType();
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package app.simplexdev.arcanumocculta.base;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.AbstractCaster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.caster.SpellBook;
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SimpleCaster extends AbstractCaster
|
||||
{
|
||||
public SimpleCaster(Player player, Wand wand,
|
||||
SpellBook spellBook,
|
||||
CasterLevel level)
|
||||
{
|
||||
super(player, wand, spellBook, level);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package app.simplexdev.arcanumocculta.base;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.AbstractSpellBook;
|
||||
|
||||
public class SimpleSpellBook extends AbstractSpellBook
|
||||
{
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package app.simplexdev.arcanumocculta.base;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.wand.AbstractWand;
|
||||
import app.simplexdev.arcanumocculta.api.wand.CapType;
|
||||
import app.simplexdev.arcanumocculta.api.wand.CoreType;
|
||||
import app.simplexdev.arcanumocculta.api.wand.GemType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class SimpleWand extends AbstractWand
|
||||
{
|
||||
public SimpleWand(String name, String description, ItemStack item,
|
||||
CapType capType,
|
||||
CoreType coreType,
|
||||
GemType gemType)
|
||||
{
|
||||
super(name, description, item, capType, coreType, gemType);
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.book;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.book.SpellBook;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSpellBook implements SpellBook {
|
||||
private final List<Spell> spellbook = new ArrayList<>();
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private ItemStack itemStack;
|
||||
|
||||
protected AbstractSpellBook(final String name) {
|
||||
this.name = name;
|
||||
this.description = ChatColor.BLUE + "A simple spell book.";
|
||||
|
||||
final ItemStack stack = new ItemStack(Material.WRITTEN_BOOK, 1);
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(List.of(description));
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
this.itemStack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBookName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBookName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBookDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBookDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getBookItem() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBookItem(final ItemStack stack) {
|
||||
this.itemStack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Spell> getSpells() {
|
||||
return this.spellbook;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpell(Spell spell) {
|
||||
this.spellbook.add(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSpell(Spell spell) {
|
||||
this.spellbook.remove(spell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getSpell(String name) {
|
||||
return getSpells()
|
||||
.stream()
|
||||
.filter(spell -> spell.getSpellName().equalsIgnoreCase(name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getSpell(int index) {
|
||||
return getSpells().get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCount() {
|
||||
return getSpells().size();
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.book;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.book.SpellTome;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSpellTome implements SpellTome {
|
||||
private final Spell containedSpell;
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final ItemStack item;
|
||||
|
||||
protected AbstractSpellTome(final String name, final String description, final Spell containedSpell) {
|
||||
this.containedSpell = containedSpell;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
final ItemStack stack = new ItemStack(Material.BOOK, 1);
|
||||
final ItemMeta meta = stack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(List.of(description));
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
this.item = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTomeName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTomeDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getTomeItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContainedSpell() {
|
||||
return this.containedSpell;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.CompoundEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public abstract class AbstractCompoundEffect extends AbstractEffect implements CompoundEffect {
|
||||
private final PotionEffectType[] effectTypes;
|
||||
|
||||
protected AbstractCompoundEffect(Duration duration, float amplifier, boolean ambient, boolean forceDisplay, PotionEffectType... effectTypes) {
|
||||
super(duration, amplifier, ambient, forceDisplay);
|
||||
this.effectTypes = effectTypes;
|
||||
}
|
||||
|
||||
protected AbstractCompoundEffect(Duration duration, float amplifier, boolean forceDisplay, PotionEffectType... effectTypes) {
|
||||
super(duration, amplifier, forceDisplay);
|
||||
this.effectTypes = effectTypes;
|
||||
}
|
||||
|
||||
protected AbstractCompoundEffect(Duration duration, float amplifier, PotionEffectType... effectTypes) {
|
||||
super(duration, amplifier);
|
||||
this.effectTypes = effectTypes;
|
||||
}
|
||||
|
||||
protected AbstractCompoundEffect(Duration duration, PotionEffectType... effectTypes) {
|
||||
super(duration);
|
||||
this.effectTypes = effectTypes;
|
||||
}
|
||||
|
||||
protected AbstractCompoundEffect(PotionEffectType... effectTypes) {
|
||||
super();
|
||||
this.effectTypes = effectTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PotionEffectType[] getEffectTypes() {
|
||||
return new PotionEffectType[0];
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.Effect;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public abstract class AbstractEffect implements Effect {
|
||||
private final Duration duration;
|
||||
private final float amplifier;
|
||||
private final boolean ambient;
|
||||
private final boolean forceDisplay;
|
||||
|
||||
protected AbstractEffect(Duration duration, float amplifier, boolean ambient, boolean forceDisplay) {
|
||||
this.duration = duration;
|
||||
this.amplifier = amplifier;
|
||||
this.ambient = ambient;
|
||||
this.forceDisplay = forceDisplay;
|
||||
}
|
||||
|
||||
protected AbstractEffect(Duration duration, float amplifier, boolean forceDisplay) {
|
||||
this(duration, amplifier, false, forceDisplay);
|
||||
}
|
||||
|
||||
protected AbstractEffect(Duration duration, float amplifier) {
|
||||
this(duration, amplifier, false, false);
|
||||
}
|
||||
|
||||
protected AbstractEffect(Duration duration) {
|
||||
this(duration, 1, false, false);
|
||||
}
|
||||
|
||||
protected AbstractEffect() {
|
||||
this(Duration.ofSeconds(5L), 1, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAmplifier() {
|
||||
return amplifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbient() {
|
||||
return ambient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceDisplay() {
|
||||
return forceDisplay;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.PassiveEffect;
|
||||
import app.simplexdev.arcanumocculta.api.effect.PassiveEffects;
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public abstract class AbstractPassiveEffect extends AbstractEffect implements PassiveEffect {
|
||||
|
||||
private final Caster wandHolder;
|
||||
private final PassiveEffects passiveEffect;
|
||||
|
||||
protected AbstractPassiveEffect(Duration duration, float amplifier, boolean ambient, boolean forceDisplay, Caster wandHolder, PassiveEffects passiveEffect) {
|
||||
super(duration, amplifier, ambient, forceDisplay);
|
||||
this.wandHolder = wandHolder;
|
||||
this.passiveEffect = passiveEffect;
|
||||
}
|
||||
|
||||
public AbstractPassiveEffect(Duration duration, float amplifier, boolean forceDisplay, Caster wandHolder, PassiveEffects passiveEffect) {
|
||||
super(duration, amplifier, forceDisplay);
|
||||
this.wandHolder = wandHolder;
|
||||
this.passiveEffect = passiveEffect;
|
||||
}
|
||||
|
||||
protected AbstractPassiveEffect(Duration duration, float amplifier, Caster wandHolder, PassiveEffects passiveEffect) {
|
||||
super(duration, amplifier);
|
||||
this.wandHolder = wandHolder;
|
||||
this.passiveEffect = passiveEffect;
|
||||
}
|
||||
|
||||
protected AbstractPassiveEffect(Duration duration, Caster wandHolder, PassiveEffects passiveEffect) {
|
||||
super(duration);
|
||||
this.wandHolder = wandHolder;
|
||||
this.passiveEffect = passiveEffect;
|
||||
}
|
||||
|
||||
protected AbstractPassiveEffect(Caster wandHolder, PassiveEffects passiveEffect) {
|
||||
super();
|
||||
this.wandHolder = wandHolder;
|
||||
this.passiveEffect = passiveEffect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Caster getWandHolder() {
|
||||
return wandHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PassiveEffects getPassiveEffect() {
|
||||
return passiveEffect;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.SpellEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public abstract class AbstractSpellEffect extends AbstractEffect implements SpellEffect {
|
||||
private final PotionEffectType effectType;
|
||||
|
||||
protected AbstractSpellEffect(Duration duration, float amplifier, boolean ambient, boolean forceDisplay, PotionEffectType effectType) {
|
||||
super(duration, amplifier, ambient, forceDisplay);
|
||||
this.effectType = effectType;
|
||||
}
|
||||
|
||||
protected AbstractSpellEffect(Duration duration, float amplifier, boolean forceDisplay, PotionEffectType effectType) {
|
||||
super(duration, amplifier, forceDisplay);
|
||||
this.effectType = effectType;
|
||||
}
|
||||
|
||||
protected AbstractSpellEffect(Duration duration, float amplifier, PotionEffectType effectType) {
|
||||
super(duration, amplifier);
|
||||
this.effectType = effectType;
|
||||
}
|
||||
|
||||
protected AbstractSpellEffect(Duration duration, PotionEffectType effectType) {
|
||||
super(duration);
|
||||
this.effectType = effectType;
|
||||
}
|
||||
|
||||
protected AbstractSpellEffect(PotionEffectType effectType) {
|
||||
super();
|
||||
this.effectType = effectType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PotionEffectType getEffectType() {
|
||||
return effectType;
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.player;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.book.SpellBook;
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.player.SpellResistance;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractCaster implements Caster {
|
||||
private final String name;
|
||||
private final UUID uuid;
|
||||
private final SpellBook spellBook;
|
||||
private final List<SpellResistance> spellResistances = new ArrayList<>();
|
||||
|
||||
private double maximumMana;
|
||||
private double currentMana;
|
||||
|
||||
protected AbstractCaster(final Player player, SpellBook spellBook) {
|
||||
this.name = player.getName();
|
||||
this.uuid = player.getUniqueId();
|
||||
this.spellBook = spellBook;
|
||||
|
||||
this.maximumMana = 20;
|
||||
this.currentMana = maximumMana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getCasterUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaximumMana() {
|
||||
return maximumMana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximumMana(double mana) {
|
||||
this.maximumMana = mana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCurrentMana() {
|
||||
return currentMana;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double addMana(double mana) {
|
||||
this.currentMana += mana;
|
||||
return getCurrentMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double increaseMaximumMana(double mana) {
|
||||
this.maximumMana += mana;
|
||||
return getMaximumMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double removeMana(double mana) {
|
||||
final double newMana = currentMana - mana;
|
||||
if (newMana < 0) {
|
||||
currentMana = 0;
|
||||
} else {
|
||||
currentMana = newMana;
|
||||
}
|
||||
return getCurrentMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double decreaseMaximumMana(double mana) {
|
||||
final double newMana = maximumMana - mana;
|
||||
if (newMana < 0) {
|
||||
maximumMana = 0;
|
||||
} else {
|
||||
maximumMana = newMana;
|
||||
}
|
||||
return getMaximumMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMana(double mana) {
|
||||
if (mana > getMaximumMana()) {
|
||||
currentMana = getMaximumMana();
|
||||
} else if (mana < 0) {
|
||||
currentMana = 0;
|
||||
} else {
|
||||
currentMana = mana;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellBook getSpellbook() {
|
||||
return spellBook;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpellResistance> getSpellResistances() {
|
||||
return spellResistances;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpellResistance(SpellResistance resistance) {
|
||||
this.spellResistances.add(resistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSpellResistance(SpellResistance resistance) {
|
||||
this.spellResistances.remove(resistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResistance(int ordinal) {
|
||||
return getSpellResistances().stream().anyMatch(resistance -> resistance.getOrdinal() == ordinal);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.player;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.PassiveEffect;
|
||||
import app.simplexdev.arcanumocculta.api.player.Wand;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractWand implements Wand {
|
||||
private final List<PassiveEffect> passiveEffects = new ArrayList<>();
|
||||
private String name;
|
||||
private String description;
|
||||
private ItemStack item;
|
||||
private double manaPenalty;
|
||||
|
||||
protected AbstractWand(String name, String description, ItemStack item, double manaPenalty) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.item = item;
|
||||
this.manaPenalty = manaPenalty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWandName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWandDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getWandItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getManaPenalty() {
|
||||
return manaPenalty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PassiveEffect> getPassiveEffects() {
|
||||
return passiveEffects;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.player;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.player.SpellResistance;
|
||||
|
||||
public class SimpleSpellResistance implements SpellResistance {
|
||||
private final String name;
|
||||
private final double resistance;
|
||||
private final int ordinal;
|
||||
|
||||
public SimpleSpellResistance(String spellName, double resistance, int ordinal) {
|
||||
this.name = spellName;
|
||||
this.resistance = resistance;
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpellName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getResistance() {
|
||||
return resistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrdinal() {
|
||||
return ordinal;
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.Effect;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public abstract class AbstractSpell<T extends Effect> implements Spell<T> {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final double manaCost;
|
||||
private final Duration coolDown;
|
||||
private final int spellLevel;
|
||||
private final T spellEffect;
|
||||
|
||||
private long coolDownEnd;
|
||||
|
||||
protected AbstractSpell(String name, String description, double manaCost, Duration coolDown, int spellLevel, T effect) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.manaCost = manaCost;
|
||||
this.coolDown = coolDown;
|
||||
this.spellLevel = spellLevel;
|
||||
this.spellEffect = effect;
|
||||
}
|
||||
|
||||
protected AbstractSpell(String name, String description, double manaCost, Duration coolDown, T effect) {
|
||||
this(name, description, manaCost, coolDown, 1, effect);
|
||||
}
|
||||
|
||||
protected AbstractSpell(String name, String description, double manaCost, T effect) {
|
||||
this(name, description, manaCost, Duration.ofSeconds(10L), effect);
|
||||
}
|
||||
|
||||
protected AbstractSpell(String name, String description, T effect) {
|
||||
this(name, description, 5.0, effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpellName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSpellDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getManaCost() {
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getCoolDown() {
|
||||
return coolDown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellLevel() {
|
||||
return spellLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getEffect() {
|
||||
return spellEffect;
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.base.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.CompoundEffect;
|
||||
import app.simplexdev.arcanumocculta.api.effect.Effect;
|
||||
import app.simplexdev.arcanumocculta.api.effect.SpecialEffect;
|
||||
import app.simplexdev.arcanumocculta.api.effect.SpellEffect;
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import app.simplexdev.arcanumocculta.api.spell.SpellProjectile;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.AreaEffectCloud;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSpellProjectile<T extends Projectile> implements SpellProjectile<T> {
|
||||
|
||||
private static final List<EntityType> accepted = List.of(
|
||||
EntityType.ARROW,
|
||||
EntityType.SPECTRAL_ARROW,
|
||||
EntityType.FIREBALL,
|
||||
EntityType.DRAGON_FIREBALL,
|
||||
EntityType.SMALL_FIREBALL,
|
||||
EntityType.WITHER_SKULL,
|
||||
EntityType.ENDER_PEARL,
|
||||
EntityType.SNOWBALL,
|
||||
EntityType.EGG,
|
||||
EntityType.TRIDENT,
|
||||
EntityType.FIREWORK,
|
||||
EntityType.LLAMA_SPIT,
|
||||
EntityType.SHULKER_BULLET,
|
||||
EntityType.FISHING_HOOK,
|
||||
EntityType.SPLASH_POTION,
|
||||
EntityType.THROWN_EXP_BOTTLE);
|
||||
|
||||
private final Class<T> projectile;
|
||||
private final List<Particle> particles;
|
||||
private final Caster caster;
|
||||
private final Spell<?> spell;
|
||||
|
||||
protected AbstractSpellProjectile(final Spell<?> spell, final Caster caster, final Class<T> projectile, final Particle... particles) {
|
||||
this.projectile = projectile;
|
||||
this.particles = Arrays.asList(particles);
|
||||
this.caster = caster;
|
||||
this.spell = spell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getProjectileType() {
|
||||
return projectile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Particle> getParticles() {
|
||||
return particles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cast(Location target) {
|
||||
final Vector velocity = caster.bukkit().getEyeLocation().getDirection().multiply(2);
|
||||
final T launched = caster.bukkit().launchProjectile(getProjectileType(), velocity);
|
||||
|
||||
while (!launched.isDead()) {
|
||||
final double randomXOffset = Math.sin((Math.random() * 10 - 2) % Math.PI) * 5;
|
||||
final double randomYOffset = ((Math.random() * 10 - 2) % Math.PI) * 5;
|
||||
final double randomZOffset = Math.cos((Math.random() * 10 - 2) % (2 * Math.PI)) * 5;
|
||||
particles.forEach(particle -> launched.getWorld().spawnParticle(particle, launched.getLocation(), 1, randomXOffset, randomYOffset, randomZOffset));
|
||||
|
||||
if (launched.isOnGround()
|
||||
|| launched.isDead()
|
||||
|| launched.getTicksLived() > 100
|
||||
|| launched.getLocation().clone().equals(target)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final Effect effect = spell.getEffect();
|
||||
if (effect instanceof SpellEffect sp) {
|
||||
PotionEffect e = sp.getEffectType().createEffect((int) sp.getDuration().getSeconds(), (int) sp.getAmplifier());
|
||||
AreaEffectCloud cloud = (AreaEffectCloud) target.getWorld().spawnEntity(target, EntityType.AREA_EFFECT_CLOUD);
|
||||
cloud.addCustomEffect(e, true);
|
||||
cloud.setRadius(2.5F);
|
||||
cloud.setDuration((int) sp.getDuration().getSeconds());
|
||||
cloud.setSource(caster.bukkit());
|
||||
} else if (effect instanceof CompoundEffect sp) {
|
||||
final List<PotionEffect> effects = new ArrayList<>();
|
||||
for (PotionEffectType type : sp.getEffectTypes()) {
|
||||
PotionEffect e = type.createEffect((int) sp.getDuration().getSeconds(), (int) sp.getAmplifier());
|
||||
effects.add(e);
|
||||
}
|
||||
AreaEffectCloud cloud = (AreaEffectCloud) target.getWorld().spawnEntity(target, EntityType.AREA_EFFECT_CLOUD);
|
||||
for (PotionEffect e : effects) {
|
||||
cloud.addCustomEffect(e, true);
|
||||
}
|
||||
cloud.setRadius(2.5F);
|
||||
cloud.setDuration((int) sp.getDuration().getSeconds());
|
||||
cloud.setSource(caster.bukkit());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cast(LivingEntity target) {
|
||||
final Vector velocity = caster.bukkit().getEyeLocation().getDirection().multiply(2);
|
||||
final T launched = caster.bukkit().launchProjectile(getProjectileType(), velocity);
|
||||
|
||||
while (!launched.isDead()) {
|
||||
final double randomXOffset = Math.sin((Math.random() * 10 - 2) % Math.PI) * 5;
|
||||
final double randomYOffset = ((Math.random() * 10 - 2) % Math.PI) * 5;
|
||||
final double randomZOffset = Math.cos((Math.random() * 10 - 2) % (2 * Math.PI)) * 5;
|
||||
particles.forEach(particle -> launched.getWorld().spawnParticle(particle, launched.getLocation(), 1, randomXOffset, randomYOffset, randomZOffset));
|
||||
|
||||
if (launched.isOnGround()
|
||||
|| launched.isDead()
|
||||
|| launched.getTicksLived() > 100
|
||||
|| launched.getLocation().clone().equals(target)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final Effect effect = spell.getEffect();
|
||||
if (effect instanceof SpellEffect sp) {
|
||||
PotionEffect e = sp.getEffectType().createEffect((int) sp.getDuration().getSeconds(), (int) sp.getAmplifier());
|
||||
target.addPotionEffect(e);
|
||||
} else if (effect instanceof CompoundEffect sp) {
|
||||
final List<PotionEffect> effects = new ArrayList<>();
|
||||
for (PotionEffectType type : sp.getEffectTypes()) {
|
||||
PotionEffect e = type.createEffect((int) sp.getDuration().getSeconds(), (int) sp.getAmplifier());
|
||||
effects.add(e);
|
||||
}
|
||||
target.addPotionEffects(effects);
|
||||
} else if (effect instanceof SpecialEffect sp) {
|
||||
sp.applyEffect(target);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package app.simplexdev.arcanumocculta.cooldown;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CooldownService
|
||||
{
|
||||
private final Map<Caster, List<CooldownStatus>> cooldowns = new HashMap<>();
|
||||
|
||||
public void tick()
|
||||
{
|
||||
cooldowns.forEach((c, sl) -> {
|
||||
sl.removeIf(CooldownStatus::hasExpired);
|
||||
|
||||
if (sl.isEmpty()) cooldowns.remove(c);
|
||||
});
|
||||
}
|
||||
|
||||
public void include(final Caster caster, final CooldownStatus status)
|
||||
{
|
||||
List<CooldownStatus> statuses = cooldowns.get(caster);
|
||||
if (status == null) statuses = new ArrayList<>();
|
||||
|
||||
statuses.add(status);
|
||||
cooldowns.put(caster, statuses);
|
||||
}
|
||||
|
||||
public void exclude(final CooldownStatus status)
|
||||
{
|
||||
cooldowns.forEach((c, sl) -> sl.removeIf(s -> s.getSpellUUID().equals(status.getSpellUUID())));
|
||||
}
|
||||
|
||||
public boolean isOnCooldown(final Spell spell)
|
||||
{
|
||||
tick();
|
||||
return cooldowns.values()
|
||||
.stream()
|
||||
.flatMap(List::stream)
|
||||
.anyMatch(status -> status.getSpellUUID().equals(spell.getUniqueId()));
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package app.simplexdev.arcanumocculta.cooldown;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CooldownStatus
|
||||
{
|
||||
private final Duration duration;
|
||||
private final Instant currentTime;
|
||||
private final Instant endTime;
|
||||
private final UUID spellUUID;
|
||||
|
||||
public CooldownStatus(final UUID spellUUID, final Duration duration)
|
||||
{
|
||||
this.duration = duration;
|
||||
this.currentTime = Instant.now();
|
||||
this.endTime = this.currentTime.plus(duration);
|
||||
this.spellUUID = spellUUID;
|
||||
}
|
||||
|
||||
public UUID getSpellUUID()
|
||||
{
|
||||
return spellUUID;
|
||||
}
|
||||
|
||||
public boolean hasExpired()
|
||||
{
|
||||
return Instant.now().isAfter(this.endTime);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.spell;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.effect.SpellEffect;
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
import app.simplexdev.arcanumocculta.base.spell.AbstractSpell;
|
||||
import app.simplexdev.arcanumocculta.spell.effect.FireballEffect;
|
||||
import app.simplexdev.arcanumocculta.spell.projectile.FireballProjectile;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public final class FireballSpell extends AbstractSpell<FireballEffect> {
|
||||
private final Caster caster;
|
||||
|
||||
public FireballSpell(final Caster caster) {
|
||||
super("Fireball", "Fires a fireball in the direction you're facing.", new FireballEffect(Duration.ofSeconds(1), 1));
|
||||
this.caster = caster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FireballProjectile getSpellProjectile() {
|
||||
return new FireballProjectile(this, this.caster);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.spell.effect;
|
||||
|
||||
import app.simplexdev.arcanumocculta.base.effect.AbstractSpellEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class FireballEffect extends AbstractSpellEffect {
|
||||
public FireballEffect(Duration duration, float amplifier) {
|
||||
super(duration, amplifier, PotionEffectType.HARM);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package app.simplexdev.arcanumocculta.spell.projectile;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.player.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import app.simplexdev.arcanumocculta.base.spell.AbstractSpellProjectile;
|
||||
import app.simplexdev.arcanumocculta.spell.FireballSpell;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Fireball;
|
||||
|
||||
public class FireballProjectile extends AbstractSpellProjectile<Fireball> {
|
||||
public FireballProjectile(FireballSpell spell,
|
||||
Caster caster) {
|
||||
super(spell, caster, Fireball.class, Particle.FLAME, Particle.SMALL_FLAME, Particle.LAVA);
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.spells;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.AbstractSpellBook;
|
||||
import app.simplexdev.arcanumocculta.api.spell.AbstractSpell;
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import app.simplexdev.arcanumocculta.util.SpellUtils;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.Scanners;
|
||||
|
||||
public class PrimarySpellList extends AbstractSpellBook
|
||||
{
|
||||
public PrimarySpellList()
|
||||
{
|
||||
Set<Class<? extends AbstractSpell>> spellClasses = m0().getSubTypesOf(AbstractSpell.class);
|
||||
final Set<Spell> v0 = new HashSet<>();
|
||||
spellClasses.forEach(spellClass ->
|
||||
{
|
||||
try
|
||||
{
|
||||
final Spell spell = spellClass.getDeclaredConstructor().newInstance();
|
||||
v0.add(spell);
|
||||
}
|
||||
catch (ReflectiveOperationException e)
|
||||
{
|
||||
Bukkit.getLogger().severe(e.getMessage());
|
||||
}
|
||||
});
|
||||
this.addAll(v0);
|
||||
}
|
||||
|
||||
private Reflections m0()
|
||||
{
|
||||
final Reflections v0 = new Reflections(SpellUtils.SPELL_PACKAGE + ".flame",
|
||||
Scanners.SubTypes);
|
||||
final Reflections v1 = new Reflections(SpellUtils.SPELL_PACKAGE + ".soul",
|
||||
Scanners.SubTypes);
|
||||
final Reflections v2 = new Reflections(SpellUtils.SPELL_PACKAGE + ".wither", Scanners.SubTypes);
|
||||
|
||||
return v0.merge(v1).merge(v2);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package app.simplexdev.arcanumocculta.spells.soul;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.spell.AbstractSpell;
|
||||
import app.simplexdev.arcanumocculta.api.spell.SpellEffect;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Damages;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Durations;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.ManaCosts;
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import app.simplexdev.arcanumocculta.util.SpellUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public final class SoulPebble extends AbstractSpell
|
||||
{
|
||||
public SoulPebble()
|
||||
{
|
||||
super("Soul Pebble",
|
||||
"soul_pebble",
|
||||
"Fires a small soul pebble",
|
||||
CasterLevel.APPRENTICE,
|
||||
Damages.MINIMAL,
|
||||
Durations.INSTANT,
|
||||
ManaCosts.MINIMAL_CAST,
|
||||
5L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellEffect[] getSpellEffects()
|
||||
{
|
||||
final SpellEffect[] effects = new SpellEffect[1];
|
||||
effects[0] = SpellUtils.soulEffectBase(baseDamage());
|
||||
return effects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cast(Caster caster, Wand wand)
|
||||
{
|
||||
if (!this.checkManaCosts(caster))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Entity projectile = prepareProjectile(caster, Material.AIR);
|
||||
|
||||
while (!projectile.isOnGround() || !projectile.isDead())
|
||||
{
|
||||
tracer(projectile.getWorld(), projectile.getLocation(), Particle.SOUL);
|
||||
|
||||
if (!projectile.getNearbyEntities(1, 1, 1).isEmpty())
|
||||
{
|
||||
applyEffects(projectile.getNearbyEntities(1, 1, 1),
|
||||
caster);
|
||||
projectile.remove();
|
||||
}
|
||||
|
||||
if (projectile.isOnGround())
|
||||
projectile.remove();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.spells.soul;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.spell.AbstractSpell;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Damages;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Durations;
|
||||
import app.simplexdev.arcanumocculta.api.spell.SpellEffect;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.ManaCosts;
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import app.simplexdev.arcanumocculta.util.SpellUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public final class SoulShard extends AbstractSpell
|
||||
{
|
||||
public SoulShard()
|
||||
{
|
||||
super("Soul Shard",
|
||||
"soul_shard",
|
||||
"A larger version of soul pebble.",
|
||||
CasterLevel.APPRENTICE, Damages.LIGHT,
|
||||
Durations.INSTANT, ManaCosts.LIGHT_CAST,
|
||||
5L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellEffect[] getSpellEffects()
|
||||
{
|
||||
final SpellEffect[] effects = new SpellEffect[1];
|
||||
effects[0] = SpellUtils.soulEffectBase(baseDamage());
|
||||
return effects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cast(Caster caster, Wand wand)
|
||||
{
|
||||
if (!this.checkManaCosts(caster))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Entity projectile = prepareProjectile(caster, Material.AIR);
|
||||
|
||||
while (!projectile.isDead()) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tracer(projectile.getWorld(), projectile.getLocation(), Particle.SOUL);
|
||||
}
|
||||
|
||||
if (!projectile.getNearbyEntities(1, 1, 1).isEmpty())
|
||||
{
|
||||
applyEffects(projectile.getNearbyEntities(1, 1, 1),
|
||||
caster);
|
||||
projectile.remove();
|
||||
}
|
||||
|
||||
if (projectile.isOnGround()) {
|
||||
projectile.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package app.simplexdev.arcanumocculta.storage.local;
|
||||
|
||||
import app.simplexdev.arcanumocculta.ArcanumOcculta;
|
||||
import app.simplexdev.arcanumocculta.api.caster.Caster;
|
||||
import app.simplexdev.arcanumocculta.api.caster.CasterLevel;
|
||||
import app.simplexdev.arcanumocculta.api.caster.SpellBook;
|
||||
import app.simplexdev.arcanumocculta.api.wand.CapType;
|
||||
import app.simplexdev.arcanumocculta.api.wand.CoreType;
|
||||
import app.simplexdev.arcanumocculta.api.wand.GemType;
|
||||
import app.simplexdev.arcanumocculta.api.wand.Wand;
|
||||
import app.simplexdev.arcanumocculta.base.SimpleCaster;
|
||||
import app.simplexdev.arcanumocculta.base.SimpleSpellBook;
|
||||
import app.simplexdev.arcanumocculta.base.SimpleWand;
|
||||
import app.simplexdev.arcanumocculta.util.SpellUtils;
|
||||
import java.util.List;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class PlayerYaml
|
||||
{
|
||||
private final YamlHolder yamlHolder;
|
||||
|
||||
public PlayerYaml(final ArcanumOcculta plugin, final String name)
|
||||
{
|
||||
this.yamlHolder = new YamlHolder(plugin, "player-default.yml", name, plugin.getDataFolder(), false);
|
||||
}
|
||||
|
||||
public YamlHolder getYamlHolder()
|
||||
{
|
||||
return yamlHolder;
|
||||
}
|
||||
|
||||
public Wand retrieveWand()
|
||||
{
|
||||
ConfigurationSection wandSection = yamlHolder.getConfigurationSection("wand");
|
||||
String name = wandSection.getString("name");
|
||||
String description = wandSection.getString("description");
|
||||
Material material = Material.getMaterial(wandSection.getString("item"));
|
||||
CoreType core = CoreType.valueOf(wandSection.getString("core"));
|
||||
CapType cap = CapType.valueOf(wandSection.getString("cap"));
|
||||
ItemStack item = new ItemStack(material, 1);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null)
|
||||
{
|
||||
meta.setDisplayName(name);
|
||||
meta.setLore(List.of(description));
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
GemType gem = GemType.valueOf(wandSection.getString("gem"));
|
||||
return new SimpleWand(name, description, item, cap, core, gem);
|
||||
}
|
||||
|
||||
public void saveWand(final Wand wand)
|
||||
{
|
||||
ConfigurationSection wandSection = yamlHolder.getConfigurationSection("wand");
|
||||
wandSection.set("name", wand.getName());
|
||||
wandSection.set("description", wand.getDescription());
|
||||
wandSection.set("item", wand.getItem().getType().name());
|
||||
wandSection.set("core", wand.getCoreType().name());
|
||||
wandSection.set("cap", wand.getCapType().name());
|
||||
wandSection.set("gem", wand.getGemType().name());
|
||||
yamlHolder.save();
|
||||
}
|
||||
|
||||
public Caster fetchCaster(final Player player)
|
||||
{
|
||||
ConfigurationSection caster = yamlHolder.getConfigurationSection("caster");
|
||||
CasterLevel level = CasterLevel.fromOrdinal(caster.getInt("caster_rank"));
|
||||
double xp = caster.getDouble("current_experience");
|
||||
double currentMana = caster.getDouble("current_mana");
|
||||
double maxMana = caster.getDouble("max_mana");
|
||||
|
||||
final Wand wand = retrieveWand();
|
||||
final SpellBook spellBook = retrieveSpellBook();
|
||||
Caster c = new SimpleCaster(player, wand, spellBook, level);
|
||||
c.setCurrentExperience(xp);
|
||||
c.setCurrentMana(currentMana);
|
||||
c.setMaxMana(maxMana);
|
||||
return c;
|
||||
}
|
||||
|
||||
public SpellBook retrieveSpellBook()
|
||||
{
|
||||
final SpellBook book = new SimpleSpellBook();
|
||||
List<String> spellBook = yamlHolder.getStringList("spellbook");
|
||||
for (String spell : spellBook)
|
||||
{
|
||||
book.addSpell(SpellUtils.copyFromPrimaryList(spell));
|
||||
}
|
||||
return book;
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package app.simplexdev.arcanumocculta.storage.local;
|
||||
|
||||
import app.simplexdev.arcanumocculta.ArcanumOcculta;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class YamlHolder
|
||||
{
|
||||
private final YamlConfiguration configuration;
|
||||
private final ArcanumOcculta plugin;
|
||||
|
||||
public YamlHolder(final ArcanumOcculta plugin, final String resourceLocation, final String fileName,
|
||||
final File parentFolder,
|
||||
final boolean copyDefaults)
|
||||
{
|
||||
final File file = new File(parentFolder, fileName);
|
||||
this.plugin = plugin;
|
||||
|
||||
try
|
||||
{
|
||||
if (file.createNewFile() || copyDefaults)
|
||||
{
|
||||
final String creatingFile = String.format("Creating %s...", fileName);
|
||||
plugin.getLogger().info(creatingFile);
|
||||
plugin.saveResource(resourceLocation, true);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
plugin.getLogger().severe(ex.getMessage());
|
||||
}
|
||||
|
||||
this.configuration = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
public String getString(final String path)
|
||||
{
|
||||
return this.configuration.getString(path);
|
||||
}
|
||||
|
||||
public boolean getBoolean(final String path)
|
||||
{
|
||||
return this.configuration.getBoolean(path);
|
||||
}
|
||||
|
||||
public int getInt(final String path)
|
||||
{
|
||||
return this.configuration.getInt(path);
|
||||
}
|
||||
|
||||
public double getDouble(final String path)
|
||||
{
|
||||
return this.configuration.getDouble(path);
|
||||
}
|
||||
|
||||
public ConfigurationSection getConfigurationSection(final String path)
|
||||
{
|
||||
return this.configuration.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
public List<String> getStringList(final String path)
|
||||
{
|
||||
return this.configuration.getStringList(path);
|
||||
}
|
||||
|
||||
public void set(final String path, final Object value)
|
||||
{
|
||||
this.configuration.set(path, value);
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.configuration.save(this.configuration.getCurrentPath());
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
final String message = MessageFormat.format("Failed to save {0}!", this.configuration.getCurrentPath());
|
||||
plugin.getLogger().severe(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.configuration.load(this.configuration.getCurrentPath());
|
||||
}
|
||||
catch (IOException | org.bukkit.configuration.InvalidConfigurationException ex)
|
||||
{
|
||||
final String message = MessageFormat.format("Failed to load {0}!", this.configuration.getCurrentPath());
|
||||
plugin.getLogger().severe(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
this.save();
|
||||
this.load();
|
||||
}
|
||||
}
|
168
src/main/java/app/simplexdev/arcanumocculta/util/SpellUtils.java
Normal file
168
src/main/java/app/simplexdev/arcanumocculta/util/SpellUtils.java
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Simplex Development Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* with the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package app.simplexdev.arcanumocculta.util;
|
||||
|
||||
import app.simplexdev.arcanumocculta.api.spell.Spell;
|
||||
import app.simplexdev.arcanumocculta.api.spell.SpellEffect;
|
||||
import app.simplexdev.arcanumocculta.api.spell.enums.Damages;
|
||||
import app.simplexdev.arcanumocculta.spells.PrimarySpellList;
|
||||
import java.util.SplittableRandom;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.Damageable;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public final class SpellUtils
|
||||
{
|
||||
public static final String SPELL_PACKAGE = PrimarySpellList.class.getPackageName();
|
||||
private static final PrimarySpellList primarySpellList = new PrimarySpellList();
|
||||
private static final SplittableRandom RANDOM = new SplittableRandom();
|
||||
|
||||
private SpellUtils()
|
||||
{
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static void damage(final Damageable target, final LivingEntity damager, final double damage)
|
||||
{
|
||||
if (target instanceof Player)
|
||||
target.damage(damage % 20.0, damager);
|
||||
else
|
||||
target.damage(damage);
|
||||
}
|
||||
|
||||
public static Spell copyFromPrimaryList(final String id)
|
||||
{
|
||||
return SpellUtils.primarySpellList.getSpell(id).dupe();
|
||||
}
|
||||
|
||||
public static SpellEffect soulEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
if (target instanceof Player player)
|
||||
// Player is freezing when hit, as if they were in powdered snow for 1 minute.
|
||||
player.setFreezeTicks(1200);
|
||||
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect flameEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Fire ticks for 15 seconds.
|
||||
target.setFireTicks(300);
|
||||
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect witherEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Wither for 10 seconds.
|
||||
target.addPotionEffect(PotionEffectType.WITHER.createEffect(200, 2));
|
||||
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect lightningEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Lightning on target
|
||||
target.getWorld().strikeLightning(target.getLocation());
|
||||
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect healEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Heal target
|
||||
target.setHealth(target.getHealth() + damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect regenEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Regen target
|
||||
target.addPotionEffect(PotionEffectType.REGENERATION.createEffect(300, 3));
|
||||
target.setHealth(target.getHealth() + ((target.getHealth() + damage) / 2));
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect meteorLikeEffectBase(final Damages baseDamage,
|
||||
final Vector incomingVelocity,
|
||||
final float size)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Meteor like effect
|
||||
// TODO: Make a configuration option to enable/disable explosions destroying blocks.
|
||||
target.getWorld().createExplosion(target.getLocation(), size, true, false);
|
||||
target.setVelocity(incomingVelocity.normalize().multiply(2).multiply(-1));
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
|
||||
public static SpellEffect arsLikeEffectBase(final Damages baseDamage)
|
||||
{
|
||||
return (target, caster) ->
|
||||
{
|
||||
final var damage = baseDamage.multiply(caster.getWand().getSpellBonus());
|
||||
// Ars Magica like effect
|
||||
target.setVelocity(caster.bukkit().getLocation().clone().getDirection().multiply(2));
|
||||
if (target instanceof Player player)
|
||||
player.setFreezeTicks(1200);
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
target.getWorld().spawnParticle(Particle.SOUL_FIRE_FLAME,
|
||||
target.getLocation(),
|
||||
0,
|
||||
RANDOM.nextDouble(-2, 2),
|
||||
RANDOM.nextDouble(-2, 2),
|
||||
RANDOM.nextDouble(-2, 2));
|
||||
}
|
||||
|
||||
damage(target, caster.bukkit(), damage);
|
||||
};
|
||||
}
|
||||
}
|
18
src/main/resources/player-default.yml
Normal file
18
src/main/resources/player-default.yml
Normal file
@ -0,0 +1,18 @@
|
||||
caster:
|
||||
caster_rank: 1
|
||||
current_experience: 0
|
||||
current_mana: 100
|
||||
max_mana: 100
|
||||
spell_influence: 0
|
||||
spell_points: 0
|
||||
|
||||
spellbook:
|
||||
- FIREBALL
|
||||
|
||||
wand:
|
||||
name: Basic Wand
|
||||
description: A basic wand
|
||||
item: STICK
|
||||
core: WOOD
|
||||
gem: NONE
|
||||
cap: IRON
|
@ -3,3 +3,5 @@ version: '${version}'
|
||||
main: app.simplexdev.arcanumocculta.ArcanumOcculta
|
||||
api-version: '1.20'
|
||||
load: STARTUP
|
||||
libraries:
|
||||
- org.reflections:reflections:0.10.2
|
||||
|
Loading…
Reference in New Issue
Block a user