forked from Upstream/mmocore
upload src
This commit is contained in:
parent
196ffd2c78
commit
dfa6b68ce9
69
config.yml
Normal file
69
config.yml
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
# Wearing heavy pieces of armors reduces
|
||||
# your movement speed by a specific amount,
|
||||
# relative to your current move speed.
|
||||
heavy-armors:
|
||||
|
||||
# The movement speed reduction in % for each heavy armor piece worn.
|
||||
speed-malus: 5.0
|
||||
|
||||
# The list of heavy armor pieces. By default gold is not
|
||||
# considered a heavy armor to incite players to use this armor set.
|
||||
list:
|
||||
- DIAMOND_HELMET
|
||||
- DIAMOND_CHESTPLATE
|
||||
- DIAMOND_LEGGINGS
|
||||
- DIAMOND_BOOTS
|
||||
- IRON_HELMET
|
||||
- IRON_CHESTPLATE
|
||||
- IRON_LEGGINGS
|
||||
- IRON_BOOTS
|
||||
|
||||
# The list of all conditions which must be met for the
|
||||
# BLOCK REGEN and BLOCK RESTRICTIONS to apply.
|
||||
# Set to 'custom-min-conditions: []' for no condition.
|
||||
custom-mine-conditions:
|
||||
- 'world{name="world1,world2,world_nether,world_the_end"}'
|
||||
- 'region{name="region1,region2,__global__"}'
|
||||
|
||||
# Offset is the distance traveled on X and Y coordinates
|
||||
# Height is the Y velocity coordinate. Lootsplosions
|
||||
# only trigger with MythicMobs monsters.
|
||||
# Requires a SERVER reload when changed.
|
||||
lootsplosion:
|
||||
enabled: true
|
||||
mmoitems-color: true
|
||||
offset: .2
|
||||
height: .6
|
||||
|
||||
party:
|
||||
|
||||
# Edit party buffs here. You may
|
||||
# add as many stats as you want.
|
||||
buff:
|
||||
health-regeneration: 3%
|
||||
additional-experience: 5%
|
||||
|
||||
# Prefix you need to put in the chat
|
||||
# to talk in the party chat.
|
||||
chat-prefix: '@'
|
||||
|
||||
# Enable this open to override vanilla EXP and display
|
||||
# level progress on the vanilla experience bar.
|
||||
# Requires a SERVER reload when changed.
|
||||
override-vanilla-exp: true
|
||||
|
||||
# Allows to scale health up/down to a specific
|
||||
# amount so extra health does not fill up the screen.
|
||||
# Requires a SERVER reload when changed.
|
||||
health-scale:
|
||||
enabled: true
|
||||
scale: 40
|
||||
|
||||
# Players can swap their hotbar with the 9 inventory slots
|
||||
# right above it by pressing [swap items] while crouching.
|
||||
hotbar-swap: true
|
||||
|
||||
# Use this option if you're having issue with Anvil GUIs.
|
||||
# This replaces anvil inputs by chat inputs.
|
||||
use-chat-input: true
|
30
default/attributes.yml
Normal file
30
default/attributes.yml
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
# Attribute ID
|
||||
strength:
|
||||
|
||||
name: Strength
|
||||
|
||||
# Maximum amount of points players
|
||||
# may spend in this attribute.
|
||||
max-points: 40
|
||||
|
||||
# Buffs given every 1 attribute point spent
|
||||
# in this specific attribute.
|
||||
buff:
|
||||
weapon_damage: 2
|
||||
max_health: 1%
|
||||
|
||||
dexterity:
|
||||
name: Dexterity
|
||||
max-points: 40
|
||||
buff:
|
||||
physical_damage: 1.5
|
||||
projectile_damage: 1
|
||||
attack_speed: 0.5%
|
||||
|
||||
intelligence:
|
||||
name: Intelligence
|
||||
max-points: 40
|
||||
buff:
|
||||
magical_damage: 2
|
||||
cooldown_reduction: 1
|
24
default/chests.yml
Normal file
24
default/chests.yml
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
'world 59 71 131':
|
||||
|
||||
# Create directly your drop table here.
|
||||
drop-table:
|
||||
items:
|
||||
- 'vanilla{type=DIAMOND} 1 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'gold{} .9 1-3'
|
||||
- 'note{min=1;max=10} .9 1-3'
|
||||
|
||||
# Ticks the chest takes to appear again.
|
||||
regen-time: 40
|
||||
|
||||
# The particle played every 4sec around the chest.
|
||||
# Types available: helix|offset|galaxy
|
||||
# Particle names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
|
||||
effect:
|
||||
type: helix
|
||||
particle: FLAME
|
103
default/classes/arcane-mage.yml
Normal file
103
default/classes/arcane-mage.yml
Normal file
@ -0,0 +1,103 @@
|
||||
options:
|
||||
display: false
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
display:
|
||||
name: 'Arcane Mage'
|
||||
lore:
|
||||
- 'The Mage has mastered the power of the'
|
||||
- 'Arcanes, taking down any enemy on his path'
|
||||
- 'using powerful magic & ranged abilities.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Mana Regeneration'
|
||||
- '&a+ &7Health Regeneration'
|
||||
- '&a+ &7Max Mana'
|
||||
- '&c- &7Max Health'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c1 &7(+&c0&7)'
|
||||
- '&7 Attack Speed: &c4 &7(+&c0&7)'
|
||||
- '&7 Max Health: &c18 &7(+&c0&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a0% &7(+&a0%&7)'
|
||||
- '&7 Movement Speed: &a20 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a0% &7(+&a0%&7)'
|
||||
- ''
|
||||
- '&8&lIntellect'
|
||||
- '&7 Max Mana: &930 &7(+&91.3&7)'
|
||||
- '&7 Health Regen: &90.13 &7(+&90&7)'
|
||||
- '&7 Mana Regen: &90.2 &7(+&90.04&7)'
|
||||
item: BLAZE_POWDER:1 # Supports custom model data/texture by durability
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
attributes:
|
||||
max-health:
|
||||
base: 18
|
||||
per-level: 0
|
||||
max-mana:
|
||||
base: 30
|
||||
per-level: 1.3
|
||||
mana-regeneration:
|
||||
base: .2
|
||||
per-level: .04
|
||||
health-regeneration:
|
||||
base: 0.13
|
||||
per-level: 0
|
||||
|
||||
skills:
|
||||
FIRE_STORM:
|
||||
level: 1
|
||||
max-level: 30
|
||||
damage:
|
||||
base: 8.0
|
||||
per-level: 4.0
|
||||
ignite:
|
||||
base: 2.0
|
||||
per-level: 0.1
|
||||
mana:
|
||||
base: 15.0
|
||||
per-level: 2.0
|
||||
cooldown:
|
||||
base: 5.0
|
||||
per-level: -0.1
|
||||
max: 5.0
|
||||
min: 1.0
|
||||
|
||||
POWER_MARK:
|
||||
level: 3
|
||||
max-level: 30
|
||||
FIREBALL:
|
||||
level: 5
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 6
|
||||
max-level: 30
|
||||
ICE_SPIKES:
|
||||
level: 8
|
||||
max-level: 30
|
||||
AMBERS:
|
||||
level: 9
|
||||
max-level: 30
|
||||
WEAKEN:
|
||||
level: 10
|
||||
max-level: 30
|
||||
WARP:
|
||||
level: 13
|
||||
max-level: 30
|
||||
GREATER_HEALINGS:
|
||||
level: 15
|
||||
max-level: 30
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
32
default/classes/human.yml
Normal file
32
default/classes/human.yml
Normal file
@ -0,0 +1,32 @@
|
||||
display:
|
||||
name: 'Human'
|
||||
|
||||
options:
|
||||
default: true
|
||||
display: false
|
||||
|
||||
# Health/mana regen scales on missing health/mana
|
||||
missing-health-regen: false
|
||||
missing-mana-regen: false
|
||||
|
||||
# Resource regen scales on max mana/health
|
||||
max-health-regen: false
|
||||
max-mana-regen: false
|
||||
|
||||
# Only regens when out of combat
|
||||
off-combat-health-regen: false
|
||||
off-combat-mana-regen: false
|
||||
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
113
default/classes/mage.yml
Normal file
113
default/classes/mage.yml
Normal file
@ -0,0 +1,113 @@
|
||||
display:
|
||||
name: 'Mage'
|
||||
lore:
|
||||
- 'The Mage has mastered the power of the'
|
||||
- 'Arcanes, taking down any enemy on his path'
|
||||
- 'using powerful magic & ranged abilities.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Mana Regeneration'
|
||||
- '&a+ &7Health Regeneration'
|
||||
- '&a+ &7Max Mana'
|
||||
- '&c- &7Max Health'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c1 &7(+&c0&7)'
|
||||
- '&7 Attack Speed: &c4 &7(+&c0&7)'
|
||||
- '&7 Max Health: &c18 &7(+&c0&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a0% &7(+&a0%&7)'
|
||||
- '&7 Movement Speed: &a20 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a0% &7(+&a0%&7)'
|
||||
- ''
|
||||
- '&8&lIntellect'
|
||||
- '&7 Max Mana: &927 &7(+&91.2&7)'
|
||||
- '&7 Health Regen: &90.13 &7(+&90&7)'
|
||||
- '&7 Mana Regen: &90.2 &7(+&90.04&7)'
|
||||
item: BLAZE_POWDER
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
|
||||
cast-particle:
|
||||
particle: SPELL_INSTANT
|
||||
|
||||
options:
|
||||
off-combat-health-regen: true
|
||||
|
||||
attributes:
|
||||
max-health:
|
||||
base: 18
|
||||
per-level: 0
|
||||
max-mana:
|
||||
base: 27
|
||||
per-level: 1.2
|
||||
mana-regeneration:
|
||||
base: .2
|
||||
per-level: .04
|
||||
health-regeneration:
|
||||
base: 0.13
|
||||
per-level: 0
|
||||
|
||||
subclasses:
|
||||
ARCANE_MAGE: 10
|
||||
|
||||
skills:
|
||||
FIRE_STORM:
|
||||
level: 1
|
||||
max-level: 30
|
||||
|
||||
# Specific skill modifiers based on class.
|
||||
# Arcane mage's fire storm may deal more damage
|
||||
# than an apprentice mage's fire storm.
|
||||
damage:
|
||||
base: 5.0
|
||||
per-level: 3.0
|
||||
ignite:
|
||||
base: 2.0
|
||||
per-level: 0.1
|
||||
mana:
|
||||
base: 15.0
|
||||
per-level: 2.0
|
||||
cooldown:
|
||||
base: 5.0
|
||||
per-level: -0.1
|
||||
max: 5.0
|
||||
min: 1.0
|
||||
POWER_MARK:
|
||||
level: 3
|
||||
max-level: 30
|
||||
FIREBALL:
|
||||
level: 5
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 6
|
||||
max-level: 30
|
||||
ICE_SPIKES:
|
||||
level: 8
|
||||
AMBERS:
|
||||
level: 9
|
||||
max-level: 30
|
||||
WEAKEN:
|
||||
level: 10
|
||||
max-level: 30
|
||||
WARP:
|
||||
level: 13
|
||||
max-level: 30
|
||||
GREATER_HEALINGS:
|
||||
level: 15
|
||||
max-level: 30
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
74
default/classes/marksman.yml
Normal file
74
default/classes/marksman.yml
Normal file
@ -0,0 +1,74 @@
|
||||
display:
|
||||
name: 'Marksman'
|
||||
lore:
|
||||
- 'The marksman is a swift and accurate'
|
||||
- 'ranged fighter, never missing any arrow.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Knockback Resistance'
|
||||
- '&a+ &7Speed Malus Reduction'
|
||||
- '&c- &7Max Health'
|
||||
- '&c- &7Movement Speed'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c1 &7(+&c0&7)'
|
||||
- '&7 Attack Speed: &c4 &7(+&c0&7)'
|
||||
- '&7 Max Health: &c18 &7(+&c0&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a15% &7(+&a1%&7)'
|
||||
- '&7 Movement Speed: &a21 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a10% &7(+&a2%&7)'
|
||||
- ''
|
||||
- '&8&lIntellect'
|
||||
- '&7 Max Mana: &920 &7(+&90&7)'
|
||||
- '&7 Health Regen: &90.1 &7(+&90&7)'
|
||||
- '&7 Mana Regen: &90.166 &7(+&90&7)'
|
||||
item: BOW
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
|
||||
cast-particle:
|
||||
particle: CRIT
|
||||
|
||||
skills:
|
||||
WEAKEN:
|
||||
level: 3
|
||||
max-level: 30
|
||||
COMBO_ATTACK:
|
||||
level: 7
|
||||
max-level: 30
|
||||
EVADE:
|
||||
level: 9
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 10
|
||||
max-level: 30
|
||||
|
||||
attributes:
|
||||
knockback-resistance:
|
||||
base: 15
|
||||
per-level: 1
|
||||
speed-malus-reduction:
|
||||
base: 10
|
||||
per-level: 2
|
||||
max-health:
|
||||
base: 18
|
||||
per-level: 0
|
||||
movement-speed:
|
||||
base: .21
|
||||
per-level: 0
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
89
default/classes/paladin.yml
Normal file
89
default/classes/paladin.yml
Normal file
@ -0,0 +1,89 @@
|
||||
display:
|
||||
name: 'Paladin'
|
||||
lore:
|
||||
- 'The paladin is a heavy tanky fighter'
|
||||
- 'who uses his mana to heal and protect'
|
||||
- 'members from his team.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Max Health'
|
||||
- '&a+ &7Knockback Resistance'
|
||||
- '&a+ &7Speed Malus Reduction'
|
||||
- '&c- &7Movement Speed'
|
||||
- '&c- &7Attack Speed'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c1 &7(+&c0&7)'
|
||||
- '&7 Attack Speed: &c3.7 &7(+&c0&7)'
|
||||
- '&7 Max Health: &c22 &7(+&c.3&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a30% &7(+&a1%&7)'
|
||||
- '&7 Movement Speed: &a19 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a30% &7(+&a2%&7)'
|
||||
- ''
|
||||
- '&8&lIntellect'
|
||||
- '&7 Max Mana: &920 &7(+&90&7)'
|
||||
- '&7 Health Regen: &90.1 &7(+&90&7)'
|
||||
- '&7 Mana Regen: &90.166 &7(+&90&7)'
|
||||
item: ENCHANTED_GOLDEN_APPLE:0 # Supports custom model data/texture by durability
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
# Get some mana back when dealing magic damage.
|
||||
magic-damage:
|
||||
- 'mana{operation=GIVE;amount=1}'
|
||||
|
||||
cast-particle:
|
||||
particle: VILLAGER_HAPPY
|
||||
|
||||
skills:
|
||||
DEEP_WOUND:
|
||||
level: 10
|
||||
max-level: 30
|
||||
WEAKEN:
|
||||
level: 5
|
||||
max-level: 30
|
||||
AMBERS:
|
||||
level: 15
|
||||
max-level: 30
|
||||
GREATER_HEALINGS:
|
||||
level: 7
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 3
|
||||
max-level: 30
|
||||
HUMAN_SHIELD:
|
||||
level: 13
|
||||
max-level: 20
|
||||
|
||||
attributes:
|
||||
knockback-resistance:
|
||||
base: 30
|
||||
per-level: 1
|
||||
speed-malus-reduction:
|
||||
base: 30
|
||||
per-level: 2
|
||||
max-health:
|
||||
base: 22
|
||||
per-level: 0.3
|
||||
attack-speed:
|
||||
base: 3.7
|
||||
per-level: 0
|
||||
movement-speed:
|
||||
base: .19
|
||||
per-level: 0
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
88
default/classes/rogue.yml
Normal file
88
default/classes/rogue.yml
Normal file
@ -0,0 +1,88 @@
|
||||
display:
|
||||
name: 'Rogue'
|
||||
lore:
|
||||
- 'His important damage burst potential and'
|
||||
- 'his lack of health forces him to one'
|
||||
- 'shot his targets before being taken down.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Attack Speed'
|
||||
- '&c- &7Max Health'
|
||||
- '&c- &7Movement Speed'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c1 &7(+&c0&7)'
|
||||
- '&7 Attack Speed: &c4.2 &7(+&c0.05&7)'
|
||||
- '&7 Max Health: &c18 &7(+&c0&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a0% &7(+&a0%&7)'
|
||||
- '&7 Movement Speed: &a21 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a0% &7(+&a0%&7)'
|
||||
- ''
|
||||
- '&8&lIntellect'
|
||||
- '&7 Max Mana: &920 &7(+&90&7)'
|
||||
- '&7 Health Regen: &90.1 &7(+&90&7)'
|
||||
- '&7 Mana Regen: &90.166 &7(+&90&7)'
|
||||
item: LEATHER_BOOTS
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
triggers:
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
options:
|
||||
off-combat-mana-regen: true
|
||||
off-combat-health-regen: true
|
||||
missing-health-regen: true
|
||||
|
||||
cast-particle:
|
||||
particle: SPELL_WITCH
|
||||
|
||||
mana:
|
||||
char: ■
|
||||
color: BLUE
|
||||
name: 'Mana'
|
||||
|
||||
skills:
|
||||
DEEP_WOUND:
|
||||
level: 1
|
||||
max-level: 30
|
||||
WEAKEN:
|
||||
level: 3
|
||||
max-level: 30
|
||||
EMPOWERED_ATTACK:
|
||||
level: 5
|
||||
max-level: 30
|
||||
COMBO_ATTACK:
|
||||
level: 7
|
||||
max-level: 30
|
||||
EVADE:
|
||||
level: 9
|
||||
max-level: 30
|
||||
FURTIVE_STRIKE:
|
||||
level: 4
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 10
|
||||
max-level: 30
|
||||
SNEAKY_PICKY:
|
||||
level: 2
|
||||
max-level: 20
|
||||
|
||||
attributes:
|
||||
attack-speed:
|
||||
base: 4.2
|
||||
per-level: 0.05
|
||||
max-health:
|
||||
base: 18
|
||||
per-level: 0
|
||||
movement-speed:
|
||||
base: .21
|
||||
per-level: 0
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
111
default/classes/warrior.yml
Normal file
111
default/classes/warrior.yml
Normal file
@ -0,0 +1,111 @@
|
||||
display:
|
||||
name: 'Warrior'
|
||||
lore:
|
||||
- 'The warrior has extraordinary fighting and'
|
||||
- 'evolving capabilities, which grant him much'
|
||||
- 'higher per-level stats than other classes.'
|
||||
- ''
|
||||
- 'The warrior collects rage when casting skills,'
|
||||
- 'temporarily increasing his base damage.'
|
||||
attribute-lore:
|
||||
- '&a+ &7Attack Damage'
|
||||
- '&a+ &7Attack Speed'
|
||||
- '&a+ &7Max Health'
|
||||
- '&a+ &7Speed Malus Reduction'
|
||||
- '&c- &7Movement Speed'
|
||||
- ''
|
||||
- '&8&lStrength'
|
||||
- '&7 Attack Damage: &c2 &7(+&c0.1&7)'
|
||||
- '&7 Attack Speed: &c4.2 &7(+&c0.05&7)'
|
||||
- '&7 Max Health: &c24 &7(+&c0.5&7)'
|
||||
- ''
|
||||
- '&8&lDexterity'
|
||||
- '&7 Knockback Resistance: &a0% &7(+&a0%&7)'
|
||||
- '&7 Movement Speed: &a19 &7(+&a0&7)'
|
||||
- '&7 Speed Malus Reduction: &a40% &7(+&a2%&7)'
|
||||
- ''
|
||||
- '&8&lWill'
|
||||
- '&7 Max Rage: &c20 &7(+&c1&7)'
|
||||
- '&7 Health Regen: &90.1 &7(+&90&7)'
|
||||
- '&7 Rage Degeneration: &9-0.5&7/s'
|
||||
item: IRON_SWORD:0 # Supports custom model data/texture by durability
|
||||
|
||||
# Players cannot go further than Lvl 100
|
||||
max-level: 100
|
||||
|
||||
# Warrior has rage which he gains while casting spells
|
||||
# Rage increase its skill damage. Use <mmocore.rage>
|
||||
# to get the player's rage (MythicMobs formulas)
|
||||
mana:
|
||||
char: ♦
|
||||
color: RED
|
||||
name: 'Rage'
|
||||
|
||||
# Rage charges when dealing weapon and physical damage.
|
||||
triggers:
|
||||
weapon-damage:
|
||||
- 'mana{operation=GIVE;amount=2-3}'
|
||||
physical-damage:
|
||||
- 'mana{operation=GIVE;amount=2-3}'
|
||||
|
||||
level-up:
|
||||
- 'command{format="mmocore admin skill-points %player% 1"}'
|
||||
|
||||
cast-particle:
|
||||
particle: REDSTONE
|
||||
color:
|
||||
red: 255
|
||||
green: 0
|
||||
blue: 0
|
||||
|
||||
# Rage only decays when out of combat
|
||||
options:
|
||||
off-combat-mana-regen: true
|
||||
|
||||
skills:
|
||||
DEEP_WOUND:
|
||||
level: 1
|
||||
max-level: 30
|
||||
WEAKEN:
|
||||
level: 3
|
||||
max-level: 30
|
||||
EMPOWERED_ATTACK:
|
||||
level: 5
|
||||
max-level: 30
|
||||
COMBO_ATTACK:
|
||||
level: 7
|
||||
max-level: 30
|
||||
MINOR_HEALINGS:
|
||||
level: 10
|
||||
max-level: 30
|
||||
FIRE_BERSERKER:
|
||||
level: 15
|
||||
|
||||
attributes:
|
||||
mana-regeneration:
|
||||
base: -0.5
|
||||
per-level: 0
|
||||
speed-malus-reduction:
|
||||
base: 50
|
||||
per-level: 2
|
||||
max-mana:
|
||||
base: 20
|
||||
per-level: 1
|
||||
max-health:
|
||||
base: 24
|
||||
per-level: 0.5
|
||||
movement-speed:
|
||||
base: .19
|
||||
per-level: 0
|
||||
attack-damage:
|
||||
base: 2
|
||||
per-level: 0.1
|
||||
attack-speed:
|
||||
base: 4.2
|
||||
per-level: 0.05
|
||||
|
||||
# Experience sources for main class experience.
|
||||
main-exp-sources:
|
||||
- 'killmob{type=ZOMBIE;amount=1-3}'
|
||||
- 'killmob{type=ENDERMAN;amount=6-9}'
|
||||
|
16
default/drop-tables/example-drop-tables.yml
Normal file
16
default/drop-tables/example-drop-tables.yml
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
# You may create as many drop tables as you want. You can also
|
||||
# make drop tables refer to other drop tables.
|
||||
#
|
||||
# DON'T TRY to create recursive drop tables (drop tables
|
||||
# which call themselves to multiply items dropped).
|
||||
|
||||
diamond-drop-table:
|
||||
items:
|
||||
- 'vanilla{type=DIAMOND} 1 1-3'
|
||||
# - 'mmoitem{type=material;id=RARE_DIAMOND} .1 1-3'
|
||||
- 'droptable{id=other-drop-table} .1'
|
||||
|
||||
other-drop-table:
|
||||
items:
|
||||
- 'vanilla{type=STONE_SLAB} 1 1-3'
|
71
default/gui/attribute-view.yml
Normal file
71
default/gui/attribute-view.yml
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
# GUI display name
|
||||
name: Player Attributes
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
reallocate:
|
||||
slots: [26]
|
||||
function: reallocation
|
||||
item: CAULDRON
|
||||
name: '&aReallocate Skill Points'
|
||||
lore:
|
||||
- ''
|
||||
- 'You have spent a total of &6{total}&7 skill points.'
|
||||
- '&7Right click to reallocate them.'
|
||||
- ''
|
||||
- '&eCosts 1 attribute reallocation point.'
|
||||
- '&e◆ Attribute Reallocation Points: &6{points}'
|
||||
str:
|
||||
slots: [11]
|
||||
function: attribute_strength
|
||||
name: '&a{name}'
|
||||
item: GOLDEN_APPLE
|
||||
lore: # {buffs} returns amount of buffs
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_weapon_damage}% Weapon Damage (&a+{total_weapon_damage}%&7)'
|
||||
- '&7 +{buff_max_health} Max Health (&a+{total_max_health}&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
dex:
|
||||
slots: [13]
|
||||
function: attribute_dexterity
|
||||
name: '&a{name}'
|
||||
item: LEATHER_BOOTS
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_physical_damage}% Physical Damage (&a+{total_physical_damage}%&7)'
|
||||
- '&7 +{buff_projectile_damage}% Projectile Damage (&a+{total_projectile_damage}%&7)'
|
||||
- '&7 +{buff_attack_speed} Attack Speed (&a+{total_attack_speed}&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
||||
int:
|
||||
slots: [15]
|
||||
function: attribute_intelligence
|
||||
name: '&a{name}'
|
||||
item: BOOK
|
||||
lore:
|
||||
- ''
|
||||
- '&7Points Spent: &6{spent}&7/&6{max}'
|
||||
- '&7Current {name}: &6&l{current}'
|
||||
- ''
|
||||
- '&8When Leveled Up:'
|
||||
- '&7 +{buff_magical_damage}% Magical Damage (&a+{total_magical_damage}%&7)'
|
||||
- '&7 +{buff_cooldown_reduction}% Cooldown Reduction (&a+{total_cooldown_reduction}%&7)'
|
||||
- ''
|
||||
- '&eClick to level up for 1 attribute point.'
|
||||
- '&e◆ Current Attribute Points: {attribute_points}'
|
39
default/gui/class-confirm.yml
Normal file
39
default/gui/class-confirm.yml
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
# GUI display name
|
||||
name: Class Confirmation
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
yes:
|
||||
slots: [12]
|
||||
function: 'yes'
|
||||
|
||||
# Displayed when the player had already selected this class
|
||||
# before (only if class slots are enabled in the config).
|
||||
unlocked:
|
||||
item: GREEN_TERRACOTTA
|
||||
name: '&aSelect {class}'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Class Level: &e{level}'
|
||||
- '&7Progression: &e{exp} / {next_level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7Skill Points: &6{skill_points}'
|
||||
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
|
||||
|
||||
# Displayed when the class is being chosen for the first time.
|
||||
locked:
|
||||
item: GREEN_TERRACOTTA
|
||||
name: '&aSelect {class}'
|
||||
lore: {}
|
||||
|
||||
back:
|
||||
slots: [14]
|
||||
item: RED_TERRACOTTA
|
||||
function: back
|
||||
name: '&aBack'
|
||||
lore: {}
|
18
default/gui/class-select.yml
Normal file
18
default/gui/class-select.yml
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
# GUI display name
|
||||
name: Class Selection
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
class:
|
||||
slots: [13,12,14,11,15,10,16]
|
||||
function: class
|
||||
name: '&a&lThe {name}'
|
||||
hide-flags: true
|
||||
lore:
|
||||
- '{lore}'
|
||||
- ''
|
||||
- '{attribute-lore}'
|
42
default/gui/friend-list.yml
Normal file
42
default/gui/friend-list.yml
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
# GUI display name
|
||||
name: Friends
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 54
|
||||
|
||||
items:
|
||||
friend:
|
||||
slots: [10,11,12,13,14,15,16,19,20,21,22,23,24,25,28,29,30,31,32,33,34]
|
||||
function: friend
|
||||
|
||||
# No friend
|
||||
item: GRAY_STAINED_GLASS_PANE
|
||||
name: '&cNo Friend'
|
||||
lore: {}
|
||||
|
||||
# Online friend
|
||||
online:
|
||||
item: PLAYER_HEAD
|
||||
name: '&a[Online] &f{name}'
|
||||
lore:
|
||||
- '&7Level {level} {class}'
|
||||
- '&7Online Since: {online_since}'
|
||||
- ''
|
||||
- '&cRight click to remove.'
|
||||
|
||||
# Offline friend
|
||||
offline:
|
||||
item: PLAYER_HEAD
|
||||
name: '&c[Offline] &f{name}'
|
||||
lore:
|
||||
- '&7Last Seen: {last_seen} ago'
|
||||
- ''
|
||||
- '&cRight click to remove.'
|
||||
request:
|
||||
slots: [49]
|
||||
function: request
|
||||
item: WRITABLE_BOOK
|
||||
name: '&aNew Friend Request'
|
||||
lore: {}
|
21
default/gui/friend-removal.yml
Normal file
21
default/gui/friend-removal.yml
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
# GUI display name
|
||||
name: Friend Removal
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
yes:
|
||||
slots: [12]
|
||||
item: RED_TERRACOTTA
|
||||
function: 'yes'
|
||||
name: '&aRemove {name}'
|
||||
lore: {}
|
||||
back:
|
||||
slots: [14]
|
||||
item: GREEN_TERRACOTTA
|
||||
function: 'back'
|
||||
name: '&aKeep {name}'
|
||||
lore: {}
|
21
default/gui/party-creation.yml
Normal file
21
default/gui/party-creation.yml
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
# GUI display name
|
||||
name: Party Creation
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
create:
|
||||
slots: [12]
|
||||
item: GREEN_TERRACOTTA
|
||||
function: 'create'
|
||||
name: '&aCreate a party!'
|
||||
lore: {}
|
||||
back:
|
||||
slots: [14]
|
||||
item: RED_TERRACOTTA
|
||||
function: back
|
||||
name: '&aBack'
|
||||
lore: {}
|
33
default/gui/party-view.yml
Normal file
33
default/gui/party-view.yml
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
# GUI display name
|
||||
name: Party ({players}/{max})
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 54
|
||||
|
||||
items:
|
||||
member:
|
||||
slots: [10,12,14,16,28,30,32,34]
|
||||
function: member
|
||||
empty:
|
||||
item: GRAY_STAINED_GLASS_PANE
|
||||
name: '&aNo Player'
|
||||
member:
|
||||
item: PLAYER_HEAD
|
||||
name: '&a{name}'
|
||||
lore:
|
||||
- '&7Level {level} {class}'
|
||||
- '&7Online Since: {since}'
|
||||
leave:
|
||||
slots: [50]
|
||||
function: leave
|
||||
item: REDSTONE
|
||||
name: '&cLeave Party'
|
||||
lore: {}
|
||||
request:
|
||||
slots: [48]
|
||||
function: invite
|
||||
item: WRITABLE_BOOK
|
||||
name: '&aInvite a player..'
|
||||
lore: {}
|
236
default/gui/player-stats.yml
Normal file
236
default/gui/player-stats.yml
Normal file
@ -0,0 +1,236 @@
|
||||
|
||||
# GUI display name
|
||||
name: Your Character
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 54
|
||||
|
||||
items:
|
||||
mining-profession:
|
||||
slots: [10]
|
||||
function: profession_mining
|
||||
item: IRON_PICKAXE
|
||||
name: '&aMining'
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oMining unlocks rare ores and raw materials.'
|
||||
- '&7&oThis is vital to your rise in power and strength,'
|
||||
- '&7&omine frequently for unique and rare drops.'
|
||||
woodcutting-profession:
|
||||
slots: [11]
|
||||
function: profession_woodcutting
|
||||
item: IRON_AXE
|
||||
name: '&aWoodcutting'
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oThough it may seem like a boring task, woodcutting'
|
||||
- '&7&ois vital to obtaining materials used for crafting and trade,'
|
||||
- '&7&oand will help give you the upper hand in the arcane ways.'
|
||||
farming-profession:
|
||||
slots: [12]
|
||||
function: profession_farming
|
||||
item: IRON_HOE
|
||||
name: '&aFarming'
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oWith tons of new food and consumable recipes,'
|
||||
- '&7&oyou will need to stay on top of the crops in order'
|
||||
- '&7&oto obtain the best food and drinks to keep yourself healthy.'
|
||||
fishing-profession:
|
||||
slots: [19]
|
||||
function: profession_fishing
|
||||
item: FISHING_ROD
|
||||
name: '&aFishing'
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oFishing may give you unique drops you'
|
||||
- '&7&ocan''t find anywhere else. The more you'
|
||||
- '&7&ofish, the easier it becomes to find these.'
|
||||
- ''
|
||||
- '&7Fishing Strength: &c{fishing_strength}%'
|
||||
- '&7Crit Fishing Rate: &c{critical_fishing_chance}%'
|
||||
- '&7Crit Failure Rate: &c{critical_fishing_failure_chance}%'
|
||||
alchemy-profession:
|
||||
slots: [20]
|
||||
function: profession_alchemy
|
||||
item: BREWING_STAND
|
||||
name: '&aAlchemy'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oIn a world where you are no longer limited to'
|
||||
- '&7&osimple potions, try learning tons of new brewing'
|
||||
- '&7&orecipes to give yourself the edge on the battlefield.'
|
||||
smithing-profession:
|
||||
slots: [21]
|
||||
function: profession_smithing
|
||||
item: ANVIL
|
||||
name: '&aSmithing'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oStabbing enemies and having them laugh is the worst,'
|
||||
- '&7&oPractice makes perfect when it comes to smithing.'
|
||||
- '&7&o&nWar is won by the man with the pointiest stick.'
|
||||
enchanting-profession:
|
||||
slots: [28]
|
||||
function: profession_enchanting
|
||||
item: ENCHANTED_BOOK
|
||||
name: '&aEnchanting'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oLorem ipsum dolor sit amet, consectetur'
|
||||
- '&7&oadipiscing elit. Proin malesuada maximus massa,'
|
||||
- '&7&osodales imperdiet sapien fermentum at.'
|
||||
smelting-profession:
|
||||
slots: [29]
|
||||
function: profession_smelting
|
||||
item: FURNACE
|
||||
name: '&aSmelting'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- ''
|
||||
- '&7&oSinging your eyebrows will become standard.'
|
||||
- '&7&oYour long hours over the heat will make you'
|
||||
- '&7&ofaster and more efficient with your oven.'
|
||||
boost-display:
|
||||
slots: [47,48,49,50,51]
|
||||
function: boost
|
||||
item: BARRIER
|
||||
no-boost:
|
||||
item: GRAY_STAINED_GLASS_PANE
|
||||
name: '&aNo Booster'
|
||||
lore: {}
|
||||
|
||||
# Profession experience boosters
|
||||
profession:
|
||||
item: EXPERIENCE_BOTTLE
|
||||
name: '&aEXP Boost'
|
||||
lore:
|
||||
- '&7Amount: &6+{value}%'
|
||||
- '&7Time left: &6{left}'
|
||||
- '&7Profession: &6{profession}'
|
||||
- '&7'
|
||||
- '&eStarted by {author}'
|
||||
|
||||
# Main class experience boosters
|
||||
main-level:
|
||||
item: EXPERIENCE_BOTTLE
|
||||
name: '&aEXP Boost'
|
||||
lore:
|
||||
- '&7Amount: &6+{value}%'
|
||||
- '&7Time left: &6{left}'
|
||||
- '&7'
|
||||
- '&eStarted by {author}'
|
||||
boost-next:
|
||||
slots: [52]
|
||||
function: boost-next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext'
|
||||
lore: {}
|
||||
boost-prev:
|
||||
slots: [46]
|
||||
function: boost-previous
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ==
|
||||
name: '&aPrevious'
|
||||
lore: {}
|
||||
party:
|
||||
slots: [16]
|
||||
function: party
|
||||
item: CAKE
|
||||
name: '&aParty Morale'
|
||||
lore:
|
||||
- '&7&oPlaying with your friends'
|
||||
- '&7&ogreatly encourages you!'
|
||||
- ''
|
||||
- '&7Party Bonuses ({count}):'
|
||||
- '&8- +{buff_additional_experience} Experience Earned!'
|
||||
- '&8- +{buff_health_regeneration} Health Regeneration'
|
||||
stats:
|
||||
slots: [15]
|
||||
function: profile
|
||||
item: PLAYER_HEAD
|
||||
name: '&e{player}'
|
||||
lore:
|
||||
- ''
|
||||
- '&7Current Level: &e{level}'
|
||||
- '&7Progression: &e{exp} / {next_level}'
|
||||
- '&8[&e{progress}&8] &e{percent}%'
|
||||
- '&7Skill Points: &6{skill_points}'
|
||||
- ''
|
||||
- '&7Current Class: &c{class}'
|
||||
- '&7Class Points: &c{class_points}'
|
||||
phys:
|
||||
slots: [32]
|
||||
function: stats
|
||||
name: '&cPhysical'
|
||||
item: GOLDEN_APPLE
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- 'Current Strength: &c&l{attribute_strength}'
|
||||
- ''
|
||||
- '✦ Attack Damage: &c{attack_damage} &7(&c{attack_damage_base}&7+&c{attack_damage_extra}&7)'
|
||||
- '✦ Attack Speed: &c{attack_speed} &7(&c{attack_speed_base}&7+&c{attack_speed_extra}&7)'
|
||||
- ''
|
||||
- '❤ Max Health: &c{max_health} &7(&c{max_health_base}&7+&c{max_health_extra}&7)'
|
||||
- '❤ Health Regen: &c{attack_speed} &7(&c{attack_speed_base}&7+&c{attack_speed_extra}&7)'
|
||||
- ''
|
||||
- '❖ Armor: &c{armor} &7(&c{armor_base}&7+&c{armor_extra}&7)'
|
||||
- '❖ Armor Toughness: &c{armor_toughness} &7(&c{armor_toughness_base}&7+&c{armor_toughness_extra}&7)'
|
||||
dex:
|
||||
slots: [33]
|
||||
function: stats
|
||||
name: '&aDexterity'
|
||||
item: LEATHER_BOOTS
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- 'Current Dexterity: &a&l{attribute_dexterity}'
|
||||
- ''
|
||||
- '✤ Knockback Resistance: &f{knockback_resistance} &7(&f{knockback_resistance_base}&7+&f{knockback_resistance_extra}&7)'
|
||||
- '✤ Movement Speed: &f{movement_speed} &7(&f{movement_speed_base}&7+&f{movement_speed_extra}&7)'
|
||||
- '✤ Speed Malus Reduction: &f{speed_malus_reduction} &7(&f{speed_malus_reduction_base}&7+&f{speed_malus_reduction_extra}&7)'
|
||||
int:
|
||||
slots: [34]
|
||||
function: stats
|
||||
name: '&bIntellect'
|
||||
item: BOOK
|
||||
hide-flags: true
|
||||
lore:
|
||||
- ''
|
||||
- 'Current Intelligence: &b&l{attribute_intelligence}'
|
||||
- ''
|
||||
- '✤ Max Mana: &c{max_mana} &7(&c{max_mana_base}&7+&c{max_mana_extra}&7)'
|
||||
- '✤ Mana Regen: &c{mana_regeneration} &7(&c{mana_regeneration_base}&7+&c{mana_regeneration_extra}&7)'
|
||||
- ''
|
||||
- '❊ Max Stellium: &c{max_stellium} &7(&c{max_stellium_base}&7+&c{max_stellium_extra}&7)'
|
||||
- '❊ Stellium Regen: &c{stellium_regeneration} &7(&c{stellium_regeneration_base}&7+&c{stellium_regeneration_extra}&7)'
|
67
default/gui/quest-list.yml
Normal file
67
default/gui/quest-list.yml
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
# GUI display name
|
||||
name: Quests
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 45
|
||||
|
||||
items:
|
||||
skill:
|
||||
slots: [10,11,12,13,14,15,16,19,20,21,22,23,24,25,28,29,30,31,32,33,34]
|
||||
function: quest
|
||||
|
||||
# When quest is locked
|
||||
locked:
|
||||
item: PAPER
|
||||
name: '&c- Unavailable -'
|
||||
|
||||
# When there is no quest to display
|
||||
no-quest:
|
||||
item: GRAY_STAINED_GLASS_PANE
|
||||
name: '&a'
|
||||
|
||||
level-requirement:
|
||||
main:
|
||||
hit: '&a ✔ Requires Level {level}'
|
||||
not-hit: '&c ✖ Requires Level {level}'
|
||||
profession:
|
||||
hit: '&a ✔ Requires {profession} Level {level}'
|
||||
not-hit: '&c ✖ Requires {profession} Level {level}'
|
||||
|
||||
# Date format used in the {date} placeholder
|
||||
date-format: 'MMM d yyyy'
|
||||
|
||||
item: BOOK
|
||||
name: '&a{name}'
|
||||
lore:
|
||||
- '{lore}'
|
||||
- ''
|
||||
- '{started}&8Quest Started!'
|
||||
- '{started}&7► Progression: &e{progress}%'
|
||||
- '{started}&7► &o{objective}'
|
||||
- '{started}'
|
||||
- '{level_req}&7Level Requirements ({current_level_req}/{total_level_req}):'
|
||||
- '{level_req}{level_requirements}'
|
||||
- '{level_req}'
|
||||
- '{completed}&8You''ve completed this quest on the {date}.'
|
||||
- '{completed_cannot_redo}&8You can''t do this quest twice.'
|
||||
- '{completed_delay}&8You can start the quest in {delay}.'
|
||||
- '{completed_can_redo}&8You can start this quest.'
|
||||
- '{completed}'
|
||||
- '{started}&c► Right click to cancel.'
|
||||
- '{!started}&e► Left click to start.'
|
||||
next:
|
||||
slots: [26]
|
||||
function: next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext'
|
||||
lore: {}
|
||||
previous:
|
||||
slots: [18]
|
||||
function: previous
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ==
|
||||
name: '&aPrevious'
|
||||
lore: {}
|
97
default/gui/skill-list.yml
Normal file
97
default/gui/skill-list.yml
Normal file
@ -0,0 +1,97 @@
|
||||
|
||||
# GUI display name
|
||||
name: Your Skills
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 45
|
||||
|
||||
items:
|
||||
skill:
|
||||
slots: [11,12,13,14,15]
|
||||
|
||||
# Index from 'slots' of the skill
|
||||
# currently selected in the GUI
|
||||
selected-slot: 2
|
||||
|
||||
function: skill
|
||||
name: '&a{skill} &6[{level}]'
|
||||
lore:
|
||||
- ''
|
||||
- '{unlocked}&a✔ Requires Level {unlock}'
|
||||
- '{locked}&c✖ Requires Level {unlock}'
|
||||
- '{max_level}&e✔ Maximum Level Hit!'
|
||||
- ''
|
||||
- '{lore}'
|
||||
next:
|
||||
slots: [16]
|
||||
function: next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext'
|
||||
lore: {}
|
||||
previous:
|
||||
slots: [10]
|
||||
function: previous
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ==
|
||||
name: '&aPrevious'
|
||||
lore: {}
|
||||
switch:
|
||||
slots: [28]
|
||||
function: switch
|
||||
item: PLAYER_HEAD
|
||||
binding:
|
||||
item: PINK_STAINED_GLASS
|
||||
name: '&aSwitch to Binding'
|
||||
lore: {}
|
||||
upgrading:
|
||||
item: PINK_STAINED_GLASS
|
||||
name: '&aSwitch to Upgrading'
|
||||
lore: {}
|
||||
skill-slot:
|
||||
slots: [29,30,31,32,33,34]
|
||||
function: slot
|
||||
item: BOOK
|
||||
|
||||
# Material used when the slot is empty
|
||||
empty-item: GRAY_DYE
|
||||
|
||||
name: '&aSkill Slot {slot}'
|
||||
no-skill: '&cNone'
|
||||
lore:
|
||||
- '&7Current Skill: &6{skill}'
|
||||
- ''
|
||||
- '&7&oCast this spell by pressing [F] followed'
|
||||
- '&7&oby the keybind displayed on the action bar.'
|
||||
- ''
|
||||
- '&e► Left click to bind {selected}.'
|
||||
- '&e► Right click to unbind.'
|
||||
skill-level:
|
||||
slots: [29,30,31,32,33,34]
|
||||
function: level
|
||||
|
||||
# Skill level offset, should be changed
|
||||
# according to the amount of inventory
|
||||
# slots the skill-level item occupies.
|
||||
offset: 2
|
||||
|
||||
# Item displayed if the skill level is
|
||||
# too low to display a level item in the GUI
|
||||
too-low:
|
||||
item: AIR
|
||||
|
||||
item: LIME_DYE
|
||||
name: '&a{skill} Level {roman}'
|
||||
lore:
|
||||
- ''
|
||||
- '{lore}'
|
||||
upgrade:
|
||||
slots: [31]
|
||||
function: upgrade
|
||||
item: GREEN_STAINED_GLASS_PANE
|
||||
name: '&a&lUPGRADE {skill_caps}'
|
||||
lore:
|
||||
- '&7Costs 1 skill point.'
|
||||
- ''
|
||||
- '&eCurrent Skill Points: {skill_points}'
|
21
default/gui/subclass-confirm.yml
Normal file
21
default/gui/subclass-confirm.yml
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
# GUI display name
|
||||
name: Subclass Confirmation
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
yes:
|
||||
slots: [12]
|
||||
item: GREEN_TERRACOTTA
|
||||
function: 'yes'
|
||||
name: '&aSelect {class}'
|
||||
lore: {}
|
||||
back:
|
||||
slots: [14]
|
||||
item: RED_TERRACOTTA
|
||||
function: back
|
||||
name: '&aBack'
|
||||
lore: {}
|
23
default/gui/subclass-select.yml
Normal file
23
default/gui/subclass-select.yml
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
# GUI display name
|
||||
name: Choose your path...
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 27
|
||||
|
||||
items:
|
||||
back:
|
||||
function: back
|
||||
slots: [26]
|
||||
item: RED_STAINED_GLASS_PANE
|
||||
name: '&aBack to Class Selection'
|
||||
lore: []
|
||||
class:
|
||||
slots: [13,12,14,11,15,10,16]
|
||||
function: class
|
||||
name: '&a&lThe {name}'
|
||||
lore:
|
||||
- '{lore}'
|
||||
- ''
|
||||
- '{attribute-lore}'
|
51
default/gui/waypoints.yml
Normal file
51
default/gui/waypoints.yml
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
# GUI display name
|
||||
name: Waypoints
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
slots: 45
|
||||
|
||||
items:
|
||||
waypoint:
|
||||
slots: [10,11,12,13,14,15,16,19,20,21,22,23,24,25,28,29,30,31,32,33,34]
|
||||
function: waypoint
|
||||
|
||||
# Displayed when there is no waypoint
|
||||
no-waypoint:
|
||||
item: GRAY_STAINED_GLASS_PANE
|
||||
name: '&a'
|
||||
lore: {}
|
||||
|
||||
# Displayed when the waypoint has not been unlocked yet.
|
||||
locked:
|
||||
name: '&c- Locked -'
|
||||
item: GRAY_DYE
|
||||
lore: {}
|
||||
|
||||
# Displayed when the waypoint is unlocked.
|
||||
display:
|
||||
name: '&a{name}'
|
||||
item: ENDER_EYE
|
||||
|
||||
# Material displayed when the waypoint is not
|
||||
# ready (not dynamic, or not enough stellium)
|
||||
not-ready: ENDER_PEARL
|
||||
|
||||
lore:
|
||||
- '&7You have unlocked this waypoint.'
|
||||
- '&7Click to teleport for &b{stellium} &7stellium.'
|
||||
next:
|
||||
slots: [26]
|
||||
function: next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext Page'
|
||||
lore: []
|
||||
previous:
|
||||
slots: [18]
|
||||
function: previous
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ==
|
||||
name: '&aPrevious Page'
|
||||
lore: []
|
29
default/items.yml
Normal file
29
default/items.yml
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
GOLD_COIN:
|
||||
item: GOLD_NUGGET
|
||||
name: '&6Gold Coin'
|
||||
lore:
|
||||
- '&eWorth: 1g'
|
||||
|
||||
NOTE:
|
||||
item: PAPER
|
||||
name: '&6Note'
|
||||
lore:
|
||||
- '&eWorth: {worth}g'
|
||||
|
||||
DEPOSIT_ITEM:
|
||||
item: BOOK
|
||||
name: '&eDeposit {worth}g'
|
||||
lore: {}
|
||||
|
||||
GOLD_POUCH:
|
||||
item: LEATHER
|
||||
name: '&fGold Pouch'
|
||||
lore:
|
||||
- '&7Right-Click to open.'
|
||||
|
||||
MOB_GOLD_POUCH:
|
||||
item: LEATHER
|
||||
name: '&fGold Pouch'
|
||||
lore:
|
||||
- '&7Right-Click to open.'
|
10
default/levels.txt
Normal file
10
default/levels.txt
Normal file
@ -0,0 +1,10 @@
|
||||
200
|
||||
400
|
||||
600
|
||||
800
|
||||
1000
|
||||
1200
|
||||
1400
|
||||
1600
|
||||
1800
|
||||
2000
|
129
default/messages.yml
Normal file
129
default/messages.yml
Normal file
@ -0,0 +1,129 @@
|
||||
|
||||
# Level & Experience
|
||||
level-up:
|
||||
- ''
|
||||
- '&eCongratulations, you reached level &6{level}&e!'
|
||||
- '&eUse &6/p &eto see your new statistics!'
|
||||
- ''
|
||||
profession-level-up:
|
||||
- '&eYou are now level &6{level}&e in &6{profession}&e!'
|
||||
exp-notification: '&f{profession} &e{progress} &e{ratio}%'
|
||||
exp-hologram: '&e+{exp} EXP!'
|
||||
class-select: '&eYou are now a &6{class}&e!'
|
||||
already-on-class: '&cYou are already a {class}.'
|
||||
|
||||
# General
|
||||
booster-main:
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e EXP multiplier is now active!'
|
||||
- '&e'
|
||||
booster-skill:
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e &6{profession} &eEXP multiplier is now active!'
|
||||
- '&e'
|
||||
|
||||
# Fishing Profession
|
||||
caught-fish: '&cYou caught a fish!'
|
||||
fish-out-water: '&aWell done!'
|
||||
fish-out-water-crit: '&aCritical Fish!'
|
||||
|
||||
# Player Input
|
||||
player-input:
|
||||
anvil:
|
||||
friend-request: 'Friend name..'
|
||||
party-invite: 'Player name..'
|
||||
chat:
|
||||
friend-request: '&eWrite in the chat the player name.'
|
||||
party-invite: '&eWrite in the chat the player you want to invite.'
|
||||
|
||||
# Spell Casting
|
||||
casting:
|
||||
action-bar: '&6[{index}] &a&l{skill}'
|
||||
split: '&7 &7 - &7 '
|
||||
no-longer: '&cYou cancelled skill casting.'
|
||||
no-mana: '&cYou do not have enough mana!'
|
||||
on-cooldown: '&cThis skill is on cooldown.'
|
||||
|
||||
# Combat Log
|
||||
now-in-combat: '&cYou are now in combat!'
|
||||
leave-combat: '&aYou left combat.'
|
||||
|
||||
# Waypoints
|
||||
new-waypoint: '&eYou unlocked the &6{waypoint} &ewaypoint!'
|
||||
not-enough-stellium: '&cYou don''t have enough stellium: you need {more} more.'
|
||||
waypoint-cooldown: '&cPlease wait {cooldown} before using a waypoint again.'
|
||||
not-unlocked-waypoint: '&cYou have not unlocked that waypoint yet.'
|
||||
not-dynamic-waypoint: '&cYou many only teleport to a non-dynamic waypoint while standing on another waypoint.'
|
||||
standing-on-waypoint: '&cYou are already standing on this waypoint.'
|
||||
warping-canceled: '&cWaypoint warping canceled.'
|
||||
warping-comencing: '&cDO NOT MOVE!&e You will be warped in {left}sec.'
|
||||
|
||||
# Cash
|
||||
deposit: '&eYou successfully deposited &6{worth}g&e.'
|
||||
withdrawing: '&eType in the chat the amount of &6gold&e you want to &6withdraw&e.'
|
||||
withdraw-cancel: '&eWithdrawing canceled.'
|
||||
withdrew: '&eYou successfully withdrew &6{worth}g&e.'
|
||||
wrong-number: '&c{arg} is not a valid number.'
|
||||
not-enough-money: '&cYou don''t have enough money, you need {left} more gold.'
|
||||
stand-near-enderchest: '&cYou must be standing near a bank to do that.'
|
||||
|
||||
# Blocks
|
||||
cannot-break: '&cYou do not have the right tool in order to break that block.'
|
||||
|
||||
# Friends
|
||||
no-longer-friends: '&cYou and {unfriend} are no longer friends.'
|
||||
not-online-player: '&c{player} is not online.'
|
||||
sent-friend-request: '&eYou sent a friend request to &6{player}&e.'
|
||||
now-friends: '&eYou are now friends with &6{player}&e.'
|
||||
friend-request-cooldown: '&cPlease wait {cooldown}.'
|
||||
cant-request-to-yourself: '&cYou can''t send a request to yourself.'
|
||||
already-friends: '&cYou are already friends with {player}.'
|
||||
friend-request:
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ejust sent you a friend request!"}'
|
||||
- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/friends accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/friends deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
|
||||
# Parties
|
||||
party-chat: '&5[Party] {player}: {message}'
|
||||
sent-party-invite: '&eYou sent a party invite to &6{player}&e.'
|
||||
already-in-party: '&c{player} is already in your party.'
|
||||
party-invite:
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ehas invited you to their party!"}'
|
||||
- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/party accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/party deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
party-is-full: '&cSorry, your party is full.'
|
||||
party-joined: '&eYou successfully joined &6{owner}&e''s party.'
|
||||
party-joined-other: '&6{player}&e joined your party!'
|
||||
transfer-party-ownership: '&eYou were transfered the party ownership.'
|
||||
kick-from-party: '&eYou successfully kicked &6{player}&e.'
|
||||
party-invite-cooldown: '&cPlease wait {cooldown} before inviting {player}.'
|
||||
|
||||
# Quests
|
||||
already-on-quest: '&cYou are already on a quest.'
|
||||
cancel-quest: '&eYou successfully canceled your ongoing quest.'
|
||||
quest-level-restriction: '&cYou need to be {level} {count}.'
|
||||
cant-redo-quest: '&cYou can''t start this quest twice.'
|
||||
quest-cooldown: '&cYou need to wait {delay}.'
|
||||
start-quest: '&eYou successfully started &6{quest}&e.'
|
||||
|
||||
cant-choose-new-class:
|
||||
- '&cYou need one class point to perform this action.'
|
||||
|
||||
# Attributes
|
||||
no-attribute-points-spent: '&cYou have not spent any attribute points.'
|
||||
not-attribute-reallocation-point: '&cYou do not have 1 reallocation point.'
|
||||
not-attribute-point: '&cYou do not have 1 attribute point.'
|
||||
attribute-points-reallocated: '&eYou successfully reset your attributes. You now have &6{points} &eattribute points.'
|
||||
attribute-max-points-hit: '&cYou cannot level up this attribute anymore.'
|
||||
attribute-level-up: '&eYou successfully leveled up your &6{attribute}&e.' # {level}
|
||||
|
||||
# Skills
|
||||
no-class-skill: '&cYour class has no skill.'
|
||||
not-enough-skill-points: '&cYou need one skill point.'
|
||||
upgrade-skill: '&eYour &6{skill} &eis now Level &6{level}&e!'
|
||||
not-unlocked-skill: '&cYou have not unlocked that skill yet.'
|
||||
no-skill-bound: '&cYou don''t have any skill bound to this slot.'
|
||||
not-active-skill: '&cThis is not an active skill.'
|
||||
skill-max-level-hit: '&cYou already hit the max level for that skill.'
|
61
default/professions/alchemy.yml
Normal file
61
default/professions/alchemy.yml
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
# Display options
|
||||
name: Alchemy
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 20
|
||||
per-level: 3
|
||||
|
||||
exp-sources:
|
||||
- 'brewpotion{effect=SPEED}'
|
||||
|
||||
# When brewing a potion, players earn Alchemy experience.
|
||||
# Experience earned depends on the effect you give to your
|
||||
# potion, if you upgrade/extend its duration, etc.
|
||||
alchemy-experience:
|
||||
|
||||
special:
|
||||
|
||||
# When brewing a potion into a splash potion,
|
||||
# only 40% of the base EXP is earned.
|
||||
splash: 40
|
||||
|
||||
# When brewing a potion into a splash potion,
|
||||
# only 40% of the base EXP is earned.
|
||||
lingering: 40
|
||||
|
||||
# When extending a pot duration,
|
||||
# only 40% of base EXP is earned.
|
||||
extend: 40
|
||||
|
||||
# When upgrading a potion level,
|
||||
# only 40% of base EXP is earned.
|
||||
upgrade: 40
|
||||
|
||||
# Base EXP of potions
|
||||
effects:
|
||||
|
||||
# Water bottles
|
||||
AWKWARD: 5
|
||||
MUNDANE: 5
|
||||
THICK: 5
|
||||
|
||||
# Potion effects
|
||||
NIGHT_VISION: 10
|
||||
INVISIBILITY: 10
|
||||
JUMP: 10
|
||||
FIRE_RESISTANCE: 10
|
||||
SPEED: 10
|
||||
SLOWNESS: 10
|
||||
WATER_BREATHING: 10
|
||||
INSTANT_HEAL: 10
|
||||
INSTANT_DAMAGE: 10
|
||||
POISON: 10
|
||||
REGEN: 10
|
||||
STRENGTH: 10
|
||||
WEAKNESS: 10
|
||||
LUCK: 10
|
||||
TURTLE_MASTER: 10
|
||||
SLOW_FALLING: 10
|
63
default/professions/enchanting.yml
Normal file
63
default/professions/enchanting.yml
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
# Display options
|
||||
name: Enchanting
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 10
|
||||
per-level: 2
|
||||
|
||||
# Remove the 'enchant' parameter from the line config
|
||||
# to make the profession get EXP with ANY enchant.
|
||||
|
||||
# Specifying enchants like that lets you create different
|
||||
# enchanting professions, like DESTRUCTION for offense enchants
|
||||
# (Smite, Bane of Arth., Sharpness, Power, Fire Aspect, Flame)
|
||||
# and ALTERATION for strategic enchants for e.g
|
||||
|
||||
exp-sources:
|
||||
- 'enchantitem{enchant=sharpness}'
|
||||
|
||||
# When enchanting an item, players earn Enchanting experience.
|
||||
# Experience given by an item is the sum of the EXP given by every extra enchantment.
|
||||
# Enchantment experience depends on the enchant itself + the enchant level.
|
||||
# Enchant exp = <enchant-level> * <base-enchant-exp>
|
||||
base-enchant-exp:
|
||||
fire_protection: 10
|
||||
sharpness: 10
|
||||
flame: 10
|
||||
aqua_affinity: 10
|
||||
punch: 10
|
||||
loyalty: 10
|
||||
depth_strider: 10
|
||||
vanishing_curse: 10
|
||||
unbreaking: 10
|
||||
knockback: 10
|
||||
luck_of_the_sea: 10
|
||||
binding_curse: 10
|
||||
fortune: 10
|
||||
protection: 10
|
||||
efficiency: 10
|
||||
mending: 10
|
||||
frost_walker: 10
|
||||
lure: 10
|
||||
looting: 10
|
||||
piercing: 10
|
||||
blast_protection: 10
|
||||
smite: 10
|
||||
multishot: 10
|
||||
fire_aspect: 10
|
||||
channeling: 10
|
||||
sweeping: 10
|
||||
thorns: 10
|
||||
bane_of_arthropods: 10
|
||||
respiration: 10
|
||||
riptide: 10
|
||||
silk_touch: 10
|
||||
quick_charge: 10
|
||||
projectile_protection: 10
|
||||
impaling: 10
|
||||
feather_falling: 10
|
||||
power: 10
|
||||
infinity: 10
|
14
default/professions/farming.yml
Normal file
14
default/professions/farming.yml
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
# Display options
|
||||
name: Farming
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 10
|
||||
per-level: 2
|
||||
|
||||
exp-sources:
|
||||
- 'mineblock{type=CARROTS;amount=1-3}'
|
||||
- 'mineblock{type=POTATOES;amount=1-3}'
|
||||
- 'mineblock{type=WHEAT;amount=1-3}'
|
41
default/professions/fishing.yml
Normal file
41
default/professions/fishing.yml
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
# Display options
|
||||
name: Fishing
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 20
|
||||
per-level: 3
|
||||
|
||||
exp-sources: {}
|
||||
|
||||
# Fishing drop tables which override MC default.
|
||||
# When fishing, the plugin reads through all the drop tables
|
||||
# and picks THE first one which all conditions are met!!
|
||||
# You must put at first place the drop tables which
|
||||
# have the most conditions/which are the most important.
|
||||
# Number of tugs = number of times you need to click to fish.
|
||||
on-fish:
|
||||
overriding-drop-table:
|
||||
conditions:
|
||||
- 'region{name=swamp}'
|
||||
|
||||
# When drop table is read, one of these
|
||||
# items will be selected randomly.
|
||||
items:
|
||||
|
||||
# Tugs needed: 4 to 5
|
||||
# Fishing EXP earned: 1 to 6
|
||||
- 'mmoitem{type=CONSUMABLE;id=SUSHI_ROLL;tugs=30-40;experience=1-6}'
|
||||
|
||||
# Tugs needed: 10 to 20
|
||||
# Fishing EXP earned: 20 to 30
|
||||
- 'mmoitem{type=GEM_STONE;id=SPITEFUL_OPAQUE_DIAMOND;tugs=10-15;experience=20-30}'
|
||||
|
||||
# Default drop table which always apply.
|
||||
# When removing every drop table, the vanilla
|
||||
# fishing mecanism is back.
|
||||
default:
|
||||
items:
|
||||
- 'vanilla{type=SALMON;tugs=4-5;experience=1-6}'
|
53
default/professions/mining.yml
Normal file
53
default/professions/mining.yml
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
# Display options
|
||||
name: Mining
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 20
|
||||
per-level: 3
|
||||
|
||||
on-mine:
|
||||
EMERALD_ORE:
|
||||
drop-table:
|
||||
items:
|
||||
- 'vanilla{type=EMERALD} 1 1-9'
|
||||
vanilla-drops: false
|
||||
regen:
|
||||
time: 2000
|
||||
temp-block: STONE
|
||||
triggers:
|
||||
- 'exp{profession=mining;amount=32}'
|
||||
|
||||
DIAMOND_ORE:
|
||||
|
||||
# Refer to drop-tables.yml
|
||||
# The drop table used by the block.
|
||||
drop-table:
|
||||
items:
|
||||
- 'vanilla{type=DIAMOND} 1 1-3'
|
||||
# - 'mmoitem{type=material;id=RARE_DIAMOND} .1 1-3'
|
||||
# - 'droptable{id=other-drop-table} .1'
|
||||
|
||||
# Triggers when destroying the block, can
|
||||
# be used to give exp to a player!
|
||||
triggers:
|
||||
- 'exp{profession=mining;amount=20}'
|
||||
|
||||
# Set to false if you want to disable vanila drops.
|
||||
vanilla-drops: false
|
||||
|
||||
regen:
|
||||
|
||||
# Ticks the block takes to appear again
|
||||
time: 2000
|
||||
|
||||
# The temporary block which shows
|
||||
# during the block regen time.
|
||||
#
|
||||
# !! Warning !!
|
||||
# When using the temp-block option, make sure you choose
|
||||
# one temp block and don't use it anywhere else in the
|
||||
# configuration so that block regens do not affect each other
|
||||
temp-block: STONE
|
9
default/professions/smelting.yml
Normal file
9
default/professions/smelting.yml
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# Display options
|
||||
name: Smelting
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 20
|
||||
per-level: 3
|
36
default/professions/smithing.yml
Normal file
36
default/professions/smithing.yml
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
# Display options
|
||||
name: Smithing
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 20
|
||||
per-level: 3
|
||||
|
||||
exp-sources:
|
||||
- 'repairitem{}'
|
||||
|
||||
# Experience given by repairing 100
|
||||
# durability points from a specific material.
|
||||
|
||||
# Warning, diamonds/iron ingots/<any material
|
||||
# which repairs a specific type of tool> do
|
||||
# not repair the same amount of durability!
|
||||
repair-exp:
|
||||
|
||||
# Swords
|
||||
DIAMOND_SWORD: 1.923 # Max durability: 1561
|
||||
GOLDEN_SWORD: 62.5 # Max durability: 32
|
||||
IRON_SWORD: 8 # Md: 250
|
||||
STONE_SWORD: 7.634 # Md: 131
|
||||
WOODEN_SWORD: 13.56 # Md: 59
|
||||
|
||||
# Picks
|
||||
DIAMOND_PICKAXE: 1.923
|
||||
GOLDEN_PICKAXE: 62.5
|
||||
IRON_PICKAXE: 8
|
||||
STONE_PICKAXE: 7.634
|
||||
WOODEN_PICKAXE: 13.56
|
||||
|
||||
# Add as many as you want: bows, shields..
|
18
default/professions/woodcutting.yml
Normal file
18
default/professions/woodcutting.yml
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
# Display options
|
||||
name: Woodcutting
|
||||
|
||||
# Experience given to the main level
|
||||
# when leveling up this profession
|
||||
experience:
|
||||
base: 13
|
||||
per-level: 2.5
|
||||
|
||||
exp-sources:
|
||||
- 'mineblock{type=OAK_LOG;amount=1-3}'
|
||||
- 'mineblock{type=SPRUCE_LOG;amount=1-3}'
|
||||
- 'mineblock{type=BIRCH_LOG;amount=1-3}'
|
||||
- 'mineblock{type=JUNGLE_LOG;amount=1-3}'
|
||||
- 'mineblock{type=ACACIA_LOG;amount=1-3}'
|
||||
- 'mineblock{type=BIRCH_LOG;amount=1-3}'
|
||||
- 'mineblock{type=DARK_OAK_LOG;amount=1-3}'
|
30
default/quests/adv-begins.yml
Normal file
30
default/quests/adv-begins.yml
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
# Display options
|
||||
name: 'The Beginning of an Adventure'
|
||||
lore:
|
||||
- 'Yet another quest example.'
|
||||
- ''
|
||||
- '&eRewards:'
|
||||
- '&7► Stone Tools'
|
||||
- '&7► 30 EXP'
|
||||
|
||||
# Parent quests
|
||||
parent:
|
||||
- 'tutorial'
|
||||
|
||||
# Quest objectives
|
||||
objectives:
|
||||
1:
|
||||
type: 'goto{world="world";x=120;y=46;z=652;range=10}'
|
||||
lore: 'Head to the camp.'
|
||||
triggers:
|
||||
- 'message{format="Good job!"}'
|
||||
2:
|
||||
type: 'talkto{npc=0}'
|
||||
lore: 'Go talk to the Blacksmith.'
|
||||
triggers:
|
||||
- 'message{format="The blacksmith told you to come see me... ?"}'
|
||||
- 'item{type=STONE_SWORD}'
|
||||
- 'item{type=STONE_AXE}'
|
||||
- 'item{type=STONE_PICKAXE}'
|
||||
- 'experience{amount=30}'
|
39
default/quests/fetch-mango.yml
Normal file
39
default/quests/fetch-mango.yml
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
# Display options
|
||||
name: 'The Exotic Fruit'
|
||||
|
||||
# Quest lore displayed in the quest menu.
|
||||
lore:
|
||||
- 'Gimme mangoes please.'
|
||||
- ''
|
||||
- '&eRewards:'
|
||||
- '&7► 10 Gold coins'
|
||||
- '&7► 30 EXP'
|
||||
|
||||
# Quests the player must finish
|
||||
# in order to unlock this one.
|
||||
parent: []
|
||||
|
||||
# Cooldown in hours. Don't put any
|
||||
# to make the quest a one-time quest.
|
||||
# Put it to 0 to make it instantly redoable.
|
||||
delay: 0
|
||||
|
||||
# Objectives the player needs to
|
||||
# complete. Once they're all complete,
|
||||
# the quest will end.
|
||||
objectives:
|
||||
1:
|
||||
type: 'mine{type=OAK_LOG;amount=8}'
|
||||
lore: 'Mangoes only grow in Oak trees. Go break 8 oak logs!'
|
||||
triggers:
|
||||
- message{format="&aThank you! Those mangoes are gonna drop from these leaves."}
|
||||
- sound{sound=ENTITY_EXPERIENCE_ORB_PICKUP;pitch=1;volume=1}
|
||||
2:
|
||||
type: 'getitem{type=APPLE;npc=1;amount=2}'
|
||||
lore: 'Bring me mangoes.'
|
||||
triggers:
|
||||
- message{format="&aThis looked like apple. But owell, thanks! Here are a a few coins'"}
|
||||
- sound{sound=ENTITY_EXPERIENCE_ORB_PICKUP;pitch=1;volume=1}
|
||||
- command{format="mmocore coins %player% 10"}
|
||||
- 'experience{amount=30}'
|
69
default/quests/tutorial.yml
Normal file
69
default/quests/tutorial.yml
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
# Levels players must have in
|
||||
# order to unlock this quest.
|
||||
level-req:
|
||||
main: 10
|
||||
mining: 5
|
||||
|
||||
# Quest name displayed in the quest menu.
|
||||
name: 'A Whole New World'
|
||||
|
||||
# Quest lore displayed in the quest menu.
|
||||
lore:
|
||||
- 'This is the tutorial quest.'
|
||||
- 'Lore example...'
|
||||
- ''
|
||||
- '&eRewards:'
|
||||
- '&7► Wooden Tools'
|
||||
- '&7► Leather Armor'
|
||||
- '&7► 100 EXP'
|
||||
|
||||
# Quests the player must finish
|
||||
# in order to unlock this one.
|
||||
parent: []
|
||||
|
||||
# Cooldown in hours. Don't put any
|
||||
# to make the quest a one-time quest.
|
||||
# Put it to 0 to make it instantly redoable.
|
||||
delay: 12
|
||||
|
||||
# Objectives the player needs to
|
||||
# complete. Once they're all complete,
|
||||
# the quest will end.
|
||||
objectives:
|
||||
1:
|
||||
type: 'goto{world="world";x=56;y=68;z=115;range=5}'
|
||||
lore: 'Head to the camp.'
|
||||
triggers:
|
||||
- 'message{format="&aBlacksmith> &fHello, %player%! I am currently looking for some help."}'
|
||||
- 'message{format="&aBlacksmith> &fCould you please get me 3 oak logs?"}'
|
||||
- 'sound{sound=ENTITY_EXPERIENCE_ORB_PICKUP}'
|
||||
2:
|
||||
type: 'mine{type="OAK_LOG";amount=3}'
|
||||
lore: 'Get three oak logs!'
|
||||
triggers:
|
||||
- 'message{format="&aBlacksmith> &fGood job, now bring these logs back to me!"}'
|
||||
- 'sound{sound="ENTITY_EXPERIENCE_ORB_PICKUP"}'
|
||||
3:
|
||||
type: 'getitem{type="OAK_LOG";amount=3;npc=0}'
|
||||
lore: 'Give these oak logs to the blacksmith.'
|
||||
triggers:
|
||||
- 'message{format="&aBlacksmith> &fGood job, now talk to the blacksmith again to claim your weapons!"}'
|
||||
- 'sound{sound=ENTITY_EXPERIENCE_ORB_PICKUP}'
|
||||
4:
|
||||
type: 'talkto{npc=0}'
|
||||
lore: 'Get your weapons from the blacksmith!'
|
||||
triggers:
|
||||
- 'item{type=WOODEN_SWORD}'
|
||||
- 'item{type=WOODEN_AXE}'
|
||||
- 'item{type=BOW}'
|
||||
- 'message{format="&aBlacksmith> &fNow go kill 5 skeletal knights to finish tutorial!"}'
|
||||
- 'sound{sound=ENTITY_PLAYER_LEVELUP}'
|
||||
5:
|
||||
type: 'killmythicmob{name="SkeletalKnight";amount=5}'
|
||||
lore: 'Kill 5 skeletal knights!'
|
||||
triggers:
|
||||
- 'message{format="&aYou have successfully finished the tutorial!"}'
|
||||
- 'sound{sound="ENTITY_PLAYER_LEVELUP"}'
|
||||
- 'mmoitem{type=SWORD;id=CUTLASS}'
|
||||
- 'experience{amount=100}'
|
15
default/recipes/brewing.yml
Normal file
15
default/recipes/brewing.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# Every brewing recipe requires an empty water bottle.
|
||||
# Make sure every brewing recipe has a different ID.
|
||||
# It is only used as reference in the plugin, doesn't really matter.
|
||||
|
||||
# Brewing recipe ID
|
||||
mana-pot-recipe:
|
||||
|
||||
# Ingredient used to brew the empty water bottles.
|
||||
ingredient: MATERIAL.MANA_FLOWER
|
||||
|
||||
# Items replacing empty water bottles when brewing is complete.
|
||||
result: CONSUMABLE.MANA_POTION
|
||||
|
||||
# Time required to brew empty water bottles.
|
||||
cook-time: 10
|
14
default/recipes/furnace.yml
Normal file
14
default/recipes/furnace.yml
Normal file
@ -0,0 +1,14 @@
|
||||
# Make sure every furnace recipe has a different ID.
|
||||
# It is only used as reference in the plugin, doesn't really matter.
|
||||
|
||||
# Furnace recipe ID
|
||||
emerald-recipe:
|
||||
|
||||
# Item being smelted.
|
||||
ingredient: MATERIAL.EMERALD_GEODE
|
||||
|
||||
# Item given as output.
|
||||
result: MATERIAL.SHINY_EMERALD
|
||||
|
||||
# Time required to smelt the item.
|
||||
cook-time: 10
|
40
default/restrictions.yml
Normal file
40
default/restrictions.yml
Normal file
@ -0,0 +1,40 @@
|
||||
# Mining a block in creative will NOT drop any
|
||||
# custom drops/will not apply block regen, etc.
|
||||
#
|
||||
# Any block specified in this config, wherever it
|
||||
# is located, MUST be mined using the correct tool
|
||||
# otherwise nothing will drop!
|
||||
|
||||
# The corresponding tool. It's CASE_SENSITIVE!
|
||||
WOODEN_PICKAXE:
|
||||
|
||||
# What the tool can mine.
|
||||
can-mine:
|
||||
- COAL_ORE
|
||||
|
||||
STONE_PICKAXE:
|
||||
can-mine:
|
||||
- IRON_ORE
|
||||
|
||||
# The block break permissions the tool inherits.
|
||||
# e.g a stone pickaxe can mine iron ores PLUS
|
||||
# any block that the wooden pickaxe can mine.
|
||||
# Used to make the config much clearer.
|
||||
parent: WOODEN_PICKAXE
|
||||
|
||||
IRON_PICKAXE:
|
||||
parent: STONE_PICKAXE
|
||||
can-mine:
|
||||
- GOLD_ORE
|
||||
|
||||
GOLDEN_PICKAXE:
|
||||
parent: IRON_PICKAXE
|
||||
can-mine:
|
||||
- LAPIS_ORE
|
||||
|
||||
DIAMOND_PICKAXE:
|
||||
parent: GOLDEN_PICKAXE
|
||||
can-mine:
|
||||
- DIAMOND_ORE
|
||||
- EMERALD_ORE
|
||||
- REDSTONE_ORE
|
112
default/stats.yml
Normal file
112
default/stats.yml
Normal file
@ -0,0 +1,112 @@
|
||||
default:
|
||||
ATTACK_DAMAGE:
|
||||
base: 1
|
||||
per-level: 0
|
||||
ATTACK_SPEED:
|
||||
base: 4
|
||||
per-level: 0
|
||||
MAX_HEALTH:
|
||||
base: 20
|
||||
per-level: 0
|
||||
MOVEMENT_SPEED:
|
||||
base: .2
|
||||
per-level: 0
|
||||
ARMOR:
|
||||
base: 0
|
||||
per-level: 0
|
||||
ARMOR_TOUGHNESS:
|
||||
base: 0
|
||||
per-level: 0
|
||||
SPEED_MALUS_REDUCTION:
|
||||
base: 0
|
||||
per-level: 0
|
||||
KNOCKBACK_RESISTANCE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
HEALTH_REGENERATION:
|
||||
base: .1
|
||||
per-level: 0
|
||||
MAX_MANA:
|
||||
base: 20
|
||||
per-level: 0
|
||||
MANA_REGENERATION:
|
||||
base: .166
|
||||
per-level: .03
|
||||
MAX_STELLIUM:
|
||||
base: 20
|
||||
per-level: 0
|
||||
STELLIUM_REGENERATION:
|
||||
base: .01
|
||||
per-level: 0
|
||||
|
||||
# Increases main class experience earned.
|
||||
ADDITIONAL_EXPERIENCE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Reduces skill cooldowns by X%
|
||||
COOLDOWN_REDUCTION:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Dealt by skills
|
||||
SKILL_DAMAGE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Physical skill damage
|
||||
PHYSICAL_DAMAGE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Magical skill damage
|
||||
MAGICAL_DAMAGE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Dealt by any weapon
|
||||
WEAPON_DAMAGE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Dealt by projectile skills or weapons
|
||||
PROJECTILE_DAMAGE:
|
||||
base: 0
|
||||
per-level: 0
|
||||
|
||||
# Reduces the amount of tugs needed to fish fishes.
|
||||
# (When set to 30, 30% of the tugs will be removed).
|
||||
FISHING_STRENGTH:
|
||||
base: 0
|
||||
per-level: 0.3
|
||||
min: 0
|
||||
max: 40
|
||||
|
||||
# Chance of instantly fishing.
|
||||
CRITICAL_FISHING_CHANCE:
|
||||
base: 5
|
||||
per-level: 0
|
||||
min: 0
|
||||
max: 70
|
||||
|
||||
# Chance of being dragged in the waters
|
||||
# by the fish when trying to catch it,
|
||||
# once the player has NOT successfully
|
||||
# fished (conditional probability).
|
||||
CRITICAL_FISHING_FAILURE_CHANCE:
|
||||
base: 3
|
||||
per-level: -.01
|
||||
min: 1
|
||||
max: 100
|
||||
|
||||
# How much decimal places the different stats
|
||||
# display in the GUIs (e.g in player stats).
|
||||
# Default is "0.#" when none is specified.
|
||||
# https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html
|
||||
decimal-format:
|
||||
MOVEMENT_SPEED: '0.##'
|
||||
ARMOR_TOUGHNESS: '0.###'
|
||||
KNOCKBACK_RESISTANCE: '0.##'
|
||||
HEALTH_REGENERATION: '0.##'
|
||||
MANA_REGENERATION: '0.##'
|
||||
STELLIUM_REGENERATION: '0.##'
|
45
default/waypoints.yml
Normal file
45
default/waypoints.yml
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
# Waypoint ID, used as reference.
|
||||
# Make sure the waypoints have different IDs.
|
||||
spawn:
|
||||
|
||||
# Name of waypoint displayed in the waypoint GUI.
|
||||
name: Spawn
|
||||
|
||||
# Location of waypoint: <world> <x y z> <yaw> <pitch>
|
||||
# Yaw and pitch are where the player will be looking at when teleported.
|
||||
location: 'world 69 71 136 136 0'
|
||||
|
||||
# Radius of waypoint around the specified location.
|
||||
radius: 1.5
|
||||
|
||||
# Stellium cost in order to use the waypoint.
|
||||
# Stellium is like stamina however it's not used
|
||||
# by skills and regens much slower than mana.
|
||||
stellium: 3
|
||||
|
||||
# When enabled, players can unlock the waypoint
|
||||
# by sneaking on it, and can open the waypoint menu
|
||||
# from the specified location (true by default).
|
||||
sneak: true
|
||||
|
||||
# Should be waypoint be unlocked by default?
|
||||
default: true
|
||||
|
||||
spawn1:
|
||||
name: Spawn1
|
||||
location: 'world 69 71 136 136 0'
|
||||
radius: 1.5
|
||||
stellium: 3
|
||||
default: false
|
||||
|
||||
# Can be teleported to even when not standing
|
||||
# on any waypoint (waypoint must be unlocked).
|
||||
dynamic: true
|
||||
|
||||
spawn2:
|
||||
name: Spawn2
|
||||
location: 'world 69 71 136 136 0'
|
||||
radius: 1.5
|
||||
stellium: 3
|
||||
sneak: false
|
47
plugin.yml
Normal file
47
plugin.yml
Normal file
@ -0,0 +1,47 @@
|
||||
name: MMOCore
|
||||
version: 1.0.6
|
||||
main: net.Indyuce.mmocore.MMOCore
|
||||
author: Indyuce
|
||||
loadbefore: [MMOItems]
|
||||
softdepend: [Vault,MythicMobs,PlaceholderAPI]
|
||||
api-version: 1.13
|
||||
commands:
|
||||
player:
|
||||
description: Show player stats.
|
||||
aliases: [p]
|
||||
class:
|
||||
description: Choose a new class.
|
||||
attributes:
|
||||
description: Opens the attribute menu.
|
||||
waypoints:
|
||||
description: Open the waypoints menu.
|
||||
mmocore:
|
||||
description: Main command.
|
||||
aliases: [rpg]
|
||||
deposit:
|
||||
description: Opens the currency deposit menu.
|
||||
withdraw:
|
||||
description: Creates a withdraw request.
|
||||
friends:
|
||||
description: Opens the friends menu.
|
||||
aliases: [f]
|
||||
party:
|
||||
description: Opens the party menu.
|
||||
aliases: [f]
|
||||
quests:
|
||||
description: Opens the quests menu.
|
||||
skills:
|
||||
description: Opens the skills menu.
|
||||
permissions:
|
||||
mmocore.admin:
|
||||
description: Access to /rpg
|
||||
default: op
|
||||
mmocore.waypoints:
|
||||
description: Access to /waypoints
|
||||
default: op
|
||||
mmocore.currency:
|
||||
description: Access to /deposit and /withdraw
|
||||
default: op
|
||||
mmocore.class-select:
|
||||
description: Access to /class
|
||||
default: op
|
97
src/com/codingforcookies/armorequip/ArmorEquipEvent.java
Normal file
97
src/com/codingforcookies/armorequip/ArmorEquipEvent.java
Normal file
@ -0,0 +1,97 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public final class ArmorEquipEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
// private boolean cancelled = false;
|
||||
private final ArmorType type;
|
||||
private final ItemStack oldArmor, newArmor;
|
||||
|
||||
/**
|
||||
* Constructor for the ArmorEquipEvent.
|
||||
*
|
||||
* @param player
|
||||
* The player who put on / removed the armor.
|
||||
* @param type
|
||||
* The ArmorType of the armor added
|
||||
* @param oldArmorPiece
|
||||
* The ItemStack of the armor removed.
|
||||
* @param newArmorPiece
|
||||
* The ItemStack of the armor added.
|
||||
*/
|
||||
public ArmorEquipEvent(Player player, ArmorType type, ItemStack oldArmor, ItemStack newArmor) {
|
||||
super(player);
|
||||
|
||||
this.type = type;
|
||||
this.oldArmor = oldArmor;
|
||||
this.newArmor = newArmor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of handlers handling this event.
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
public final static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of handlers handling this event.
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
@Override
|
||||
public final HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this event should be cancelled.
|
||||
*
|
||||
* @param cancel
|
||||
* If this event should be cancelled.
|
||||
*/
|
||||
// public final void setCancelled(final boolean cancelled){
|
||||
// this.cancelled = cancelled;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets if this event is cancelled.
|
||||
*
|
||||
* @return If this event is cancelled
|
||||
*/
|
||||
// public final boolean isCancelled(){
|
||||
// return cancelled;
|
||||
// }
|
||||
|
||||
public final ArmorType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last equipped armor piece, could be a piece of armor,
|
||||
* {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getOldArmor() {
|
||||
return oldArmor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the newly equipped armor, could be a piece of armor,
|
||||
* {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getNewArmorPiece() {
|
||||
return newArmor;
|
||||
}
|
||||
}
|
186
src/com/codingforcookies/armorequip/ArmorListener.java
Normal file
186
src/com/codingforcookies/armorequip/ArmorListener.java
Normal file
@ -0,0 +1,186 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemBreakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public class ArmorListener implements Listener {
|
||||
|
||||
// private final List<String> blockedMaterials;
|
||||
|
||||
// public ArmorListener(List<String> blockedMaterials){
|
||||
// this.blockedMaterials = blockedMaterials;
|
||||
// }
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onClick(InventoryClickEvent event) {
|
||||
if (event.isCancelled() || event.getAction() == InventoryAction.NOTHING)
|
||||
return;
|
||||
|
||||
final boolean shift = event.getClick().equals(ClickType.SHIFT_LEFT) || event.getClick().equals(ClickType.SHIFT_RIGHT), numberkey = event.getClick().equals(ClickType.NUMBER_KEY);
|
||||
|
||||
if (event.getSlotType() != SlotType.ARMOR && event.getSlotType() != SlotType.QUICKBAR && event.getSlotType() != SlotType.CONTAINER)
|
||||
return;
|
||||
if (event.getClickedInventory() != null && !event.getClickedInventory().getType().equals(InventoryType.PLAYER))
|
||||
return;
|
||||
if (!event.getInventory().getType().equals(InventoryType.CRAFTING) && !event.getInventory().getType().equals(InventoryType.PLAYER))
|
||||
return;
|
||||
if (!(event.getWhoClicked() instanceof Player))
|
||||
return;
|
||||
ArmorType newArmorType = ArmorType.matchType(shift ? event.getCurrentItem() : event.getCursor());
|
||||
if (!shift && newArmorType != null && event.getRawSlot() != newArmorType.getSlot()) {
|
||||
// Used for drag and drop checking to make sure you aren't trying to
|
||||
// place a helmet in the boots slot.
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
newArmorType = ArmorType.matchType(event.getCurrentItem());
|
||||
if (newArmorType != null) {
|
||||
final boolean equipping = event.getRawSlot() != newArmorType.getSlot();
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
|
||||
if (equipping ? isAirOrNull(newArmorType.getItem(player)) : !isAirOrNull(newArmorType.getItem(player)))
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent((Player) event.getWhoClicked(), newArmorType, equipping ? null : event.getCurrentItem(), equipping ? event.getCurrentItem() : null));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// event.setCancelled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
} else {
|
||||
ItemStack newArmorPiece = event.getCursor();
|
||||
ItemStack oldArmorPiece = event.getCurrentItem();
|
||||
if (numberkey) {
|
||||
|
||||
// prevents shit in the 2v2 crafting
|
||||
if (event.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
|
||||
// event.getClickedInventory() == The players inventory
|
||||
// event.getHotBarButton() == key people are pressing to
|
||||
// equip
|
||||
// or unequip the item to or from.
|
||||
// event.getRawSlot() == The slot the item is going to.
|
||||
// event.getSlot() == Armor slot, can't use
|
||||
// event.getRawSlot() as
|
||||
// that gives a hotbar slot ;-;
|
||||
ItemStack hotbarItem = event.getClickedInventory().getItem(event.getHotbarButton());
|
||||
if (!isAirOrNull(hotbarItem)) {// Equipping
|
||||
newArmorType = ArmorType.matchType(hotbarItem);
|
||||
newArmorPiece = hotbarItem;
|
||||
oldArmorPiece = event.getClickedInventory().getItem(event.getSlot());
|
||||
} else // Unequipping
|
||||
newArmorType = ArmorType.matchType(!isAirOrNull(event.getCurrentItem()) ? event.getCurrentItem() : event.getCursor());
|
||||
}
|
||||
|
||||
// equip with no new item going into the slot
|
||||
} else if (isAirOrNull(event.getCursor()) && !isAirOrNull(event.getCurrentItem()))
|
||||
newArmorType = ArmorType.matchType(event.getCurrentItem());
|
||||
|
||||
// event.getCurrentItem() == Unequip
|
||||
// event.getCursor() == Equip
|
||||
// newArmorType =
|
||||
// ArmorType.matchType(!isAirOrNull(event.getCurrentItem()) ?
|
||||
// event.getCurrentItem() : event.getCursor());
|
||||
if (newArmorType != null && event.getRawSlot() == newArmorType.getSlot())
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent((Player) event.getWhoClicked(), newArmorType, oldArmorPiece, newArmorPiece));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// event.setCancelled(true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInteract(PlayerInteractEvent event) {
|
||||
if (event.getAction() == Action.PHYSICAL || (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK))
|
||||
return;
|
||||
|
||||
ArmorType type = ArmorType.matchType(event.getItem());
|
||||
if (type != null && isAirOrNull(type.getItem(event.getPlayer())))
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(event.getPlayer(), ArmorType.matchType(event.getItem()), null, event.getItem()));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// event.setCancelled(true);
|
||||
// player.updateInventory();
|
||||
// }
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
// getType() seems to always be even.
|
||||
// Old Cursor gives the item you are equipping
|
||||
// Raw slot is the ArmorType slot
|
||||
// Can't replace armor using this method making getCursor() useless.
|
||||
ArmorType type = ArmorType.matchType(event.getOldCursor());
|
||||
if (event.getRawSlots().isEmpty())
|
||||
return;// Idk if this will ever happen
|
||||
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0))
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent((Player) event.getWhoClicked(), type, null, event.getOldCursor()));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// event.setResult(Result.DENY);
|
||||
// event.setCancelled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onItemBreak(PlayerItemBreakEvent event) {
|
||||
ArmorType type = ArmorType.matchType(event.getBrokenItem());
|
||||
if (type != null)
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(event.getPlayer(), type, event.getBrokenItem(), null));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// ItemStack i = event.getBrokenItem().clone();
|
||||
// i.setAmount(1);
|
||||
// i.setDurability((short) (i.getDurability() - 1));
|
||||
// if(type.equals(ArmorType.HELMET)){
|
||||
// p.getInventory().setHelmet(i);
|
||||
// }else if(type.equals(ArmorType.CHESTPLATE)){
|
||||
// p.getInventory().setChestplate(i);
|
||||
// }else if(type.equals(ArmorType.LEGGINGS)){
|
||||
// p.getInventory().setLeggings(i);
|
||||
// }else if(type.equals(ArmorType.BOOTS)){
|
||||
// p.getInventory().setBoots(i);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
Player player = event.getEntity();
|
||||
for (ItemStack item : player.getInventory().getArmorContents())
|
||||
if (!isAirOrNull(item))
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(player, ArmorType.matchType(item), item, null));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDispense(BlockDispenseArmorEvent event) {
|
||||
ArmorType type = ArmorType.matchType(event.getItem());
|
||||
if (type != null && event.getTargetEntity() instanceof Player)
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent((Player) event.getTargetEntity(), type, null, event.getItem()));
|
||||
// if(armorEquipEvent.isCancelled()){
|
||||
// event.setCancelled(true);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to support versions that use null or air ItemStacks.
|
||||
*/
|
||||
private boolean isAirOrNull(ItemStack item) {
|
||||
return item == null || item.getType().equals(Material.AIR);
|
||||
}
|
||||
}
|
64
src/com/codingforcookies/armorequip/ArmorType.java
Normal file
64
src/com/codingforcookies/armorequip/ArmorType.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public enum ArmorType {
|
||||
HELMET(5, (inv) -> inv.getHelmet()),
|
||||
CHESTPLATE(6, (inv) -> inv.getChestplate()),
|
||||
LEGGINGS(7, (inv) -> inv.getLeggings()),
|
||||
BOOTS(8, (inv) -> inv.getBoots());
|
||||
|
||||
private final int slot;
|
||||
private final Function<PlayerInventory, ItemStack> handler;
|
||||
|
||||
private ArmorType(int slot, Function<PlayerInventory, ItemStack> handler) {
|
||||
this.slot = slot;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
public ItemStack getItem(Player player) {
|
||||
return handler.apply(player.getInventory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to match the ArmorType for the specified ItemStack.
|
||||
*
|
||||
* @param itemStack
|
||||
* The ItemStack to parse the type of.
|
||||
* @return The parsed ArmorType. (null if none were found.)
|
||||
*/
|
||||
public static ArmorType matchType(ItemStack item) {
|
||||
if (item == null || item.getType().equals(Material.AIR))
|
||||
return null;
|
||||
|
||||
Material type = item.getType();
|
||||
String name = type.name();
|
||||
if (name.endsWith("HELMET") || name.endsWith("SKULL") || name.endsWith("HEAD") || type == Material.PLAYER_HEAD || type == Material.PUMPKIN)
|
||||
return HELMET;
|
||||
|
||||
else if (name.endsWith("CHESTPLATE"))
|
||||
return CHESTPLATE;
|
||||
|
||||
else if (name.endsWith("LEGGINGS"))
|
||||
return LEGGINGS;
|
||||
|
||||
else if (name.endsWith("BOOTS"))
|
||||
return BOOTS;
|
||||
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
356
src/net/Indyuce/mmocore/MMOCore.java
Normal file
356
src/net/Indyuce/mmocore/MMOCore.java
Normal file
@ -0,0 +1,356 @@
|
||||
package net.Indyuce.mmocore;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.codingforcookies.armorequip.ArmorListener;
|
||||
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import net.Indyuce.mmocore.api.player.stats.StatType;
|
||||
import net.Indyuce.mmocore.command.AttributesCommand;
|
||||
import net.Indyuce.mmocore.command.ClassCommand;
|
||||
import net.Indyuce.mmocore.command.DepositCommand;
|
||||
import net.Indyuce.mmocore.command.FriendsCommand;
|
||||
import net.Indyuce.mmocore.command.MMOCoreCommand;
|
||||
import net.Indyuce.mmocore.command.PartyCommand;
|
||||
import net.Indyuce.mmocore.command.PlayerStatsCommand;
|
||||
import net.Indyuce.mmocore.command.QuestsCommand;
|
||||
import net.Indyuce.mmocore.command.SkillsCommand;
|
||||
import net.Indyuce.mmocore.command.WaypointsCommand;
|
||||
import net.Indyuce.mmocore.command.WithdrawCommand;
|
||||
import net.Indyuce.mmocore.comp.Metrics;
|
||||
import net.Indyuce.mmocore.comp.ShopKeepersEntityHandler;
|
||||
import net.Indyuce.mmocore.comp.citizens.CitizenInteractEventListener;
|
||||
import net.Indyuce.mmocore.comp.citizens.CitizensMMOLoader;
|
||||
import net.Indyuce.mmocore.comp.entity.MyPetEntityHandler;
|
||||
import net.Indyuce.mmocore.comp.holograms.CMIPlugin;
|
||||
import net.Indyuce.mmocore.comp.holograms.HologramSupport;
|
||||
import net.Indyuce.mmocore.comp.holograms.HologramsPlugin;
|
||||
import net.Indyuce.mmocore.comp.holograms.HolographicDisplaysPlugin;
|
||||
import net.Indyuce.mmocore.comp.mythicmobs.MythicMobsDrops;
|
||||
import net.Indyuce.mmocore.comp.mythicmobs.MythicMobsMMOLoader;
|
||||
import net.Indyuce.mmocore.comp.placeholder.DefaultParser;
|
||||
import net.Indyuce.mmocore.comp.placeholder.PlaceholderAPIParser;
|
||||
import net.Indyuce.mmocore.comp.placeholder.PlaceholderParser;
|
||||
import net.Indyuce.mmocore.comp.rpg.DefaultRPGUtilHandler;
|
||||
import net.Indyuce.mmocore.comp.rpg.RPGUtilHandler;
|
||||
import net.Indyuce.mmocore.comp.vault.VaultEconomy;
|
||||
import net.Indyuce.mmocore.comp.vault.VaultMMOLoader;
|
||||
import net.Indyuce.mmocore.comp.worldguard.DefaultRegionHandler;
|
||||
import net.Indyuce.mmocore.comp.worldguard.RegionHandler;
|
||||
import net.Indyuce.mmocore.comp.worldguard.WorldGuardMMOLoader;
|
||||
import net.Indyuce.mmocore.comp.worldguard.WorldGuardRegionHandler;
|
||||
import net.Indyuce.mmocore.listener.BlockListener;
|
||||
import net.Indyuce.mmocore.listener.GoldPouchesListener;
|
||||
import net.Indyuce.mmocore.listener.LootableChestsListener;
|
||||
import net.Indyuce.mmocore.listener.PartyListener;
|
||||
import net.Indyuce.mmocore.listener.PlayerListener;
|
||||
import net.Indyuce.mmocore.listener.SpellCast;
|
||||
import net.Indyuce.mmocore.listener.WaypointsListener;
|
||||
import net.Indyuce.mmocore.listener.event.PlayerAttackEventListener;
|
||||
import net.Indyuce.mmocore.listener.profession.FishingListener;
|
||||
import net.Indyuce.mmocore.listener.profession.PlayerCollectStats;
|
||||
import net.Indyuce.mmocore.manager.AttributeManager;
|
||||
import net.Indyuce.mmocore.manager.ClassManager;
|
||||
import net.Indyuce.mmocore.manager.ConfigItemManager;
|
||||
import net.Indyuce.mmocore.manager.ConfigManager;
|
||||
import net.Indyuce.mmocore.manager.CustomBlockManager;
|
||||
import net.Indyuce.mmocore.manager.DamageManager;
|
||||
import net.Indyuce.mmocore.manager.DropTableManager;
|
||||
import net.Indyuce.mmocore.manager.EntityManager;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import net.Indyuce.mmocore.manager.LootableChestManager;
|
||||
import net.Indyuce.mmocore.manager.MMOLoadManager;
|
||||
import net.Indyuce.mmocore.manager.QuestManager;
|
||||
import net.Indyuce.mmocore.manager.RestrictionManager;
|
||||
import net.Indyuce.mmocore.manager.SkillManager;
|
||||
import net.Indyuce.mmocore.manager.WaypointManager;
|
||||
import net.Indyuce.mmocore.manager.profession.AlchemyManager;
|
||||
import net.Indyuce.mmocore.manager.profession.EnchantManager;
|
||||
import net.Indyuce.mmocore.manager.profession.FishingManager;
|
||||
import net.Indyuce.mmocore.manager.profession.ProfessionManager;
|
||||
import net.Indyuce.mmocore.manager.profession.SmithingManager;
|
||||
import net.Indyuce.mmocore.manager.social.BoosterManager;
|
||||
import net.Indyuce.mmocore.manager.social.PartyManager;
|
||||
import net.Indyuce.mmocore.manager.social.RequestManager;
|
||||
import net.Indyuce.mmocore.version.ServerVersion;
|
||||
import net.Indyuce.mmocore.version.nms.NMSHandler;
|
||||
|
||||
public class MMOCore extends JavaPlugin {
|
||||
public static MMOCore plugin;
|
||||
|
||||
public final ClassManager classManager = new ClassManager();
|
||||
public ConfigManager configManager;
|
||||
public WaypointManager waypointManager;
|
||||
public RestrictionManager restrictionManager;
|
||||
public final DropTableManager dropTableManager = new DropTableManager();
|
||||
public final CustomBlockManager mineManager = new CustomBlockManager();
|
||||
public final BoosterManager boosterManager = new BoosterManager();
|
||||
public LootableChestManager chestManager;
|
||||
public RequestManager requestManager;
|
||||
public final AttributeManager attributeManager = new AttributeManager();
|
||||
public final PartyManager partyManager = new PartyManager();
|
||||
public final QuestManager questManager = new QuestManager();
|
||||
public ConfigItemManager configItems;
|
||||
public SkillManager skillManager;
|
||||
public final ProfessionManager professionManager = new ProfessionManager();
|
||||
public VaultEconomy economy;
|
||||
public HologramSupport hologramSupport;
|
||||
public PlaceholderParser placeholderParser = new DefaultParser();
|
||||
public final DamageManager damage = new DamageManager();
|
||||
public final EntityManager entities = new EntityManager();
|
||||
public NMSHandler nms;
|
||||
public ServerVersion version;
|
||||
public InventoryManager inventoryManager;
|
||||
public RegionHandler regionHandler;
|
||||
|
||||
/*
|
||||
* professions
|
||||
*/
|
||||
public final FishingManager fishingManager = new FishingManager();
|
||||
public final AlchemyManager alchemyManager = new AlchemyManager();
|
||||
public final EnchantManager enchantManager = new EnchantManager();
|
||||
public final SmithingManager smithingManager = new SmithingManager();
|
||||
|
||||
public final MMOLoadManager loadManager = new MMOLoadManager();
|
||||
public RPGUtilHandler rpgUtilHandler = new DefaultRPGUtilHandler();
|
||||
|
||||
public static final DecimalFormat digit = new DecimalFormat("0.#"), digit2 = new DecimalFormat("0.##"), digit3 = new DecimalFormat("0.###");
|
||||
public static final SimpleDateFormat smoothDateFormat = new SimpleDateFormat("");
|
||||
|
||||
public void onLoad() {
|
||||
plugin = this;
|
||||
version = new ServerVersion(Bukkit.getServer().getClass());
|
||||
|
||||
/*
|
||||
* register extra objective, drop items...
|
||||
*/
|
||||
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null)
|
||||
loadManager.registerLoader(new WorldGuardMMOLoader());
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Citizens") != null)
|
||||
loadManager.registerLoader(new CitizensMMOLoader());
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Vault") != null)
|
||||
loadManager.registerLoader(new VaultMMOLoader());
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null)
|
||||
loadManager.registerLoader(new MythicMobsMMOLoader());
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
|
||||
/*
|
||||
* decimal format
|
||||
*/
|
||||
DecimalFormatSymbols symbols = digit.getDecimalFormatSymbols();
|
||||
symbols.setDecimalSeparator('.');
|
||||
digit.setDecimalFormatSymbols(symbols);
|
||||
digit2.setDecimalFormatSymbols(symbols);
|
||||
digit3.setDecimalFormatSymbols(symbols);
|
||||
|
||||
try {
|
||||
getLogger().log(Level.INFO, "Detected Bukkit Version: " + version.toString());
|
||||
nms = (NMSHandler) Class.forName("net.Indyuce.mmocore.version.nms.NMSHandler_" + version.toString().substring(1)).newInstance();
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException exception) {
|
||||
getLogger().log(Level.INFO, "Your server version is not compatible.");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
new Metrics(this);
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Vault") != null)
|
||||
economy = new VaultEconomy();
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
placeholderParser = new PlaceholderAPIParser();
|
||||
getLogger().log(Level.INFO, "Hooked onto PlaceholderAPI");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("Citizens") != null) {
|
||||
Bukkit.getPluginManager().registerEvents(new CitizenInteractEventListener(), this);
|
||||
getLogger().log(Level.INFO, "Hooked onto Citizens");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
regionHandler = new WorldGuardRegionHandler();
|
||||
getLogger().log(Level.INFO, "Hooked onto WorldGuard");
|
||||
} else
|
||||
regionHandler = new DefaultRegionHandler();
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("HolographicDisplays") != null) {
|
||||
hologramSupport = new HolographicDisplaysPlugin();
|
||||
getLogger().log(Level.INFO, "Hooked onto HolographicDisplays");
|
||||
} else if (Bukkit.getPluginManager().getPlugin("CMI") != null) {
|
||||
hologramSupport = new CMIPlugin();
|
||||
getLogger().log(Level.INFO, "Hooked onto CMI Holograms");
|
||||
} else if (Bukkit.getPluginManager().getPlugin("Holograms") != null) {
|
||||
hologramSupport = new HologramsPlugin();
|
||||
getLogger().log(Level.INFO, "Hooked onto Holograms");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("ShopKeepers") != null) {
|
||||
entities.registerHandler(new ShopKeepersEntityHandler());
|
||||
getLogger().log(Level.INFO, "Hooked onto ShopKeepers");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("MyPet") != null) {
|
||||
entities.registerHandler(new MyPetEntityHandler());
|
||||
getLogger().log(Level.INFO, "Hooked onto MyPet");
|
||||
}
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) {
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new MythicMobsDrops(), this);
|
||||
getLogger().log(Level.INFO, "Hooked onto MythicMobs");
|
||||
}
|
||||
|
||||
/*
|
||||
* resource regeneration. must check if entity is dead otherwise regen
|
||||
* will make the 'respawn' button glitched plus HURT entity effect bug
|
||||
*/
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
for (PlayerData data : PlayerData.getAll())
|
||||
if (data.isOnline() && !data.getPlayer().isDead()) {
|
||||
|
||||
data.giveStellium(data.getStats().getStat(StatType.STELLIUM_REGENERATION));
|
||||
|
||||
if (data.canRegen(PlayerResource.HEALTH))
|
||||
data.heal(data.calculateRegen(PlayerResource.HEALTH));
|
||||
|
||||
if (data.canRegen(PlayerResource.MANA))
|
||||
data.giveMana(data.calculateRegen(PlayerResource.MANA));
|
||||
|
||||
if (data.canRegen(PlayerResource.STAMINA))
|
||||
data.giveMana(data.calculateRegen(PlayerResource.STAMINA));
|
||||
}
|
||||
}
|
||||
}.runTaskTimerAsynchronously(MMOCore.plugin, 100, 20);
|
||||
|
||||
saveDefaultConfig();
|
||||
reloadPlugin();
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerAttackEventListener(), this);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new DamageManager(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new WaypointsListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new BlockListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new LootableChestsListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new SpellCast(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PartyListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new FishingListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new ArmorListener(), this);
|
||||
|
||||
/*
|
||||
* initialize player data from all online players. this is very
|
||||
* important to do that after registering all the professses otherwise
|
||||
* the player datas can't recognize what profess the player has and
|
||||
* professes will be lost
|
||||
*/
|
||||
Bukkit.getOnlinePlayers().forEach(player -> PlayerData.setup(player).setPlayer(player));
|
||||
|
||||
// commands
|
||||
getCommand("player").setExecutor(new PlayerStatsCommand());
|
||||
getCommand("attributes").setExecutor(new AttributesCommand());
|
||||
getCommand("class").setExecutor(new ClassCommand());
|
||||
getCommand("waypoints").setExecutor(new WaypointsCommand());
|
||||
getCommand("quests").setExecutor(new QuestsCommand());
|
||||
getCommand("skills").setExecutor(new SkillsCommand());
|
||||
getCommand("friends").setExecutor(new FriendsCommand());
|
||||
getCommand("party").setExecutor(new PartyCommand());
|
||||
|
||||
if (hasEconomy() && economy.isValid()) {
|
||||
getCommand("withdraw").setExecutor(new WithdrawCommand());
|
||||
getCommand("deposit").setExecutor(new DepositCommand());
|
||||
}
|
||||
|
||||
MMOCoreCommand mmoCoreCommand = new MMOCoreCommand();
|
||||
getCommand("mmocore").setExecutor(mmoCoreCommand);
|
||||
getCommand("mmocore").setTabCompleter(mmoCoreCommand);
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
for (PlayerData playerData : PlayerData.getAll()) {
|
||||
ConfigFile config = new ConfigFile(playerData.getUniqueId());
|
||||
playerData.getQuestData().resetBossBar();
|
||||
playerData.saveInConfig(config.getConfig());
|
||||
config.save();
|
||||
}
|
||||
|
||||
mineManager.resetRemainingBlocks();
|
||||
}
|
||||
|
||||
public void reloadPlugin() {
|
||||
configManager = new ConfigManager();
|
||||
skillManager = new SkillManager();
|
||||
|
||||
mineManager.clear();
|
||||
mineManager.reload();
|
||||
|
||||
fishingManager.clear();
|
||||
alchemyManager.clear();
|
||||
smithingManager.clear();
|
||||
|
||||
partyManager.clear();
|
||||
partyManager.reload();
|
||||
|
||||
attributeManager.clear();
|
||||
attributeManager.reload();
|
||||
|
||||
professionManager.clear();
|
||||
professionManager.reload();
|
||||
|
||||
classManager.clear();
|
||||
classManager.reload();
|
||||
|
||||
inventoryManager = new InventoryManager();
|
||||
|
||||
dropTableManager.clear();
|
||||
dropTableManager.reload();
|
||||
|
||||
questManager.clear();
|
||||
questManager.reload();
|
||||
|
||||
chestManager = new LootableChestManager(new ConfigFile("chests").getConfig());
|
||||
waypointManager = new WaypointManager(new ConfigFile("waypoints").getConfig());
|
||||
restrictionManager = new RestrictionManager(new ConfigFile("restrictions").getConfig());
|
||||
requestManager = new RequestManager();
|
||||
configItems = new ConfigItemManager(new ConfigFile("items").getConfig());
|
||||
|
||||
StatType.load();
|
||||
}
|
||||
|
||||
public static void log(String message) {
|
||||
log(Level.INFO, message);
|
||||
}
|
||||
|
||||
public static void log(Level level, String message) {
|
||||
plugin.getLogger().log(level, message);
|
||||
}
|
||||
|
||||
public File getJarFile() {
|
||||
return getFile();
|
||||
}
|
||||
|
||||
public boolean hasHolograms() {
|
||||
return hologramSupport != null;
|
||||
}
|
||||
|
||||
public boolean hasEconomy() {
|
||||
return economy != null && economy.isValid();
|
||||
}
|
||||
}
|
186
src/net/Indyuce/mmocore/MMOCoreUtils.java
Normal file
186
src/net/Indyuce/mmocore/MMOCoreUtils.java
Normal file
@ -0,0 +1,186 @@
|
||||
package net.Indyuce.mmocore;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||
|
||||
public class MMOCoreUtils {
|
||||
public static boolean pluginItem(ItemStack item) {
|
||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
||||
}
|
||||
|
||||
public static String displayName(ItemStack item) {
|
||||
return item.hasItemMeta() && item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : caseOnWords(item.getType().name().replace("_", " "));
|
||||
}
|
||||
|
||||
public static String caseOnWords(String s) {
|
||||
StringBuilder builder = new StringBuilder(s);
|
||||
boolean isLastSpace = true;
|
||||
for (int item = 0; item < builder.length(); item++) {
|
||||
char ch = builder.charAt(item);
|
||||
if (isLastSpace && ch >= 'a' && ch <= 'z') {
|
||||
builder.setCharAt(item, (char) (ch + ('A' - 'a')));
|
||||
isLastSpace = false;
|
||||
} else if (ch != ' ')
|
||||
isLastSpace = false;
|
||||
else
|
||||
isLastSpace = true;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static ItemStack readIcon(String string) {
|
||||
try {
|
||||
Validate.notNull(string, "String cannot be null");
|
||||
String[] split = string.split("\\:");
|
||||
Material material = Material.valueOf(split[0].toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
return split.length > 1 ? MMOCore.plugin.version.getTextureHandler().textureItem(material, Integer.parseInt(split[1])) : new ItemStack(material);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
return new ItemStack(Material.BARRIER);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getWorth(ItemStack[] items) {
|
||||
int t = 0;
|
||||
for (ItemStack item : items)
|
||||
if (item != null && item.getType() != Material.AIR)
|
||||
t += MMOCore.plugin.nms.getNBTItem(item).getInt("RpgWorth") * item.getAmount();
|
||||
return t;
|
||||
}
|
||||
|
||||
public static String toBase64(ItemStack[] items) {
|
||||
try {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
|
||||
dataOutput.writeInt(items.length);
|
||||
for (int i = 0; i < items.length; i++)
|
||||
dataOutput.writeObject(items[i]);
|
||||
dataOutput.close();
|
||||
return Base64Coder.encodeLines(outputStream.toByteArray());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ItemStack[] itemStackArrayFromBase64(String data) {
|
||||
try {
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
|
||||
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
|
||||
ItemStack[] items = new ItemStack[dataInput.readInt()];
|
||||
for (int i = 0; i < items.length; i++)
|
||||
items[i] = (ItemStack) dataInput.readObject();
|
||||
dataInput.close();
|
||||
return items;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String intToRoman(int input) {
|
||||
if (input < 1 || input > 499)
|
||||
return ">499";
|
||||
|
||||
String s = "";
|
||||
while (input >= 400) {
|
||||
s += "CD";
|
||||
input -= 400;
|
||||
}
|
||||
while (input >= 100) {
|
||||
s += "C";
|
||||
input -= 100;
|
||||
}
|
||||
while (input >= 90) {
|
||||
s += "XC";
|
||||
input -= 90;
|
||||
}
|
||||
while (input >= 50) {
|
||||
s += "L";
|
||||
input -= 50;
|
||||
}
|
||||
while (input >= 40) {
|
||||
s += "XL";
|
||||
input -= 40;
|
||||
}
|
||||
while (input >= 10) {
|
||||
s += "X";
|
||||
input -= 10;
|
||||
}
|
||||
while (input >= 9) {
|
||||
s += "IX";
|
||||
input -= 9;
|
||||
}
|
||||
while (input >= 5) {
|
||||
s += "V";
|
||||
input -= 5;
|
||||
}
|
||||
while (input >= 4) {
|
||||
s += "IV";
|
||||
input -= 4;
|
||||
}
|
||||
while (input >= 1) {
|
||||
s += "I";
|
||||
input -= 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* method to get all entities surrounding a location. this method does not
|
||||
* take every entity in the world but rather takes all the entities from the
|
||||
* 9 chunks around the entity, so even if the location is at the border of a
|
||||
* chunk (worst case border of 4 chunks), the entity will still be included
|
||||
*/
|
||||
public static List<Entity> getNearbyChunkEntities(Location loc) {
|
||||
|
||||
/*
|
||||
* another method to save performance is if an entity bounding box
|
||||
* calculation is made twice in the same tick then the method does not
|
||||
* need to be called twice, it can utilize the same entity list since
|
||||
* the entities have not moved (e.g fireball which does 2+ calculations
|
||||
* per tick)
|
||||
*/
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
|
||||
int cx = loc.getChunk().getX();
|
||||
int cz = loc.getChunk().getZ();
|
||||
|
||||
for (int x = -1; x < 2; x++)
|
||||
for (int z = -1; z < 2; z++)
|
||||
for (Entity entity : loc.getWorld().getChunkAt(cx + x, cz + z).getEntities())
|
||||
entities.add(entity);
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
// TODO worldguard flags support for no target
|
||||
public static boolean canTarget(Player player, Entity target) {
|
||||
return !player.equals(target) && target instanceof LivingEntity && !target.isDead() && !MMOCore.plugin.entities.findCustom(target);
|
||||
}
|
||||
|
||||
public static void heal(LivingEntity target, double value) {
|
||||
|
||||
double max = target.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
double gain = Math.min(max, target.getHealth() + value) - target.getHealth();
|
||||
|
||||
EntityRegainHealthEvent event = new EntityRegainHealthEvent(target, gain, RegainReason.CUSTOM);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled())
|
||||
target.setHealth(target.getHealth() + gain);
|
||||
}
|
||||
}
|
27
src/net/Indyuce/mmocore/api/AltChar.java
Normal file
27
src/net/Indyuce/mmocore/api/AltChar.java
Normal file
@ -0,0 +1,27 @@
|
||||
package net.Indyuce.mmocore.api;
|
||||
|
||||
public class AltChar {
|
||||
public static final String gemSymbol = "۞";
|
||||
public static final String square = "█";
|
||||
public static final String star = "✦";
|
||||
public static final String rightArrow = "⇨";
|
||||
public static final String fourEdgedClub = "✤";
|
||||
|
||||
public static final String club = "♣";
|
||||
public static final String diamond = "◆";
|
||||
public static final String spade = "♤";
|
||||
public static final String heart = "♥";
|
||||
|
||||
public static final String note1 = "♩";
|
||||
public static final String note2 = "♪";
|
||||
public static final String doubleNote1 = "♫";
|
||||
public static final String doubleNote2 = "♬";
|
||||
|
||||
public static final String listDash = "►";
|
||||
public static final String smallListDash = "▸";
|
||||
|
||||
public static final String listSquare = "■";
|
||||
|
||||
public static final String ok = "✔";
|
||||
public static final String no = "✖";
|
||||
}
|
51
src/net/Indyuce/mmocore/api/ConfigFile.java
Normal file
51
src/net/Indyuce/mmocore/api/ConfigFile.java
Normal file
@ -0,0 +1,51 @@
|
||||
package net.Indyuce.mmocore.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class ConfigFile {
|
||||
private final File file;
|
||||
private final String name;
|
||||
private final FileConfiguration config;
|
||||
|
||||
public ConfigFile(Player player) {
|
||||
this(player.getUniqueId());
|
||||
}
|
||||
|
||||
public ConfigFile(UUID uuid) {
|
||||
this(MMOCore.plugin, "/userdata", uuid.toString());
|
||||
}
|
||||
|
||||
public ConfigFile(String name) {
|
||||
this(MMOCore.plugin, "", name);
|
||||
}
|
||||
|
||||
public ConfigFile(String folder, String name) {
|
||||
this(MMOCore.plugin, folder, name);
|
||||
}
|
||||
|
||||
public ConfigFile(Plugin plugin, String folder, String name) {
|
||||
config = YamlConfiguration.loadConfiguration(file = new File(plugin.getDataFolder() + folder, (this.name = name) + ".yml"));
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
config.save(file);
|
||||
} catch (IOException e2) {
|
||||
MMOCore.plugin.getLogger().log(Level.SEVERE, "Could not save " + name + ".yml!");
|
||||
}
|
||||
}
|
||||
}
|
43
src/net/Indyuce/mmocore/api/ConfigMessage.java
Normal file
43
src/net/Indyuce/mmocore/api/ConfigMessage.java
Normal file
@ -0,0 +1,43 @@
|
||||
package net.Indyuce.mmocore.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class ConfigMessage {
|
||||
private final List<String> messages;
|
||||
|
||||
public ConfigMessage(String key) {
|
||||
messages = MMOCore.plugin.configManager.getMessage(key);
|
||||
}
|
||||
|
||||
public ConfigMessage addPlaceholders(String... placeholders) {
|
||||
for (int n = 0; n < messages.size(); n++) {
|
||||
String line = messages.get(n);
|
||||
for (int j = 0; j < placeholders.length - 1; j += 2) {
|
||||
String placeholder = placeholders[j];
|
||||
if (line.contains("{" + placeholder + "}"))
|
||||
line = line.replace("{" + placeholder + "}", placeholders[j + 1]);
|
||||
}
|
||||
messages.set(n, line);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void send(CommandSender sender) {
|
||||
messages.forEach(line -> sender.sendMessage(ChatColor.translateAlternateColorCodes('&', line)));
|
||||
}
|
||||
|
||||
public void send(Collection<? extends Player> players) {
|
||||
players.forEach(player -> messages.forEach(line -> player.sendMessage(ChatColor.translateAlternateColorCodes('&', line))));
|
||||
}
|
||||
|
||||
public void sendAsJSon(Player player) {
|
||||
messages.forEach(line -> MMOCore.plugin.nms.sendJson(player, ChatColor.translateAlternateColorCodes('&', line)));
|
||||
}
|
||||
}
|
91
src/net/Indyuce/mmocore/api/Waypoint.java
Normal file
91
src/net/Indyuce/mmocore/api/Waypoint.java
Normal file
@ -0,0 +1,91 @@
|
||||
package net.Indyuce.mmocore.api;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class Waypoint {
|
||||
private final String id, name;
|
||||
private final Location loc;
|
||||
private final double radiusSquared, stellium;
|
||||
private final boolean def, sneak, dynamic;
|
||||
|
||||
public Waypoint(ConfigurationSection section) {
|
||||
Validate.notNull(section, "Could not load config section");
|
||||
|
||||
id = section.getName();
|
||||
|
||||
name = section.getString("name");
|
||||
Validate.notNull(name, "Could not load waypoint name");
|
||||
|
||||
String format = section.getString("location");
|
||||
Validate.notNull(format, "Could not read location");
|
||||
loc = readLocation(format);
|
||||
|
||||
stellium = section.getDouble("stellium");
|
||||
radiusSquared = Math.pow(section.getDouble("radius"), 2);
|
||||
def = section.getBoolean("default");
|
||||
sneak = section.contains("sneak") ? section.getBoolean("sneak") : true;
|
||||
dynamic = section.getBoolean("dynamic");
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public double getStelliumCost() {
|
||||
return stellium;
|
||||
}
|
||||
|
||||
public boolean hasSneakEnabled() {
|
||||
return sneak;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return def;
|
||||
}
|
||||
|
||||
public boolean isDynamic() {
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
public boolean isOnWaypoint(Player player) {
|
||||
return player.getWorld().equals(loc.getWorld()) && player.getLocation().distanceSquared(loc) < radiusSquared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof Waypoint && ((Waypoint) object).id.equals(id);
|
||||
}
|
||||
|
||||
private Location readLocation(String string) {
|
||||
String[] split = string.split("\\ ");
|
||||
|
||||
World world = Bukkit.getWorld(split[0]);
|
||||
Validate.notNull(world, "Could not find world " + world);
|
||||
|
||||
double x = Double.parseDouble(split[1]);
|
||||
double y = Double.parseDouble(split[2]);
|
||||
double z = Double.parseDouble(split[3]);
|
||||
float yaw = split.length > 4 ? (float) Double.parseDouble(split[4]) : 0;
|
||||
float pitch = split.length > 5 ? (float) Double.parseDouble(split[5]) : 0;
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
}
|
64
src/net/Indyuce/mmocore/api/droptable/DropTable.java
Normal file
64
src/net/Indyuce/mmocore/api/droptable/DropTable.java
Normal file
@ -0,0 +1,64 @@
|
||||
package net.Indyuce.mmocore.api.droptable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.load.MMOLoadException;
|
||||
|
||||
public class DropTable {
|
||||
private final String id;
|
||||
private final Set<DropItem> drops = new HashSet<>();
|
||||
|
||||
/*
|
||||
* cached in order to load other items.
|
||||
*/
|
||||
private ConfigurationSection loaded;
|
||||
|
||||
public DropTable(ConfigurationSection section) {
|
||||
id = section.getName();
|
||||
loaded = section;
|
||||
}
|
||||
|
||||
/*
|
||||
* must be loaded after since drop tables must be initialized first
|
||||
* otherwise no reference for drop table drop items.
|
||||
*/
|
||||
public DropTable load() {
|
||||
|
||||
List<String> list = loaded.getStringList("items");
|
||||
Validate.notNull(list, "Could not find drop item list");
|
||||
|
||||
for (String key : list)
|
||||
try {
|
||||
drops.add(MMOCore.plugin.loadManager.loadDropItem(new MMOLineConfig(key)));
|
||||
} catch (MMOLoadException exception) {
|
||||
exception.printConsole("DropTables", "drop item");
|
||||
}
|
||||
|
||||
loaded = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<ItemStack> collect() {
|
||||
List<ItemStack> total = new ArrayList<>();
|
||||
|
||||
for (DropItem item : drops)
|
||||
if (item.rollChance())
|
||||
item.collect(total);
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package net.Indyuce.mmocore.api.droptable.condition;
|
||||
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public abstract class Condition {
|
||||
private final String id;
|
||||
|
||||
public Condition(MMOLineConfig config) {
|
||||
this.id = config.getKey();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract boolean isMet(ConditionInstance entity);
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package net.Indyuce.mmocore.api.droptable.condition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class ConditionInstance {
|
||||
private final Entity entity;
|
||||
private final Location applied;
|
||||
private final List<String> regions;
|
||||
|
||||
public ConditionInstance(Entity entity) {
|
||||
this(entity, entity.getLocation());
|
||||
}
|
||||
|
||||
public ConditionInstance(Entity entity, Location applied) {
|
||||
this.entity = entity;
|
||||
this.regions = MMOCore.plugin.regionHandler.getRegions(this.applied = applied);
|
||||
|
||||
regions.add("__global__");
|
||||
}
|
||||
|
||||
public boolean isInRegion(String name) {
|
||||
return regions.contains(name);
|
||||
}
|
||||
|
||||
public Location getAppliedLocation() {
|
||||
return applied;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Stream<String> getRegionStream() {
|
||||
return regions.stream();
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package net.Indyuce.mmocore.api.droptable.condition;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public class WorldCondition extends Condition {
|
||||
private final List<String> names;
|
||||
|
||||
public WorldCondition(MMOLineConfig config) {
|
||||
super(config);
|
||||
|
||||
config.validate("name");
|
||||
names = Arrays.asList(config.getString("name").split("\\,"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
return names.contains(entity.getEntity().getWorld().getName());
|
||||
}
|
||||
}
|
39
src/net/Indyuce/mmocore/api/droptable/dropitem/DropItem.java
Normal file
39
src/net/Indyuce/mmocore/api/droptable/dropitem/DropItem.java
Normal file
@ -0,0 +1,39 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.math.formula.RandomAmount;
|
||||
|
||||
public abstract class DropItem {
|
||||
protected static final Random random = new Random();
|
||||
|
||||
private double chance;
|
||||
private RandomAmount amount;
|
||||
|
||||
public DropItem(MMOLineConfig config) {
|
||||
chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1;
|
||||
amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 0);
|
||||
}
|
||||
|
||||
public RandomAmount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public int rollAmount() {
|
||||
return amount.calculateInt();
|
||||
}
|
||||
|
||||
public boolean rollChance() {
|
||||
return random.nextDouble() < chance;
|
||||
}
|
||||
|
||||
public abstract void collect(List<ItemStack> total);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.droptable.DropTable;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public class DropTableDropItem extends DropItem {
|
||||
private DropTable dropTable;
|
||||
|
||||
public DropTableDropItem(MMOLineConfig config) {
|
||||
super(config);
|
||||
|
||||
config.validate("id");
|
||||
String id = config.getString("id");
|
||||
|
||||
Validate.isTrue(MMOCore.plugin.dropTableManager.has(id), "Could not find drop table " + id);
|
||||
this.dropTable = MMOCore.plugin.dropTableManager.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(List<ItemStack> total) {
|
||||
for (int j = 0; j < rollAmount(); j++)
|
||||
total.addAll(dropTable.collect());
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.item.CurrencyItem;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public class GoldDropItem extends DropItem {
|
||||
public GoldDropItem(MMOLineConfig config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(List<ItemStack> total) {
|
||||
total.add(new CurrencyItem("GOLD_COIN", 1, rollAmount()).build());
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.item.CurrencyItem;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public class NoteDropItem extends DropItem {
|
||||
private int min, max;
|
||||
|
||||
public NoteDropItem(MMOLineConfig config) {
|
||||
super(config);
|
||||
|
||||
config.validate("max", "min");
|
||||
|
||||
min = (int) config.getDouble("min");
|
||||
max = (int) config.getDouble("max");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(List<ItemStack> total) {
|
||||
total.add(new CurrencyItem("NOTE", random.nextInt(max - min + 1) + min, rollAmount()).build());
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
|
||||
public class VanillaDropItem extends DropItem {
|
||||
private final Material material;
|
||||
|
||||
public VanillaDropItem(MMOLineConfig config) {
|
||||
super(config);
|
||||
|
||||
config.validate("type");
|
||||
this.material = Material.valueOf(config.getString("type"));
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(List<ItemStack> total) {
|
||||
total.add(new ItemStack(material, rollAmount()));
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package net.Indyuce.mmocore.api.droptable.dropitem.fishing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.math.formula.RandomAmount;
|
||||
|
||||
public class FishingDropItem {
|
||||
private final RandomAmount experience, tugs;
|
||||
private final DropItem dropItem;
|
||||
|
||||
private final int minCoef, maxCoef;
|
||||
|
||||
public FishingDropItem(int minCoef, String value) {
|
||||
MMOLineConfig config = new MMOLineConfig(value);
|
||||
|
||||
config.validate("tugs", "experience");
|
||||
|
||||
tugs = new RandomAmount(config.getString("tugs"));
|
||||
experience = new RandomAmount(config.getString("experience"));
|
||||
|
||||
this.minCoef = minCoef;
|
||||
maxCoef = minCoef + (config.contains("coef") ? Math.min(1, config.getInt("coef")) : 1);
|
||||
|
||||
dropItem = MMOCore.plugin.loadManager.loadDropItem(config);
|
||||
}
|
||||
|
||||
public int getMinCoefficient() {
|
||||
return minCoef;
|
||||
}
|
||||
|
||||
public int getMaxCoefficient() {
|
||||
return maxCoef;
|
||||
}
|
||||
|
||||
public boolean matchesCoefficient(int n) {
|
||||
return n >= minCoef && n < maxCoef;
|
||||
}
|
||||
|
||||
public DropItem getItem() {
|
||||
return dropItem;
|
||||
}
|
||||
|
||||
public RandomAmount getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
public RandomAmount getTugs() {
|
||||
return tugs;
|
||||
}
|
||||
|
||||
public int rollExperience() {
|
||||
return experience.calculateInt();
|
||||
}
|
||||
|
||||
public int rollTugs() {
|
||||
return tugs.calculateInt();
|
||||
}
|
||||
|
||||
public DropItem getDropItem() {
|
||||
return dropItem;
|
||||
}
|
||||
|
||||
public ItemStack collect() {
|
||||
List<ItemStack> collect = new ArrayList<>();
|
||||
dropItem.collect(collect);
|
||||
return collect.stream().findAny().get();
|
||||
}
|
||||
}
|
119
src/net/Indyuce/mmocore/api/eco/Withdraw.java
Normal file
119
src/net/Indyuce/mmocore/api/eco/Withdraw.java
Normal file
@ -0,0 +1,119 @@
|
||||
package net.Indyuce.mmocore.api.eco;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.item.CurrencyItem;
|
||||
import net.Indyuce.mmocore.api.item.SmartGive;
|
||||
|
||||
public class Withdraw implements Listener {
|
||||
private static final Set<UUID> withdrawing = new HashSet<>();
|
||||
|
||||
private final Player player;
|
||||
|
||||
public Withdraw(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
if (isWithdrawing())
|
||||
return;
|
||||
|
||||
withdrawing.add(player.getUniqueId());
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("withdrawing"));
|
||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> close(), 20 * 20);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
HandlerList.unregisterAll(this);
|
||||
withdrawing.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean isWithdrawing() {
|
||||
return withdrawing.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void a(PlayerMoveEvent event) {
|
||||
if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ())
|
||||
return;
|
||||
|
||||
if (!event.getPlayer().equals(player))
|
||||
return;
|
||||
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("withdraw-cancel"));
|
||||
close();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void b(AsyncPlayerChatEvent event) {
|
||||
if (!event.getPlayer().equals(player))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
final int worth;
|
||||
try {
|
||||
worth = Integer.parseInt(event.getMessage());
|
||||
} catch (Exception e) {
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("wrong-number", "arg", event.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
int left = (int) (MMOCore.plugin.economy.getEconomy().getBalance(player) - worth);
|
||||
if (left < 0) {
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("not-enough-money", "left", "" + -left));
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> {
|
||||
MMOCore.plugin.economy.getEconomy().withdrawPlayer(player, worth);
|
||||
withdrawAlgorythm(worth);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("withdrew", "worth", "" + worth));
|
||||
});
|
||||
}
|
||||
|
||||
public void withdrawAlgorythm(int worth) {
|
||||
int note = worth / 10 * 10;
|
||||
int coins = worth - note;
|
||||
|
||||
SmartGive smart = new SmartGive(player);
|
||||
if (note > 0)
|
||||
smart.give(new CurrencyItem("NOTE", note).build());
|
||||
|
||||
ItemStack coinsItem = new CurrencyItem("GOLD_COIN", 1).build();
|
||||
coinsItem.setAmount(coins);
|
||||
smart.give(coinsItem);
|
||||
}
|
||||
|
||||
/*
|
||||
* extra safety
|
||||
*/
|
||||
@EventHandler
|
||||
public void c(PlayerQuitEvent event) {
|
||||
if (event.getPlayer().equals(player))
|
||||
close();
|
||||
}
|
||||
}
|
65
src/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java
Normal file
65
src/net/Indyuce/mmocore/api/event/CustomBlockMineEvent.java
Normal file
@ -0,0 +1,65 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.ExperienceInfo;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.CustomBlockManager.BlockInfo;
|
||||
|
||||
public class CustomBlockMineEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final Block block;
|
||||
private final List<ItemStack> drops;
|
||||
private final ExperienceInfo experience;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public CustomBlockMineEvent(PlayerData player, Block block, BlockInfo info) {
|
||||
super(player);
|
||||
|
||||
this.block = block;
|
||||
this.drops = info.collectDrops();
|
||||
this.experience = info.hasExperience() ? info.getExperience().newInfo() : null;
|
||||
}
|
||||
|
||||
public boolean hasGainedExperience() {
|
||||
return experience != null;
|
||||
}
|
||||
|
||||
public ExperienceInfo getGainedExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
public List<ItemStack> getDrops() {
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
44
src/net/Indyuce/mmocore/api/event/CustomPlayerFishEvent.java
Normal file
44
src/net/Indyuce/mmocore/api/event/CustomPlayerFishEvent.java
Normal file
@ -0,0 +1,44 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
public class CustomPlayerFishEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final DropItem caught;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public CustomPlayerFishEvent(PlayerData player, DropItem caught) {
|
||||
super(player);
|
||||
|
||||
this.caught = caught;
|
||||
}
|
||||
|
||||
public DropItem getCaught() {
|
||||
return caught;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
31
src/net/Indyuce/mmocore/api/event/EntityKillEntityEvent.java
Normal file
31
src/net/Indyuce/mmocore/api/event/EntityKillEntityEvent.java
Normal file
@ -0,0 +1,31 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
|
||||
public class EntityKillEntityEvent extends EntityEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final Entity target;
|
||||
|
||||
public EntityKillEntityEvent(Entity what, Entity target) {
|
||||
super(what);
|
||||
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Entity getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
64
src/net/Indyuce/mmocore/api/event/PlayerAttackEvent.java
Normal file
64
src/net/Indyuce/mmocore/api/event/PlayerAttackEvent.java
Normal file
@ -0,0 +1,64 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.comp.rpg.damage.DamageInfo;
|
||||
import net.Indyuce.mmocore.comp.rpg.damage.DamageInfo.DamageType;
|
||||
|
||||
public class PlayerAttackEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final EntityDamageByEntityEvent event;
|
||||
private final DamageInfo info;
|
||||
|
||||
public PlayerAttackEvent(PlayerData data, EntityDamageByEntityEvent event, DamageInfo info) {
|
||||
super(data);
|
||||
|
||||
this.event = event;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
event.setCancelled(value);
|
||||
}
|
||||
|
||||
public DamageInfo getDamageInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
// @Deprecated
|
||||
public boolean isWeapon() {
|
||||
return info.getTypes().contains(DamageType.WEAPON);
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return event.getEntity();
|
||||
}
|
||||
|
||||
public double getDamage() {
|
||||
return event.getDamage();
|
||||
}
|
||||
|
||||
public void setDamage(double value) {
|
||||
event.setDamage(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
44
src/net/Indyuce/mmocore/api/event/PlayerCastSkillEvent.java
Normal file
44
src/net/Indyuce/mmocore/api/event/PlayerCastSkillEvent.java
Normal file
@ -0,0 +1,44 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.skill.Skill.SkillInfo;
|
||||
|
||||
public class PlayerCastSkillEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final SkillInfo skill;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerCastSkillEvent(PlayerData playerData, SkillInfo skill) {
|
||||
super(playerData);
|
||||
|
||||
this.skill = skill;
|
||||
}
|
||||
|
||||
public SkillInfo getCast() {
|
||||
return skill;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
|
||||
public class PlayerChangeClassEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final PlayerClass newClass;
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public PlayerChangeClassEvent(PlayerData player, PlayerClass newClass) {
|
||||
super(player);
|
||||
|
||||
this.newClass = newClass;
|
||||
}
|
||||
|
||||
public PlayerClass getNewClass() {
|
||||
return newClass;
|
||||
}
|
||||
|
||||
public boolean isSubclass() {
|
||||
return getData().getProfess().getSubclasses().stream().filter(sub -> sub.getProfess().equals(newClass)).count() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
30
src/net/Indyuce/mmocore/api/event/PlayerCombatEvent.java
Normal file
30
src/net/Indyuce/mmocore/api/event/PlayerCombatEvent.java
Normal file
@ -0,0 +1,30 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
public class PlayerCombatEvent extends PlayerDataEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final boolean enter;
|
||||
|
||||
public PlayerCombatEvent(PlayerData playerData, boolean enter) {
|
||||
super(playerData);
|
||||
|
||||
this.enter = enter;
|
||||
}
|
||||
|
||||
public boolean entersCombat() {
|
||||
return enter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
19
src/net/Indyuce/mmocore/api/event/PlayerDataEvent.java
Normal file
19
src/net/Indyuce/mmocore/api/event/PlayerDataEvent.java
Normal file
@ -0,0 +1,19 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
public abstract class PlayerDataEvent extends PlayerEvent {
|
||||
private final PlayerData playerData;
|
||||
|
||||
public PlayerDataEvent(PlayerData playerData) {
|
||||
super(playerData.getPlayer());
|
||||
|
||||
this.playerData = playerData;
|
||||
}
|
||||
|
||||
public PlayerData getData() {
|
||||
return playerData;
|
||||
}
|
||||
}
|
46
src/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java
Normal file
46
src/net/Indyuce/mmocore/api/event/PlayerLevelUpEvent.java
Normal file
@ -0,0 +1,46 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
public class PlayerLevelUpEvent extends PlayerDataEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
// if null, this is main level
|
||||
private final Profession profession;
|
||||
private final int level;
|
||||
|
||||
public PlayerLevelUpEvent(PlayerData player, int level) {
|
||||
this(player, null, level);
|
||||
}
|
||||
|
||||
public PlayerLevelUpEvent(PlayerData player, Profession profession, int level) {
|
||||
super(player);
|
||||
|
||||
this.profession = profession;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getNewLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public boolean hasProfession() {
|
||||
return profession != null;
|
||||
}
|
||||
|
||||
public Profession getProfession() {
|
||||
return profession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
54
src/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java
Normal file
54
src/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java
Normal file
@ -0,0 +1,54 @@
|
||||
package net.Indyuce.mmocore.api.event.social;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import net.Indyuce.mmocore.api.event.PlayerDataEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.social.Party;
|
||||
|
||||
public class PartyChatEvent extends PlayerDataEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final Party party;
|
||||
|
||||
private boolean cancelled;
|
||||
private String message;
|
||||
|
||||
public PartyChatEvent(PlayerData playerData, String message) {
|
||||
super(playerData);
|
||||
this.party = playerData.getParty();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Party getParty() {
|
||||
return party;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
70
src/net/Indyuce/mmocore/api/experience/Booster.java
Normal file
70
src/net/Indyuce/mmocore/api/experience/Booster.java
Normal file
@ -0,0 +1,70 @@
|
||||
package net.Indyuce.mmocore.api.experience;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Booster {
|
||||
private final UUID uuid = UUID.randomUUID();
|
||||
private final long date = System.currentTimeMillis(), length;
|
||||
private final Profession profession;
|
||||
private final double extra;
|
||||
private final String author;
|
||||
|
||||
public Booster(double extra, long length) {
|
||||
this(null, null, extra, length);
|
||||
}
|
||||
|
||||
public Booster(String author, double extra, long length) {
|
||||
this(author, null, extra, length);
|
||||
}
|
||||
|
||||
public Booster(String author, Profession profession, double extra, long length) {
|
||||
this.author = author;
|
||||
this.length = length * 1000;
|
||||
this.profession = profession;
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public boolean isTimedOut() {
|
||||
return date + length < System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getLeft() {
|
||||
return Math.max(0, date + length - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public long getCreationDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public boolean hasProfession() {
|
||||
return profession != null;
|
||||
}
|
||||
|
||||
public Profession getProfession() {
|
||||
return profession;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public double calculateExp(double exp) {
|
||||
return exp * (1 + extra);
|
||||
}
|
||||
|
||||
public double getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public boolean hasAuthor() {
|
||||
return author != null;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
}
|
19
src/net/Indyuce/mmocore/api/experience/ExperienceInfo.java
Normal file
19
src/net/Indyuce/mmocore/api/experience/ExperienceInfo.java
Normal file
@ -0,0 +1,19 @@
|
||||
package net.Indyuce.mmocore.api.experience;
|
||||
|
||||
public class ExperienceInfo {
|
||||
private final Profession profess;
|
||||
private final int value;
|
||||
|
||||
public ExperienceInfo(int value, Profession profess) {
|
||||
this.value = value;
|
||||
this.profess = profess;
|
||||
}
|
||||
|
||||
public Profession getProfession() {
|
||||
return profess;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
119
src/net/Indyuce/mmocore/api/experience/Profession.java
Normal file
119
src/net/Indyuce/mmocore/api/experience/Profession.java
Normal file
@ -0,0 +1,119 @@
|
||||
package net.Indyuce.mmocore.api.experience;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.load.MMOLoadException;
|
||||
import net.Indyuce.mmocore.api.math.formula.LinearValue;
|
||||
|
||||
public class Profession {
|
||||
private final String id, name;
|
||||
|
||||
private final LinearValue experience;
|
||||
|
||||
/*
|
||||
* removed when loaded
|
||||
*/
|
||||
private FileConfiguration config;
|
||||
|
||||
public Profession(String id, FileConfiguration config) {
|
||||
this.id = id.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
this.config = config;
|
||||
|
||||
this.name = config.getString("name");
|
||||
Validate.notNull(name, "Could not load name");
|
||||
|
||||
experience = new LinearValue(config.getConfigurationSection("experience"));
|
||||
|
||||
if (config.contains("exp-sources"))
|
||||
for (String key : config.getStringList("exp-sources"))
|
||||
try {
|
||||
MMOCore.plugin.professionManager.registerExpSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this));
|
||||
} catch (MMOLoadException exception) {
|
||||
exception.printConsole("Professions", "exp source");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* drop tables must be loaded after professions are initialized
|
||||
*/
|
||||
public void loadOptions() {
|
||||
|
||||
if (config.contains("on-fish"))
|
||||
MMOCore.plugin.fishingManager.loadDropTables(config.getConfigurationSection("on-fish"));
|
||||
|
||||
if (config.contains("on-mine"))
|
||||
MMOCore.plugin.mineManager.loadDropTables(config.getConfigurationSection("on-mine"));
|
||||
|
||||
if (config.contains("alchemy-experience")) {
|
||||
|
||||
MMOCore.plugin.alchemyManager.splash = 1 + config.getDouble("alchemy-experience.special.splash") / 100;
|
||||
MMOCore.plugin.alchemyManager.lingering = 1 + config.getDouble("alchemy-experience.special.lingering") / 100;
|
||||
MMOCore.plugin.alchemyManager.extend = 1 + config.getDouble("alchemy-experience.special.extend") / 100;
|
||||
MMOCore.plugin.alchemyManager.upgrade = 1 + config.getDouble("alchemy-experience.special.upgrade") / 100;
|
||||
|
||||
for (String key : config.getConfigurationSection("alchemy-experience.effects").getKeys(false))
|
||||
try {
|
||||
PotionType type = PotionType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
MMOCore.plugin.alchemyManager.registerBaseExperience(type, config.getDouble("alchemy-experience.effects." + key));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "[Professions:" + id + "] Could not read potion type from " + key);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.contains("base-enchant-exp"))
|
||||
for (String key : config.getConfigurationSection("base-enchant-exp").getKeys(false))
|
||||
try {
|
||||
Enchantment enchant = Enchantment.getByKey(NamespacedKey.minecraft(key.toLowerCase().replace("-", "_")));
|
||||
MMOCore.plugin.enchantManager.registerBaseExperience(enchant, config.getDouble("base-enchant-exp." + key));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "[Professions:" + id + "] Could not read enchant from " + key);
|
||||
}
|
||||
|
||||
if (config.contains("repair-exp"))
|
||||
for (String key : config.getConfigurationSection("repair-exp").getKeys(false))
|
||||
try {
|
||||
Material material = Material.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
MMOCore.plugin.smithingManager.registerBaseExperience(material, config.getDouble("repair-exp." + key));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "[Professions:" + id + "] Could not read material from " + key);
|
||||
}
|
||||
|
||||
// if (config.contains("effect-weight"))
|
||||
// for (String key :
|
||||
// config.getConfigurationSection("effect-weight").getKeys(false))
|
||||
// try {
|
||||
// MMOCore.plugin.alchemyManager.registerEffectWeight(PotionEffectType.getByName(key.toUpperCase().replace("-",
|
||||
// "_").replace(" ", "_")), config.getDouble("effect-weight." + key));
|
||||
// } catch (IllegalArgumentException exception) {
|
||||
// MMOCore.log(Level.WARNING, "[Professions:" + id + "] Could not read
|
||||
// potion effect type from " + key);
|
||||
// }
|
||||
|
||||
config = null;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int calculateExperience(int x) {
|
||||
return (int) experience.calculate(x);
|
||||
}
|
||||
|
||||
public LinearValue getExperience() {
|
||||
return experience;
|
||||
}
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.inventory.BrewEvent;
|
||||
import org.bukkit.inventory.BrewerInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
|
||||
private final List<PotionType> types = new ArrayList<>();
|
||||
|
||||
public BrewPotionExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession);
|
||||
|
||||
if (config.contains("effect"))
|
||||
for (String key : config.getString("effect").split("\\,"))
|
||||
types.add(PotionType.valueOf(key.toUpperCase().replace("-", "_")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, PotionMeta meta) {
|
||||
return hasRightClass(player) && (types.isEmpty() || new ArrayList<>(types).stream().filter(type -> meta.getBasePotionData().getType() == type).count() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<BrewPotionExperienceSource> newManager() {
|
||||
return new ExperienceManager<BrewPotionExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void a(BrewEvent event) {
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
|
||||
Optional<Player> playerOpt = getNearbyPlayer(event.getBlock().getLocation(), 10);
|
||||
if (!playerOpt.isPresent())
|
||||
return;
|
||||
|
||||
final ItemStack found = findPotion(event.getContents());
|
||||
if (found != null)
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||
ItemStack brewn = findPotion(event.getContents());
|
||||
if (brewn == null)
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(playerOpt.get());
|
||||
for (BrewPotionExperienceSource source : getSources())
|
||||
if (source.matches(data, (PotionMeta) brewn.getItemMeta()))
|
||||
new PotionUpgrade(found, brewn).process(data.getPlayer());
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ItemStack findPotion(BrewerInventory inv) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
ItemStack item = inv.getItem(j);
|
||||
if (item != null && item.hasItemMeta() && item.getItemMeta() instanceof PotionMeta)
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<Player> getNearbyPlayer(Location loc, double d) {
|
||||
double d2 = d * d;
|
||||
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < d2).findAny();
|
||||
}
|
||||
|
||||
public class PotionUpgrade {
|
||||
|
||||
/*
|
||||
* if the potion was extended using redstone or upgraded using
|
||||
* glowstone. PREPARE corresponds to when a water bottle is prepared for
|
||||
* later recipes using NETHER STALK
|
||||
*/
|
||||
private double exp;
|
||||
|
||||
// private final PotionMeta old, brewn;
|
||||
|
||||
public PotionUpgrade(ItemStack old, ItemStack brewn) {
|
||||
this(old.getType(), (PotionMeta) old.getItemMeta(), brewn.getType(), (PotionMeta) brewn.getItemMeta());
|
||||
}
|
||||
|
||||
public PotionUpgrade(Material oldPot, PotionMeta old, Material brewnPot, PotionMeta brewn) {
|
||||
|
||||
// this.old = old;
|
||||
// this.brewn = brewn;
|
||||
|
||||
/*
|
||||
* calculate base exp
|
||||
*/
|
||||
|
||||
exp += MMOCore.plugin.alchemyManager.getBaseExperience(brewn.getBasePotionData().getType());
|
||||
|
||||
// !old.getBasePotionData().getType().isUpgradeable() &&
|
||||
// brewn.getBasePotionData().getType().isUpgradeable(),
|
||||
//
|
||||
// !old.getBasePotionData().isExtended() &&
|
||||
// brewn.getBasePotionData().isExtended(),
|
||||
//
|
||||
// !old.getBasePotionData().isUpgraded() &&
|
||||
// brewn.getBasePotionData().isUpgraded());
|
||||
|
||||
/*
|
||||
* EXP modifiers based on brewing conditions
|
||||
*/
|
||||
if (oldPot == Material.POTION && brewnPot == Material.SPLASH_POTION)
|
||||
exp *= MMOCore.plugin.alchemyManager.splash;
|
||||
if (oldPot == Material.POTION && brewnPot == Material.LINGERING_POTION)
|
||||
exp *= MMOCore.plugin.alchemyManager.lingering;
|
||||
if (!old.getBasePotionData().isExtended() && brewn.getBasePotionData().isExtended())
|
||||
exp *= MMOCore.plugin.alchemyManager.extend;
|
||||
if (!old.getBasePotionData().isUpgraded() && brewn.getBasePotionData().isUpgraded())
|
||||
exp *= MMOCore.plugin.alchemyManager.upgrade;
|
||||
}
|
||||
|
||||
// private Map<PotionEffectType, Double> mapEffectDurations() {
|
||||
// Map<PotionEffectType, Double> map = new HashMap<>();
|
||||
//
|
||||
// /*
|
||||
// * potion level, plus the potion gained duration (max 0 so it does
|
||||
// * not give negative EXP), multiplied by the potion effect weight.
|
||||
// */
|
||||
// brewn.getCustomEffects().forEach(effect -> map.put(effect.getType(),
|
||||
//
|
||||
// (effect.getAmplifier() + 1 + (double) Math.max(0,
|
||||
// effect.getDuration() - getPotionEffect(old,
|
||||
// effect.getType()).orElseGet(() -> new
|
||||
// PotionEffect(PotionEffectType.SPEED, 0, 0)).getDuration()) / 60.)
|
||||
//
|
||||
// * MMOCore.plugin.alchemyManager.getWeight(effect.getType())));
|
||||
//
|
||||
// return map;
|
||||
// }
|
||||
|
||||
// private int getTotal(Map<?, Double> map) {
|
||||
// double t = 0;
|
||||
// for (double d : map.values())
|
||||
// t += d;
|
||||
// return (int) t;
|
||||
// }
|
||||
|
||||
// private Optional<PotionEffect> getPotionEffect(PotionMeta meta,
|
||||
// PotionEffectType type) {
|
||||
// return meta.getCustomEffects().stream().filter(effect ->
|
||||
// effect.getType() == type).findFirst();
|
||||
// }
|
||||
|
||||
public void process(Player player) {
|
||||
|
||||
/*
|
||||
* calculate extra exp due to extra effects
|
||||
*/
|
||||
// exp += getTotal(mapEffectDurations());
|
||||
|
||||
giveExperience(PlayerData.get(player), (int) exp);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.enchantment.EnchantItemEvent;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class EnchantItemExperienceSource extends ExperienceSource<Void> {
|
||||
private final List<Enchantment> enchants = new ArrayList<>();
|
||||
|
||||
public EnchantItemExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession);
|
||||
|
||||
if (config.contains("enchant"))
|
||||
for (String key : config.getString("enchant").split("\\,"))
|
||||
enchants.add(Enchantment.getByKey(NamespacedKey.minecraft(key.toLowerCase().replace("-", "_"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, Void v) {
|
||||
return hasRightClass(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<EnchantItemExperienceSource> newManager() {
|
||||
return new ExperienceManager<EnchantItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void a(EnchantItemEvent event) {
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
|
||||
PlayerData player = PlayerData.get(event.getEnchanter());
|
||||
for (EnchantItemExperienceSource source : getSources())
|
||||
if (source.matches(player, null)) {
|
||||
Map<Enchantment, Integer> ench = new HashMap<>(event.getEnchantsToAdd());
|
||||
|
||||
if (!enchants.isEmpty())
|
||||
for (Iterator<Enchantment> iterator = ench.keySet().iterator(); iterator.hasNext();)
|
||||
if (!enchants.contains(iterator.next()))
|
||||
iterator.remove();
|
||||
|
||||
if (ench.isEmpty())
|
||||
continue;
|
||||
|
||||
double exp = 0;
|
||||
for (Entry<Enchantment, Integer> entry : ench.entrySet())
|
||||
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
|
||||
giveExperience(player, (int) exp);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent.State;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class FishItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||
private final Material material;
|
||||
|
||||
public FishItemExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession, config);
|
||||
|
||||
config.validate("type");
|
||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<FishItemExperienceSource> newManager() {
|
||||
return new ExperienceManager<FishItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void a(PlayerFishEvent event) {
|
||||
if (!event.isCancelled() && event.getState() == State.CAUGHT_FISH) {
|
||||
ItemStack caught = ((Item) event.getCaught()).getItemStack();
|
||||
if (caught.hasItemMeta())
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (FishItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught))
|
||||
source.giveExperience(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, ItemStack obj) {
|
||||
return hasRightClass(player) && obj.getType() == material;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import net.Indyuce.mmocore.api.event.EntityKillEntityEvent;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
||||
private final EntityType type;
|
||||
|
||||
public KillMobExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession, config);
|
||||
|
||||
config.validate("type");
|
||||
type = EntityType.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<KillMobExperienceSource> newManager() {
|
||||
return new ExperienceManager<KillMobExperienceSource>() {
|
||||
|
||||
@EventHandler
|
||||
public void a(EntityKillEntityEvent event) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
PlayerData data = PlayerData.get((Player) event.getEntity());
|
||||
for (KillMobExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getTarget()))
|
||||
source.giveExperience(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, Entity obj) {
|
||||
return hasRightClass(player) && obj.getType() == type;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class MineBlockExperienceSource extends SpecificExperienceSource<Material> {
|
||||
private final Material material;
|
||||
private final boolean silkTouch;
|
||||
|
||||
public MineBlockExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession, config);
|
||||
|
||||
config.validate("type");
|
||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
silkTouch = config.getBoolean("silk-touch", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<MineBlockExperienceSource> newManager() {
|
||||
return new ExperienceManager<MineBlockExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void a(BlockBreakEvent event) {
|
||||
if (event.isCancelled() || event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
||||
return;
|
||||
|
||||
if (silkTouch && hasSilkTouch(event.getPlayer().getInventory().getItemInMainHand()))
|
||||
return;
|
||||
|
||||
Material broken = event.getBlock().getType();
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (MineBlockExperienceSource source : getSources())
|
||||
if (source.matches(data, broken))
|
||||
source.giveExperience(data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean hasSilkTouch(ItemStack item) {
|
||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, Material obj) {
|
||||
return material == obj && hasRightClass(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
|
||||
private final Material material;
|
||||
|
||||
public RepairItemExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession);
|
||||
|
||||
/*
|
||||
* if material is null, the player can repair ANY material in order to
|
||||
* get experience.
|
||||
*/
|
||||
material = config.contains("type") ? Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_")) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, ItemStack item) {
|
||||
return (material == null || item.getType() == material) && hasRightClass(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<RepairItemExperienceSource> newManager() {
|
||||
return new ExperienceManager<RepairItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void a(InventoryClickEvent event) {
|
||||
if (!event.isCancelled() && event.getInventory() != null && event.getInventory().getType() == InventoryType.ANVIL && event.getSlot() == 2) {
|
||||
|
||||
ItemStack item = event.getCurrentItem();
|
||||
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
||||
|
||||
for (RepairItemExperienceSource source : getSources())
|
||||
if (source.matches(data, item)) {
|
||||
/*
|
||||
* make sure the items can actually be repaired
|
||||
* before getting the amount of durability repaired
|
||||
*/
|
||||
ItemStack old = event.getInventory().getItem(0);
|
||||
if (old.getType().getMaxDurability() < 30 || item.getType().getMaxDurability() < 10)
|
||||
return;
|
||||
|
||||
if (!MMOCore.plugin.smithingManager.hasExperience(item.getType()))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* calculate exp based on amount of durability which
|
||||
* was repaired, substract damage from old item
|
||||
* durability.
|
||||
*/
|
||||
double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType()) * Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100;
|
||||
giveExperience(data, (int) exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package net.Indyuce.mmocore.api.experience.source;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockCookEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public class SmeltItemExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||
private final Material material;
|
||||
|
||||
public SmeltItemExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession, config);
|
||||
|
||||
config.validate("type");
|
||||
material = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceManager<SmeltItemExperienceSource> newManager() {
|
||||
return new ExperienceManager<SmeltItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void a(BlockCookEvent event) {
|
||||
if (!event.isCancelled()) {
|
||||
Optional<Player> player = getNearbyPlayer(event.getBlock().getLocation(), 10);
|
||||
if (!player.isPresent())
|
||||
return;
|
||||
|
||||
ItemStack caught = event.getResult();
|
||||
if (caught.hasItemMeta())
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(player.get());
|
||||
for (SmeltItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught))
|
||||
source.giveExperience(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Optional<Player> getNearbyPlayer(Location loc, double d) {
|
||||
double d2 = d * d;
|
||||
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < d2).findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlayerData player, ItemStack obj) {
|
||||
return obj.getType() == material && hasRightClass(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package net.Indyuce.mmocore.api.experience.source.type;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceManager;
|
||||
|
||||
public abstract class ExperienceSource<T> {
|
||||
private final Profession profession;
|
||||
private PlayerClass profess;
|
||||
|
||||
public ExperienceSource(Profession profession) {
|
||||
this(profession, null);
|
||||
}
|
||||
|
||||
public ExperienceSource(PlayerClass profess) {
|
||||
this(null, profess);
|
||||
}
|
||||
|
||||
public ExperienceSource(Profession profession, PlayerClass profess) {
|
||||
this.profession = profession;
|
||||
this.profess = profess;
|
||||
}
|
||||
|
||||
public void setClass(PlayerClass profess) {
|
||||
this.profess = profess;
|
||||
}
|
||||
|
||||
public boolean hasRightClass(PlayerData data) {
|
||||
return profess == null || profess.equals(data.getProfess());
|
||||
}
|
||||
|
||||
public boolean hasProfession() {
|
||||
return profession != null;
|
||||
}
|
||||
|
||||
public boolean hasClass() {
|
||||
return profess != null;
|
||||
}
|
||||
|
||||
public abstract ExperienceManager<?> newManager();
|
||||
|
||||
public abstract boolean matches(PlayerData player, T obj);
|
||||
|
||||
public void giveExperience(PlayerData player, int amount) {
|
||||
if (hasProfession())
|
||||
player.getCollectionSkills().giveExperience(profession, amount);
|
||||
else
|
||||
player.giveExperience(amount);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package net.Indyuce.mmocore.api.experience.source.type;
|
||||
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.load.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.math.formula.RandomAmount;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
public abstract class SpecificExperienceSource<T> extends ExperienceSource<T> {
|
||||
private final RandomAmount amount;
|
||||
|
||||
/*
|
||||
* not all experience sources have to specify a random experience amount e.g
|
||||
* ENCHANT and ALCHEMY experience depend on the enchanted item.
|
||||
*/
|
||||
public SpecificExperienceSource(Profession profession, MMOLineConfig config) {
|
||||
super(profession);
|
||||
|
||||
config.validate("amount");
|
||||
amount = new RandomAmount(config.getString("amount"));
|
||||
}
|
||||
|
||||
public RandomAmount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int rollAmount() {
|
||||
return amount.calculateInt();
|
||||
}
|
||||
|
||||
public void giveExperience(PlayerData player) {
|
||||
giveExperience(player, rollAmount());
|
||||
}
|
||||
}
|
70
src/net/Indyuce/mmocore/api/input/AnvilGUI.java
Normal file
70
src/net/Indyuce/mmocore/api/input/AnvilGUI.java
Normal file
@ -0,0 +1,70 @@
|
||||
package net.Indyuce.mmocore.api.input;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.util.Consumer;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class AnvilGUI extends PlayerInput {
|
||||
private final int containerId;
|
||||
private final Inventory inventory;
|
||||
|
||||
public AnvilGUI(Player player, InputType type, Consumer<String> output) {
|
||||
super(player, output);
|
||||
|
||||
ItemStack paper = new ItemStack(Material.PAPER);
|
||||
ItemMeta paperMeta = paper.getItemMeta();
|
||||
paperMeta.setDisplayName(MMOCore.plugin.configManager.getSimpleMessage("player-input.anvil." + type.getLowerCaseName()));
|
||||
paper.setItemMeta(paperMeta);
|
||||
|
||||
MMOCore.plugin.nms.handleInventoryCloseEvent(player);
|
||||
MMOCore.plugin.nms.setActiveContainerDefault(player);
|
||||
|
||||
final Object container = MMOCore.plugin.nms.newContainerAnvil(player);
|
||||
|
||||
inventory = MMOCore.plugin.nms.toBukkitInventory(container);
|
||||
inventory.setItem(0, paper);
|
||||
|
||||
containerId = MMOCore.plugin.nms.getNextContainerId(player);
|
||||
MMOCore.plugin.nms.sendPacketOpenWindow(player, containerId);
|
||||
MMOCore.plugin.nms.setActiveContainer(player, container);
|
||||
MMOCore.plugin.nms.setActiveContainerId(container, containerId);
|
||||
MMOCore.plugin.nms.addActiveContainerSlotListener(container, player);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
MMOCore.plugin.nms.handleInventoryCloseEvent(getPlayer());
|
||||
MMOCore.plugin.nms.setActiveContainerDefault(getPlayer());
|
||||
MMOCore.plugin.nms.sendPacketCloseWindow(getPlayer(), containerId);
|
||||
|
||||
InventoryClickEvent.getHandlerList().unregister(this);
|
||||
InventoryCloseEvent.getHandlerList().unregister(this);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void a(InventoryClickEvent event) {
|
||||
if (event.getInventory().equals(inventory)) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (event.getRawSlot() == 2) {
|
||||
ItemStack clicked = inventory.getItem(event.getRawSlot());
|
||||
if (clicked != null && clicked.getType() != Material.AIR)
|
||||
getOutput().accept(clicked.hasItemMeta() ? clicked.getItemMeta().getDisplayName() : clicked.getType().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void b(InventoryCloseEvent event) {
|
||||
if (event.getInventory().equals(inventory))
|
||||
close();
|
||||
}
|
||||
}
|
40
src/net/Indyuce/mmocore/api/input/ChatInput.java
Normal file
40
src/net/Indyuce/mmocore/api/input/ChatInput.java
Normal file
@ -0,0 +1,40 @@
|
||||
package net.Indyuce.mmocore.api.input;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.util.Consumer;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class ChatInput extends PlayerInput {
|
||||
public ChatInput(Player player, InputType type, Consumer<String> output) {
|
||||
super(player, output);
|
||||
|
||||
player.closeInventory();
|
||||
player.sendMessage(MMOCore.plugin.configManager.getSimpleMessage("player-input.chat." + type.getLowerCaseName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
AsyncPlayerChatEvent.getHandlerList().unregister(this);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void a(AsyncPlayerChatEvent event) {
|
||||
if (event.getPlayer().equals(getPlayer())) {
|
||||
close();
|
||||
event.setCancelled(true);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> getOutput().accept(event.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void b(InventoryOpenEvent event) {
|
||||
if (event.getPlayer().equals(getPlayer()))
|
||||
close();
|
||||
}
|
||||
}
|
40
src/net/Indyuce/mmocore/api/input/PlayerInput.java
Normal file
40
src/net/Indyuce/mmocore/api/input/PlayerInput.java
Normal file
@ -0,0 +1,40 @@
|
||||
package net.Indyuce.mmocore.api.input;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.Consumer;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public abstract class PlayerInput implements Listener {
|
||||
private final Player player;
|
||||
private final Consumer<String> output;
|
||||
|
||||
public PlayerInput(Player player, Consumer<String> output) {
|
||||
this.player = player;
|
||||
this.output = output;
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||
}
|
||||
|
||||
public Consumer<String> getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public abstract void close();
|
||||
|
||||
public enum InputType {
|
||||
FRIEND_REQUEST,
|
||||
|
||||
PARTY_INVITE;
|
||||
|
||||
public String getLowerCaseName() {
|
||||
return name().toLowerCase().replace("_", "-");
|
||||
}
|
||||
}
|
||||
}
|
133
src/net/Indyuce/mmocore/api/item/ConfigItem.java
Normal file
133
src/net/Indyuce/mmocore/api/item/ConfigItem.java
Normal file
@ -0,0 +1,133 @@
|
||||
package net.Indyuce.mmocore.api.item;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.version.nms.ItemTag;
|
||||
|
||||
public class ConfigItem {
|
||||
private final String name, id, texture;
|
||||
private final ItemStack item;
|
||||
private final List<String> lore;
|
||||
private final int damage;
|
||||
|
||||
private boolean unbreakable;
|
||||
private Map<String, String> placeholders = new HashMap<>();
|
||||
|
||||
public ConfigItem(ConfigurationSection config) {
|
||||
id = config.getName();
|
||||
name = config.getString("name");
|
||||
lore = config.getStringList("lore");
|
||||
item = new ItemStack(Material.valueOf(config.getString("item")));
|
||||
|
||||
Validate.notNull(name, "Name cannot be null");
|
||||
Validate.notNull(lore, "Lore can be empty but not null");
|
||||
|
||||
/*
|
||||
* extra options
|
||||
*/
|
||||
damage = config.getInt("damage");
|
||||
texture = config.getString("texture");
|
||||
}
|
||||
|
||||
public ConfigItem(String id) {
|
||||
this(MMOCore.plugin.configItems.get(id));
|
||||
}
|
||||
|
||||
public ConfigItem(ConfigItem cache) {
|
||||
this.id = cache.id;
|
||||
name = cache.name;
|
||||
lore = cache.lore;
|
||||
item = cache.item;
|
||||
damage = cache.damage;
|
||||
texture = cache.texture;
|
||||
}
|
||||
|
||||
public ItemStack getItem(int amount) {
|
||||
ItemStack item = this.item.clone();
|
||||
item.setAmount(amount);
|
||||
return item;
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return lore;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public ConfigItem setUnbreakable() {
|
||||
unbreakable = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigItem addPlaceholders(String... placeholders) {
|
||||
for (int j = 0; j < placeholders.length - 1; j += 2)
|
||||
this.placeholders.put(placeholders[j], placeholders[j + 1]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack build() {
|
||||
return build(1);
|
||||
}
|
||||
|
||||
public ItemStack build(int amount) {
|
||||
ItemStack item = getItem(amount);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta instanceof Damageable)
|
||||
((Damageable) meta).setDamage(damage);
|
||||
|
||||
if (item.getType() == Material.PLAYER_HEAD && texture != null) {
|
||||
try {
|
||||
Field profileField = meta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
GameProfile profile = new GameProfile(UUID.randomUUID(), null);
|
||||
profile.getProperties().put("textures", new Property("textures", texture));
|
||||
profileField.set(meta, profile);
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load config item texture of " + id);
|
||||
}
|
||||
}
|
||||
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
meta.setDisplayName(format(name));
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
getLore().forEach(line -> lore.add(format(line)));
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
return unbreakable ? NBTItem.get(item).add(new ItemTag("Unbreakable", true)).toItem() : item;
|
||||
}
|
||||
|
||||
protected String format(String string) {
|
||||
for (String placeholder : placeholders.keySet())
|
||||
if (string.contains("{" + placeholder + "}"))
|
||||
string = string.replace("{" + placeholder + "}", "" + placeholders.get(placeholder));
|
||||
return ChatColor.translateAlternateColorCodes('&', string);
|
||||
}
|
||||
}
|
40
src/net/Indyuce/mmocore/api/item/CurrencyItem.java
Normal file
40
src/net/Indyuce/mmocore/api/item/CurrencyItem.java
Normal file
@ -0,0 +1,40 @@
|
||||
package net.Indyuce.mmocore.api.item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import net.Indyuce.mmocore.version.nms.ItemTag;
|
||||
|
||||
public class CurrencyItem extends ConfigItem {
|
||||
private final int worth, amount;
|
||||
|
||||
public CurrencyItem(String key, int worth) {
|
||||
this(key, worth, 1);
|
||||
}
|
||||
|
||||
public CurrencyItem(String key, int worth, int amount) {
|
||||
super(key);
|
||||
addPlaceholders("worth", "" + (this.worth = worth));
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack build() {
|
||||
ItemStack item = getItem(amount);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
meta.setDisplayName(format(getName()));
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
getLore().forEach(line -> lore.add(format(line)));
|
||||
meta.setLore(lore);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
return NBTItem.get(item).add(new ItemTag("RpgWorth", worth)).toItem();
|
||||
}
|
||||
}
|
48
src/net/Indyuce/mmocore/api/item/NBTItem.java
Normal file
48
src/net/Indyuce/mmocore/api/item/NBTItem.java
Normal file
@ -0,0 +1,48 @@
|
||||
package net.Indyuce.mmocore.api.item;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.version.nms.ItemTag;
|
||||
|
||||
public abstract class NBTItem {
|
||||
protected ItemStack item;
|
||||
|
||||
public NBTItem(ItemStack item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public abstract String getString(String path);
|
||||
|
||||
public abstract boolean has(String path);
|
||||
|
||||
public abstract boolean getBoolean(String path);
|
||||
|
||||
public abstract double getDouble(String path);
|
||||
|
||||
public abstract int getInt(String path);
|
||||
|
||||
public abstract NBTItem add(ItemTag... tags);
|
||||
|
||||
public abstract NBTItem remove(String... paths);
|
||||
|
||||
public abstract Set<String> getTags();
|
||||
|
||||
public abstract ItemStack toItem();
|
||||
|
||||
public void add(List<ItemTag> tags) {
|
||||
for (ItemTag tag : tags)
|
||||
add(tag);
|
||||
}
|
||||
|
||||
public static NBTItem get(ItemStack item) {
|
||||
return MMOCore.plugin.nms.getNBTItem(item);
|
||||
}
|
||||
}
|
16
src/net/Indyuce/mmocore/api/item/NamedItemStack.java
Normal file
16
src/net/Indyuce/mmocore/api/item/NamedItemStack.java
Normal file
@ -0,0 +1,16 @@
|
||||
package net.Indyuce.mmocore.api.item;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public class NamedItemStack extends ItemStack {
|
||||
public NamedItemStack(Material material, String name) {
|
||||
super(material);
|
||||
|
||||
ItemMeta meta = getItemMeta();
|
||||
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
|
||||
setItemMeta(meta);
|
||||
}
|
||||
}
|
32
src/net/Indyuce/mmocore/api/item/SmartGive.java
Normal file
32
src/net/Indyuce/mmocore/api/item/SmartGive.java
Normal file
@ -0,0 +1,32 @@
|
||||
package net.Indyuce.mmocore.api.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class SmartGive {
|
||||
private final Inventory inv;
|
||||
private final Location loc;
|
||||
|
||||
public SmartGive(Player player) {
|
||||
inv = player.getInventory();
|
||||
loc = player.getLocation();
|
||||
}
|
||||
|
||||
/*
|
||||
* either give directly the item to the player or drops it on the ground if
|
||||
* there is not enough space in the player inventory.
|
||||
*/
|
||||
public void give(ItemStack... item) {
|
||||
for (ItemStack drop : inv.addItem(item).values())
|
||||
loc.getWorld().dropItem(loc, drop);
|
||||
}
|
||||
|
||||
public void give(List<ItemStack> item) {
|
||||
for (ItemStack drop : inv.addItem(item.toArray(new ItemStack[item.size()])).values())
|
||||
loc.getWorld().dropItem(loc, drop);
|
||||
}
|
||||
}
|
130
src/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
Normal file
130
src/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
Normal file
@ -0,0 +1,130 @@
|
||||
package net.Indyuce.mmocore.api.load;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
||||
import net.Indyuce.mmocore.api.droptable.condition.WorldCondition;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropTableDropItem;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.GoldDropItem;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.NoteDropItem;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.VanillaDropItem;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.BrewPotionExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.EnchantItemExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.FishItemExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.KillMobExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.MineBlockExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.RepairItemExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.SmeltItemExperienceSource;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.api.quest.objective.ClickonObjective;
|
||||
import net.Indyuce.mmocore.api.quest.objective.GoToObjective;
|
||||
import net.Indyuce.mmocore.api.quest.objective.KillMobObjective;
|
||||
import net.Indyuce.mmocore.api.quest.objective.MineBlockObjective;
|
||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.CommandTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.ExperienceTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.ItemTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.ManaTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.MessageTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.SoundTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.StelliumTrigger;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
||||
|
||||
public class DefaultMMOLoader implements MMOLoader {
|
||||
|
||||
@Override
|
||||
public Trigger loadTrigger(MMOLineConfig config) {
|
||||
if (config.getKey().equals("message"))
|
||||
return new MessageTrigger(config);
|
||||
|
||||
if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
|
||||
return new SoundTrigger(config);
|
||||
|
||||
if (config.getKey().equals("mana"))
|
||||
return new ManaTrigger(config);
|
||||
|
||||
if (config.getKey().equals("stellium"))
|
||||
return new StelliumTrigger(config);
|
||||
|
||||
if (config.getKey().equals("command"))
|
||||
return new CommandTrigger(config);
|
||||
|
||||
if (config.getKey().equals("item") || config.getKey().equals("vanilla"))
|
||||
return new ItemTrigger(config);
|
||||
|
||||
if (config.getKey().equals("exp") || config.getKey().equals("experience"))
|
||||
return new ExperienceTrigger(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropItem loadDropItem(MMOLineConfig config) {
|
||||
if (config.getKey().equals("droptable"))
|
||||
return new DropTableDropItem(config);
|
||||
|
||||
if (config.getKey().equals("vanilla"))
|
||||
return new VanillaDropItem(config);
|
||||
|
||||
if (config.getKey().equals("note"))
|
||||
return new NoteDropItem(config);
|
||||
|
||||
if (config.getKey().equals("gold") || config.getKey().equals("coin"))
|
||||
return new GoldDropItem(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) {
|
||||
if (config.getKey().equals("goto"))
|
||||
return new GoToObjective(section, config);
|
||||
|
||||
if (config.getKey().equals("mine"))
|
||||
return new MineBlockObjective(section, config);
|
||||
|
||||
if (config.getKey().equals("kill"))
|
||||
return new KillMobObjective(section, config);
|
||||
|
||||
if (config.getKey().equals("clickon"))
|
||||
return new ClickonObjective(section, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition loadCondition(MMOLineConfig config) {
|
||||
if (config.getKey().equals("world"))
|
||||
return new WorldCondition(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession) {
|
||||
if (config.getKey().equals("fishitem"))
|
||||
return new FishItemExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("killmob"))
|
||||
return new KillMobExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("mineblock"))
|
||||
return new MineBlockExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("brewpotion"))
|
||||
return new BrewPotionExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("smeltitem"))
|
||||
return new SmeltItemExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("enchantitem"))
|
||||
return new EnchantItemExperienceSource(profession, config);
|
||||
|
||||
if (config.getKey().equals("repairitem"))
|
||||
return new RepairItemExperienceSource(profession, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
96
src/net/Indyuce/mmocore/api/load/MMOLineConfig.java
Normal file
96
src/net/Indyuce/mmocore/api/load/MMOLineConfig.java
Normal file
@ -0,0 +1,96 @@
|
||||
package net.Indyuce.mmocore.api.load;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class MMOLineConfig {
|
||||
private final String key, value;
|
||||
private final String[] args;
|
||||
private JsonObject json;
|
||||
|
||||
public MMOLineConfig(String value) {
|
||||
this.value = value;
|
||||
|
||||
/*
|
||||
* if there is no config, no need to parse the json object. split,
|
||||
* define key and find arg
|
||||
*/
|
||||
if (!value.contains("{") || !value.contains("}")) {
|
||||
String[] split = value.split("\\ ");
|
||||
key = split[0];
|
||||
args = split.length > 1 ? value.replace(key + " ", "").split("\\ ") : new String[0];
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* load json and extra args
|
||||
*/
|
||||
int begin = value.indexOf("{"), end = value.lastIndexOf("}") + 1;
|
||||
key = value.substring(0, begin);
|
||||
|
||||
try {
|
||||
json = new JsonParser().parse(value.substring(begin, end)).getAsJsonObject();
|
||||
} catch (JsonParseException exception) {
|
||||
throw new IllegalArgumentException("Could not load config");
|
||||
}
|
||||
|
||||
String format = value.substring(Math.min(value.length(), end + 1));
|
||||
args = format.isEmpty() ? new String[0] : format.split("\\ ");
|
||||
}
|
||||
|
||||
/*
|
||||
* extra arguments outside the config brackets
|
||||
*/
|
||||
public String[] args() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getString(String path) {
|
||||
return json.get(path).getAsString();
|
||||
}
|
||||
|
||||
public double getDouble(String path) {
|
||||
return json.get(path).getAsDouble();
|
||||
}
|
||||
|
||||
public int getInt(String path) {
|
||||
return json.get(path).getAsInt();
|
||||
}
|
||||
|
||||
public long getLong(String path) {
|
||||
return json.get(path).getAsLong();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path) {
|
||||
return json.get(path).getAsBoolean();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def) {
|
||||
return json.has(path) ? getBoolean(path) : def;
|
||||
}
|
||||
|
||||
public boolean contains(String path) {
|
||||
return json.has(path);
|
||||
}
|
||||
|
||||
public void validate(String... paths) {
|
||||
for (String path : paths)
|
||||
Validate.isTrue(contains(path), "Config is missing parameter '" + path+"'");
|
||||
}
|
||||
|
||||
public void validateArgs(int count) {
|
||||
Validate.isTrue(args.length >= count, "Config must have at least " + count + " parameters");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
29
src/net/Indyuce/mmocore/api/load/MMOLoadException.java
Normal file
29
src/net/Indyuce/mmocore/api/load/MMOLoadException.java
Normal file
@ -0,0 +1,29 @@
|
||||
package net.Indyuce.mmocore.api.load;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class MMOLoadException extends IllegalArgumentException {
|
||||
private static final long serialVersionUID = -8839506644440697800L;
|
||||
|
||||
private MMOLineConfig config;
|
||||
|
||||
public MMOLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MMOLoadException(MMOLineConfig config, Exception exception) {
|
||||
super(exception.getMessage());
|
||||
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public boolean hasConfig() {
|
||||
return config != null;
|
||||
}
|
||||
|
||||
public void printConsole(String prefix, String obj) {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "[" + prefix + "] " + (hasConfig() ? "Could not load " + obj + " '" + config.toString() + "': " : "") + getMessage());
|
||||
}
|
||||
}
|
22
src/net/Indyuce/mmocore/api/load/MMOLoader.java
Normal file
22
src/net/Indyuce/mmocore/api/load/MMOLoader.java
Normal file
@ -0,0 +1,22 @@
|
||||
package net.Indyuce.mmocore.api.load;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import net.Indyuce.mmocore.api.droptable.condition.Condition;
|
||||
import net.Indyuce.mmocore.api.droptable.dropitem.DropItem;
|
||||
import net.Indyuce.mmocore.api.experience.Profession;
|
||||
import net.Indyuce.mmocore.api.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.api.quest.objective.Objective;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
|
||||
|
||||
public interface MMOLoader {
|
||||
public Condition loadCondition(MMOLineConfig config);
|
||||
|
||||
public Trigger loadTrigger(MMOLineConfig config);
|
||||
|
||||
public DropItem loadDropItem(MMOLineConfig config);
|
||||
|
||||
public Objective loadObjective(MMOLineConfig config, ConfigurationSection section);
|
||||
|
||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, Profession profession);
|
||||
}
|
63
src/net/Indyuce/mmocore/api/math/Line3D.java
Normal file
63
src/net/Indyuce/mmocore/api/math/Line3D.java
Normal file
@ -0,0 +1,63 @@
|
||||
package net.Indyuce.mmocore.api.math;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class Line3D {
|
||||
|
||||
private final Vector dir;
|
||||
private final Vector pt;
|
||||
|
||||
public Line3D(Vector loc1, Vector loc2) {
|
||||
pt = loc1.clone();
|
||||
dir = loc1.clone().subtract(loc2);
|
||||
}
|
||||
|
||||
public Line3D(Location pt, Vector dir) {
|
||||
this.dir = dir.clone();
|
||||
this.pt = pt.toVector();
|
||||
}
|
||||
|
||||
public Line3D(double a, double b, double c, double e, double f, double g) {
|
||||
pt = new Vector(a, b, c);
|
||||
dir = new Vector(e, f, g);
|
||||
}
|
||||
|
||||
public double distanceSquared(Entity entity) {
|
||||
return distanceSquared(entity.getLocation().add(0, entity.getHeight() / 2, 0).toVector());
|
||||
}
|
||||
|
||||
public double distanceSquared(Vector loc) {
|
||||
|
||||
// dir = (alpha ; beta ; gamma)
|
||||
// LINE : (x ; y ; z) = (a ; b ; c) + t * dir
|
||||
// loc = (e ; f ; g)
|
||||
|
||||
// therefore, distance vector is:
|
||||
// ( a + t * alpha - e ; b + t * beta - f ; c + t * gamma - g )
|
||||
|
||||
// length of vector is:
|
||||
// d = sqrt( (a-e)² + (b-f)² + (c-g)² + 2t( alpha(a-e) + beta(b-f) +
|
||||
// gamma(c-g) ) + t²(alpha² + beta² + gamma²) )
|
||||
|
||||
// analysis: we find the value of t for which the distance d is the
|
||||
// smallest. (canonical form) axis of symetry is min = -b/2a therefore
|
||||
|
||||
// we don't care about calculating the 0 degree constant of polynomial
|
||||
|
||||
double a = dir.lengthSquared();
|
||||
double b = 2 * (dir.getX() * (pt.getX() - loc.getX()) + dir.getY() * (pt.getY() - loc.getY()) + dir.getZ() * (pt.getZ() - loc.getZ()));
|
||||
double min = -b / (2 * a);
|
||||
|
||||
return loc.distanceSquared(getPoint(min));
|
||||
}
|
||||
|
||||
public double distance(Vector loc) {
|
||||
return Math.sqrt(distanceSquared(loc));
|
||||
}
|
||||
|
||||
public Vector getPoint(double t) {
|
||||
return pt.clone().add(dir.clone().multiply(t));
|
||||
}
|
||||
}
|
37
src/net/Indyuce/mmocore/api/math/VectorRotation.java
Normal file
37
src/net/Indyuce/mmocore/api/math/VectorRotation.java
Normal file
@ -0,0 +1,37 @@
|
||||
package net.Indyuce.mmocore.api.math;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class VectorRotation {
|
||||
private final float yaw, pitch;
|
||||
|
||||
public VectorRotation(Location source) {
|
||||
this.yaw = source.getYaw();
|
||||
this.pitch = source.getPitch();
|
||||
}
|
||||
|
||||
public Vector rotate(Vector vec) {
|
||||
vec = rotateX(vec, this.pitch / 180 * Math.PI);
|
||||
vec = rotateY(vec, -this.yaw / 180 * Math.PI);
|
||||
return vec;
|
||||
}
|
||||
|
||||
private Vector rotateX(Vector vec, double a) {
|
||||
double y = vec.getY() * Math.cos(a) - vec.getZ() * Math.sin(a);
|
||||
double z = vec.getY() * Math.sin(a) + vec.getZ() * Math.cos(a);
|
||||
return vec.setY(y).setZ(z);
|
||||
}
|
||||
|
||||
private Vector rotateY(Vector vec, double b) {
|
||||
double x = vec.getX() * Math.cos(b) + vec.getZ() * Math.sin(b);
|
||||
double z = vec.getX() * -Math.sin(b) + vec.getZ() * Math.cos(b);
|
||||
return vec.setX(x).setZ(z);
|
||||
}
|
||||
|
||||
// private Vector rotateZ(Vector vec, double c) {
|
||||
// double x = vec.getX() * Math.cos(c) - vec.getY() * Math.sin(c);
|
||||
// double y = vec.getX() * Math.sin(c) + vec.getY() * Math.cos(c);
|
||||
// return vec.setX(x).setY(y);
|
||||
// }
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user