upload src

This commit is contained in:
Indyuce 2019-08-30 20:03:13 +02:00
parent 196ffd2c78
commit dfa6b68ce9
322 changed files with 22908 additions and 0 deletions

69
config.yml Normal file
View 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
View 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
View 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

View 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
View 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
View 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}'

View 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}'

View 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
View 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
View 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}'

View 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'

View 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}'

View 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: {}

View 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}'

View 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: {}

View 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: {}

View 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: {}

View 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: {}

View 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)'

View 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: {}

View 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}'

View 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: {}

View 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
View 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
View 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
View File

@ -0,0 +1,10 @@
200
400
600
800
1000
1200
1400
1600
1800
2000

129
default/messages.yml Normal file
View 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.'

View 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

View 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

View 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}'

View 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}'

View 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

View 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

View 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..

View 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}'

View 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}'

View 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}'

View 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}'

View 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

View 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
View 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
View 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
View 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
View 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

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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();
}
}

View 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);
}
}

View 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 = "";
}

View 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!");
}
}
}

View 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)));
}
}

View 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);
}
}

View 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;
}
}

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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());
}
}

View 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);
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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()));
}
}

View File

@ -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();
}
}

View 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();
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@ -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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
};
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}
};
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View 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();
}
}

View 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();
}
}

View 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("_", "-");
}
}
}

View 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);
}
}

View 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();
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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());
}
}

View 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);
}

View 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));
}
}

View 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