First stab at Living Armour reimplementation.
Added a lot of the upgrades, but there's still more testing/upgrades to be done/reimplemented.
This commit is contained in:
parent
06faa916c3
commit
2075fa5be3
|
@ -56,7 +56,7 @@ e6d9cf699667aaa47efff37b2b033895dee29c15 assets/bloodmagic/blockstates/waterritu
|
||||||
42f26f715bddd16c069f9b51e3767b36477c8908 assets/bloodmagic/blockstates/woodtilepath.json
|
42f26f715bddd16c069f9b51e3767b36477c8908 assets/bloodmagic/blockstates/woodtilepath.json
|
||||||
3c6ce233dae6c1307d9016406c324bbe844b4e1e assets/bloodmagic/blockstates/wornstonebrickpath.json
|
3c6ce233dae6c1307d9016406c324bbe844b4e1e assets/bloodmagic/blockstates/wornstonebrickpath.json
|
||||||
d59655f12d1724b73b77c373fb6864fcff69db12 assets/bloodmagic/blockstates/wornstonetilepath.json
|
d59655f12d1724b73b77c373fb6864fcff69db12 assets/bloodmagic/blockstates/wornstonetilepath.json
|
||||||
c220fc49d1981be98283901bf1b50702f5c021cd assets/bloodmagic/lang/en_us.json
|
0529422020c4a1669969bd3ee63aee063de4954d assets/bloodmagic/lang/en_us.json
|
||||||
34445195b9f2459475cde53454bc8e37d32865d7 assets/bloodmagic/models/block/accelerationrune.json
|
34445195b9f2459475cde53454bc8e37d32865d7 assets/bloodmagic/models/block/accelerationrune.json
|
||||||
bcdbccc49d4509571be6988762ab87126275a4c8 assets/bloodmagic/models/block/airritualstone.json
|
bcdbccc49d4509571be6988762ab87126275a4c8 assets/bloodmagic/models/block/airritualstone.json
|
||||||
adf6c0b1e25451609486dc8c8cfbd9cf0f8c67f4 assets/bloodmagic/models/block/alchemicalreactionchamber.json
|
adf6c0b1e25451609486dc8c8cfbd9cf0f8c67f4 assets/bloodmagic/models/block/alchemicalreactionchamber.json
|
||||||
|
@ -269,6 +269,10 @@ ccbcba6e4a6450bb67f91ba17754d668ba64c0ac assets/bloodmagic/models/item/ironfragm
|
||||||
413fa378c40dec89cb765a7d5c8bfc9cdef1d828 assets/bloodmagic/models/item/lavacrystal.json
|
413fa378c40dec89cb765a7d5c8bfc9cdef1d828 assets/bloodmagic/models/item/lavacrystal.json
|
||||||
588c5208e3f4ef941cd8375aeceeed44484d85d3 assets/bloodmagic/models/item/lavasigil.json
|
588c5208e3f4ef941cd8375aeceeed44484d85d3 assets/bloodmagic/models/item/lavasigil.json
|
||||||
5a76914a87fc9b99079bb6afed1d4cfe3e4a532e assets/bloodmagic/models/item/lightritualstone.json
|
5a76914a87fc9b99079bb6afed1d4cfe3e4a532e assets/bloodmagic/models/item/lightritualstone.json
|
||||||
|
bd4db65caffbc68b312607bae4258fc1b67f60fd assets/bloodmagic/models/item/livingboots.json
|
||||||
|
c80cdacad2c4b6e995fe846c11cb2124a1813d79 assets/bloodmagic/models/item/livinghelmet.json
|
||||||
|
a64aa9003209d9eeca67cd7d3f1e2f05795c8f1a assets/bloodmagic/models/item/livingleggings.json
|
||||||
|
c0c9c72a8e31c9fa2d12eb870495407255431c8b assets/bloodmagic/models/item/livingplate.json
|
||||||
15d8178b626da912334774142d40d1012fb21fa0 assets/bloodmagic/models/item/magicianbloodorb.json
|
15d8178b626da912334774142d40d1012fb21fa0 assets/bloodmagic/models/item/magicianbloodorb.json
|
||||||
0a3566d3c86403f24c22977dd32ffaec727a9ad3 assets/bloodmagic/models/item/masterbloodorb.json
|
0a3566d3c86403f24c22977dd32ffaec727a9ad3 assets/bloodmagic/models/item/masterbloodorb.json
|
||||||
9e377ab2c131993f96ab6fb544bda4dbba0ab87e assets/bloodmagic/models/item/masterritualstone.json
|
9e377ab2c131993f96ab6fb544bda4dbba0ab87e assets/bloodmagic/models/item/masterritualstone.json
|
||||||
|
@ -322,6 +326,7 @@ fe2b201007c974229509f6900c6eb8b03d158b0a assets/bloodmagic/models/item/soulsword
|
||||||
29009ca92dc30e1ec4ae1d454cd3f8726d8edc3c assets/bloodmagic/models/item/stonebrickpath.json
|
29009ca92dc30e1ec4ae1d454cd3f8726d8edc3c assets/bloodmagic/models/item/stonebrickpath.json
|
||||||
2dc28b0e2b7ae7bb0bcf8c8e74b9ba7c800446ff assets/bloodmagic/models/item/stonetilepath.json
|
2dc28b0e2b7ae7bb0bcf8c8e74b9ba7c800446ff assets/bloodmagic/models/item/stonetilepath.json
|
||||||
26cb0aae63ea4f27efd5337c90c580ddd7481b99 assets/bloodmagic/models/item/sulfur.json
|
26cb0aae63ea4f27efd5337c90c580ddd7481b99 assets/bloodmagic/models/item/sulfur.json
|
||||||
|
1e735651ebcc0087d38dfce304e5d722d219870e assets/bloodmagic/models/item/upgradetome.json
|
||||||
e8fe01c5cddc268538681889f3161472a8f1c8ad assets/bloodmagic/models/item/variants/growthsigil_activated.json
|
e8fe01c5cddc268538681889f3161472a8f1c8ad assets/bloodmagic/models/item/variants/growthsigil_activated.json
|
||||||
20c802279de4df496057795c2e891fa54a21376f assets/bloodmagic/models/item/variants/growthsigil_deactivated.json
|
20c802279de4df496057795c2e891fa54a21376f assets/bloodmagic/models/item/variants/growthsigil_deactivated.json
|
||||||
2778ea3a62ce6dd718a557beee7b5329bb185ff9 assets/bloodmagic/models/item/variants/icesigil_activated.json
|
2778ea3a62ce6dd718a557beee7b5329bb185ff9 assets/bloodmagic/models/item/variants/icesigil_activated.json
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
"block.bloodmagic.wornstonebrickpath": "Worn Stone Path",
|
"block.bloodmagic.wornstonebrickpath": "Worn Stone Path",
|
||||||
"block.bloodmagic.wornstonetilepath": "Tiled Worn Stone Path",
|
"block.bloodmagic.wornstonetilepath": "Tiled Worn Stone Path",
|
||||||
"chat.bloodmagic.damageSource": "%s's soul became too weak",
|
"chat.bloodmagic.damageSource": "%s's soul became too weak",
|
||||||
|
"chat.bloodmagic.living_upgrade_level_increase": "%s has leveled up to %d",
|
||||||
"chat.bloodmagic.ritual.activate": "A rush of energy flows through the ritual!",
|
"chat.bloodmagic.ritual.activate": "A rush of energy flows through the ritual!",
|
||||||
"chat.bloodmagic.ritual.notValid": "You feel that these runes are not configured correctly...",
|
"chat.bloodmagic.ritual.notValid": "You feel that these runes are not configured correctly...",
|
||||||
"chat.bloodmagic.ritual.prevent": "The ritual is actively resisting you!",
|
"chat.bloodmagic.ritual.prevent": "The ritual is actively resisting you!",
|
||||||
|
@ -112,6 +113,10 @@
|
||||||
"item.bloodmagic.lavacrystal": "Lava Crystal",
|
"item.bloodmagic.lavacrystal": "Lava Crystal",
|
||||||
"item.bloodmagic.lavasigil": "Lava Sigil",
|
"item.bloodmagic.lavasigil": "Lava Sigil",
|
||||||
"item.bloodmagic.life_essence_bucket": "Bucket of Life",
|
"item.bloodmagic.life_essence_bucket": "Bucket of Life",
|
||||||
|
"item.bloodmagic.livingboots": "Living Boots",
|
||||||
|
"item.bloodmagic.livinghelmet": "Living Helmet",
|
||||||
|
"item.bloodmagic.livingleggings": "Living Leggings",
|
||||||
|
"item.bloodmagic.livingplate": "Living Chestplate",
|
||||||
"item.bloodmagic.magicianbloodorb": "Magician Blood Orb",
|
"item.bloodmagic.magicianbloodorb": "Magician Blood Orb",
|
||||||
"item.bloodmagic.masterbloodorb": "Master Blood Orb",
|
"item.bloodmagic.masterbloodorb": "Master Blood Orb",
|
||||||
"item.bloodmagic.miningsigil": "Sigil of the Fast Miner",
|
"item.bloodmagic.miningsigil": "Sigil of the Fast Miner",
|
||||||
|
@ -150,6 +155,7 @@
|
||||||
"item.bloodmagic.soulsword": "Sentient Sword",
|
"item.bloodmagic.soulsword": "Sentient Sword",
|
||||||
"item.bloodmagic.steadfastcrystal": "Steadfast Will Crystal",
|
"item.bloodmagic.steadfastcrystal": "Steadfast Will Crystal",
|
||||||
"item.bloodmagic.sulfur": "Sulfur",
|
"item.bloodmagic.sulfur": "Sulfur",
|
||||||
|
"item.bloodmagic.upgradetome": "Living Armour Upgrade Tome",
|
||||||
"item.bloodmagic.vengefulcrystal": "Vengeful Will Crystal",
|
"item.bloodmagic.vengefulcrystal": "Vengeful Will Crystal",
|
||||||
"item.bloodmagic.voidsigil": "Void Sigil",
|
"item.bloodmagic.voidsigil": "Void Sigil",
|
||||||
"item.bloodmagic.waterscribetool": "Inscription Tool: Water",
|
"item.bloodmagic.waterscribetool": "Inscription Tool: Water",
|
||||||
|
@ -170,6 +176,41 @@
|
||||||
"jei.bloodmagic.recipe.requiredtier": "Tier: %d",
|
"jei.bloodmagic.recipe.requiredtier": "Tier: %d",
|
||||||
"jei.bloodmagic.recipe.soulforge": "Hellfire Forge",
|
"jei.bloodmagic.recipe.soulforge": "Hellfire Forge",
|
||||||
"jei.bloodmagic.recipe.soulsdrained": "Drained: %s Will",
|
"jei.bloodmagic.recipe.soulsdrained": "Drained: %s Will",
|
||||||
|
"living_upgrade.bloodmagic.arrowShot": "Trick Shot",
|
||||||
|
"living_upgrade.bloodmagic.arrow_protect": "Pin Cushion",
|
||||||
|
"living_upgrade.bloodmagic.battleHunger": "Battle Hungry",
|
||||||
|
"living_upgrade.bloodmagic.crippledArm": "Crippled Arm",
|
||||||
|
"living_upgrade.bloodmagic.criticalStrike": "True Strike",
|
||||||
|
"living_upgrade.bloodmagic.digSlowdown": "Weakened Pick",
|
||||||
|
"living_upgrade.bloodmagic.digging": "Dwarven Might",
|
||||||
|
"living_upgrade.bloodmagic.disoriented": "Disoriented",
|
||||||
|
"living_upgrade.bloodmagic.elytra": "Elytra",
|
||||||
|
"living_upgrade.bloodmagic.experienced": "Experienced",
|
||||||
|
"living_upgrade.bloodmagic.fallProtect": "Soft Fall",
|
||||||
|
"living_upgrade.bloodmagic.fireResist": "Gift of Ignis",
|
||||||
|
"living_upgrade.bloodmagic.graveDigger": "Grave Digger",
|
||||||
|
"living_upgrade.bloodmagic.grimReaper": "Grim Reaper's Sprint",
|
||||||
|
"living_upgrade.bloodmagic.health": "Healthy",
|
||||||
|
"living_upgrade.bloodmagic.jump": "Strong Legs",
|
||||||
|
"living_upgrade.bloodmagic.knockback": "Body Builder",
|
||||||
|
"living_upgrade.bloodmagic.meleeDamage": "Fierce Strike",
|
||||||
|
"living_upgrade.bloodmagic.meleeDecrease": "Dulled Blade",
|
||||||
|
"living_upgrade.bloodmagic.nightSight": "Nocturnal Prowess",
|
||||||
|
"living_upgrade.bloodmagic.physicalProtect": "Tough",
|
||||||
|
"living_upgrade.bloodmagic.poisonResist": "Poison Resistance",
|
||||||
|
"living_upgrade.bloodmagic.quenched": "Quenched",
|
||||||
|
"living_upgrade.bloodmagic.repair": "Repairing",
|
||||||
|
"living_upgrade.bloodmagic.revealing": "Revealing",
|
||||||
|
"living_upgrade.bloodmagic.self_sacrifice": "Tough Palms",
|
||||||
|
"living_upgrade.bloodmagic.slippery": "Loose Traction",
|
||||||
|
"living_upgrade.bloodmagic.slowHeal": "Diseased",
|
||||||
|
"living_upgrade.bloodmagic.slowness": "Limp Leg",
|
||||||
|
"living_upgrade.bloodmagic.solarPowered": "Solar Powered",
|
||||||
|
"living_upgrade.bloodmagic.speed": "Quick Feet",
|
||||||
|
"living_upgrade.bloodmagic.sprint_attack": "Charging Strike",
|
||||||
|
"living_upgrade.bloodmagic.stepAssist": "Step Assist",
|
||||||
|
"living_upgrade.bloodmagic.stormTrooper": "Storm Trooper",
|
||||||
|
"living_upgrade.bloodmagic.thaumRunicShielding": "Runic Shielding",
|
||||||
"ritual.bloodmagic.altarBuilderRitual": "The Assembly of the High Altar",
|
"ritual.bloodmagic.altarBuilderRitual": "The Assembly of the High Altar",
|
||||||
"ritual.bloodmagic.altarBuilderRitual.info": "Builds an altar out of the components inside of the connected inventory.",
|
"ritual.bloodmagic.altarBuilderRitual.info": "Builds an altar out of the components inside of the connected inventory.",
|
||||||
"ritual.bloodmagic.animalGrowthRitual": "Ritual of the Shepherd",
|
"ritual.bloodmagic.animalGrowthRitual": "Ritual of the Shepherd",
|
||||||
|
@ -203,8 +244,10 @@
|
||||||
"ritual.bloodmagic.crushingRitual.info": "Breaks blocks within its crushing range and places the items into the linked chest.",
|
"ritual.bloodmagic.crushingRitual.info": "Breaks blocks within its crushing range and places the items into the linked chest.",
|
||||||
"ritual.bloodmagic.crushingRitual.steadfast.info": "(Steadfast) Causes all blocks that are broken to be picked up with silk touch. Overrides Fortune where applicable.",
|
"ritual.bloodmagic.crushingRitual.steadfast.info": "(Steadfast) Causes all blocks that are broken to be picked up with silk touch. Overrides Fortune where applicable.",
|
||||||
"ritual.bloodmagic.crushingRitual.vengeful.info": "(Vengeful) Compresses the inventory on successful operation. Currently only does one compression per operation.",
|
"ritual.bloodmagic.crushingRitual.vengeful.info": "(Vengeful) Compresses the inventory on successful operation. Currently only does one compression per operation.",
|
||||||
|
"ritual.bloodmagic.crystalHarvestRitual": "Crack of the Fractured Crystal",
|
||||||
"ritual.bloodmagic.crystalHarvestRitual.crystal.info": "(Crystal) All Demon Will crystal clusters have a single crystal broken off, spawning the crystal into the world. If there is only one crystal on the cluster, it will not break it.",
|
"ritual.bloodmagic.crystalHarvestRitual.crystal.info": "(Crystal) All Demon Will crystal clusters have a single crystal broken off, spawning the crystal into the world. If there is only one crystal on the cluster, it will not break it.",
|
||||||
"ritual.bloodmagic.crystalHarvestRitual.info": "Breaks Demon Will crystal clusters within its range, dropping the results on top of the crystals.",
|
"ritual.bloodmagic.crystalHarvestRitual.info": "Breaks Demon Will crystal clusters within its range, dropping the results on top of the crystals.",
|
||||||
|
"ritual.bloodmagic.crystalSplitRitual": "Resonance of the Faceted Crystal",
|
||||||
"ritual.bloodmagic.crystalSplitRitual.info": "Splits apart a well-grown Raw crystal cluster into seperal aspected crystal clusters.",
|
"ritual.bloodmagic.crystalSplitRitual.info": "Splits apart a well-grown Raw crystal cluster into seperal aspected crystal clusters.",
|
||||||
"ritual.bloodmagic.ellipseRitual.chest.info": "(Chest) The location of the inventory that the ritual will grab blocks from to place in the world.",
|
"ritual.bloodmagic.ellipseRitual.chest.info": "(Chest) The location of the inventory that the ritual will grab blocks from to place in the world.",
|
||||||
"ritual.bloodmagic.ellipseRitual.info": "Creates a hollow spheroid around the ritual using the blocks in the attached chest.",
|
"ritual.bloodmagic.ellipseRitual.info": "Creates a hollow spheroid around the ritual using the blocks in the attached chest.",
|
||||||
|
@ -226,6 +269,7 @@
|
||||||
"ritual.bloodmagic.fellingRitual.chest.info": "(Chest) The location of the inventory that the ritual will place the results into.",
|
"ritual.bloodmagic.fellingRitual.chest.info": "(Chest) The location of the inventory that the ritual will place the results into.",
|
||||||
"ritual.bloodmagic.fellingRitual.fellingRange.info": "(Cutting) The range that the ritual will search out logs and leaves in order to cut down.",
|
"ritual.bloodmagic.fellingRitual.fellingRange.info": "(Cutting) The range that the ritual will search out logs and leaves in order to cut down.",
|
||||||
"ritual.bloodmagic.fellingRitual.info": "A standard tree-cutting machine, this ritual will cut down all trees and leaves within its area and collect the drops.",
|
"ritual.bloodmagic.fellingRitual.info": "A standard tree-cutting machine, this ritual will cut down all trees and leaves within its area and collect the drops.",
|
||||||
|
"ritual.bloodmagic.forsakenSoulRitual": "Gathering of the Forsaken Souls",
|
||||||
"ritual.bloodmagic.forsakenSoulRitual.crystal.info": "(Crystal) Demon Crystals in this range receive an increase in growth speed when a mob is killed by the ritual.",
|
"ritual.bloodmagic.forsakenSoulRitual.crystal.info": "(Crystal) Demon Crystals in this range receive an increase in growth speed when a mob is killed by the ritual.",
|
||||||
"ritual.bloodmagic.forsakenSoulRitual.damage.info": "(Damage) Mobs within this range will be slowly damaged, and when killed will grow the crystals.",
|
"ritual.bloodmagic.forsakenSoulRitual.damage.info": "(Damage) Mobs within this range will be slowly damaged, and when killed will grow the crystals.",
|
||||||
"ritual.bloodmagic.forsakenSoulRitual.info": "Damages mobs within its damage range and when the mob dies a demon crystal within its crystal range will be grown.",
|
"ritual.bloodmagic.forsakenSoulRitual.info": "Damages mobs within its damage range and when the mob dies a demon crystal within its crystal range will be grown.",
|
||||||
|
@ -360,6 +404,10 @@
|
||||||
"tooltip.bloodmagic.extraInfo": "&9-Hold shift for more info-",
|
"tooltip.bloodmagic.extraInfo": "&9-Hold shift for more info-",
|
||||||
"tooltip.bloodmagic.holdShiftForInfo": "Press shift for extra info",
|
"tooltip.bloodmagic.holdShiftForInfo": "Press shift for extra info",
|
||||||
"tooltip.bloodmagic.inscriber.desc": "The writing is on the wall...",
|
"tooltip.bloodmagic.inscriber.desc": "The writing is on the wall...",
|
||||||
|
"tooltip.bloodmagic.livingarmour.extraExtraInfo": "&9-Hold shift + M for progress info-",
|
||||||
|
"tooltip.bloodmagic.livingarmour.upgrade.level": "%s (Level %d)",
|
||||||
|
"tooltip.bloodmagic.livingarmour.upgrade.points": "Upgrade points: %s / %s",
|
||||||
|
"tooltip.bloodmagic.livingarmour.upgrade.progress": "%s (%d/100)",
|
||||||
"tooltip.bloodmagic.orb.desc": "Stores raw Life Essence",
|
"tooltip.bloodmagic.orb.desc": "Stores raw Life Essence",
|
||||||
"tooltip.bloodmagic.orb.owner": "Added by: %s",
|
"tooltip.bloodmagic.orb.owner": "Added by: %s",
|
||||||
"tooltip.bloodmagic.ritualReader.currentState": "Current mode: %s",
|
"tooltip.bloodmagic.ritualReader.currentState": "Current mode: %s",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "bloodmagic:item/livingboots"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "bloodmagic:item/livinghelmet"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "bloodmagic:item/livingleggings"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "bloodmagic:item/livingplate"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "bloodmagic:item/upgradetome"
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ import wayoftime.bloodmagic.common.data.recipe.BloodMagicRecipeProvider;
|
||||||
import wayoftime.bloodmagic.common.item.BloodMagicItems;
|
import wayoftime.bloodmagic.common.item.BloodMagicItems;
|
||||||
import wayoftime.bloodmagic.common.registries.BloodMagicEntityTypes;
|
import wayoftime.bloodmagic.common.registries.BloodMagicEntityTypes;
|
||||||
import wayoftime.bloodmagic.common.registries.BloodMagicRecipeSerializers;
|
import wayoftime.bloodmagic.common.registries.BloodMagicRecipeSerializers;
|
||||||
|
import wayoftime.bloodmagic.core.LivingArmorRegistrar;
|
||||||
import wayoftime.bloodmagic.core.recipe.IngredientBloodOrb;
|
import wayoftime.bloodmagic.core.recipe.IngredientBloodOrb;
|
||||||
import wayoftime.bloodmagic.core.registry.OrbRegistry;
|
import wayoftime.bloodmagic.core.registry.OrbRegistry;
|
||||||
import wayoftime.bloodmagic.impl.BloodMagicAPI;
|
import wayoftime.bloodmagic.impl.BloodMagicAPI;
|
||||||
|
@ -96,6 +97,7 @@ public class BloodMagic
|
||||||
BloodMagicItems.ITEMS.register(modBus);
|
BloodMagicItems.ITEMS.register(modBus);
|
||||||
// RegistrarBloodMagic.BLOOD_ORBS.createAndRegister(modBus, "bloodorbs");
|
// RegistrarBloodMagic.BLOOD_ORBS.createAndRegister(modBus, "bloodorbs");
|
||||||
BloodMagicItems.BLOOD_ORBS.createAndRegister(modBus, "bloodorbs");
|
BloodMagicItems.BLOOD_ORBS.createAndRegister(modBus, "bloodorbs");
|
||||||
|
LivingArmorRegistrar.UPGRADES.createAndRegister(modBus, "upgrades");
|
||||||
BloodMagicItems.BASICITEMS.register(modBus);
|
BloodMagicItems.BASICITEMS.register(modBus);
|
||||||
BloodMagicBlocks.BASICBLOCKS.register(modBus);
|
BloodMagicBlocks.BASICBLOCKS.register(modBus);
|
||||||
BloodMagicBlocks.DUNGEONBLOCKS.register(modBus);
|
BloodMagicBlocks.DUNGEONBLOCKS.register(modBus);
|
||||||
|
@ -165,6 +167,7 @@ public class BloodMagic
|
||||||
BloodMagicCorePlugin.INSTANCE.register(BloodMagicAPI.INSTANCE);
|
BloodMagicCorePlugin.INSTANCE.register(BloodMagicAPI.INSTANCE);
|
||||||
RITUAL_MANAGER.discover();
|
RITUAL_MANAGER.discover();
|
||||||
ModRituals.initHarvestHandlers();
|
ModRituals.initHarvestHandlers();
|
||||||
|
LivingArmorRegistrar.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerTileEntityTypes(RegistryEvent.Register<TileEntityType<?>> event)
|
public void registerTileEntityTypes(RegistryEvent.Register<TileEntityType<?>> event)
|
||||||
|
|
|
@ -297,6 +297,52 @@ public class GeneratorLanguage extends LanguageProvider
|
||||||
add("tooltip.bloodmagic.ritualReader.desc.information", "Right click on an active Master Ritual Stone to gather basic information about the ritual.");
|
add("tooltip.bloodmagic.ritualReader.desc.information", "Right click on an active Master Ritual Stone to gather basic information about the ritual.");
|
||||||
add("tooltip.bloodmagic.ritualReader.desc.set_will_types", "Set the types of demon will that the ritual will consume from the aura by right clicking on the MRS with the same types of crystals on your hotbar.");
|
add("tooltip.bloodmagic.ritualReader.desc.set_will_types", "Set the types of demon will that the ritual will consume from the aura by right clicking on the MRS with the same types of crystals on your hotbar.");
|
||||||
|
|
||||||
|
// Living Armour - the 'u' is important, TehNut!
|
||||||
|
add("living_upgrade.bloodmagic.arrow_protect", "Pin Cushion");
|
||||||
|
add("living_upgrade.bloodmagic.speed", "Quick Feet");
|
||||||
|
add("living_upgrade.bloodmagic.digging", "Dwarven Might");
|
||||||
|
add("living_upgrade.bloodmagic.poisonResist", "Poison Resistance");
|
||||||
|
add("living_upgrade.bloodmagic.fireResist", "Gift of Ignis");
|
||||||
|
add("living_upgrade.bloodmagic.self_sacrifice", "Tough Palms");
|
||||||
|
add("living_upgrade.bloodmagic.knockback", "Body Builder");
|
||||||
|
add("living_upgrade.bloodmagic.physicalProtect", "Tough");
|
||||||
|
add("living_upgrade.bloodmagic.health", "Healthy");
|
||||||
|
add("living_upgrade.bloodmagic.meleeDamage", "Fierce Strike");
|
||||||
|
add("living_upgrade.bloodmagic.arrowShot", "Trick Shot");
|
||||||
|
add("living_upgrade.bloodmagic.stepAssist", "Step Assist");
|
||||||
|
add("living_upgrade.bloodmagic.grimReaper", "Grim Reaper's Sprint");
|
||||||
|
add("living_upgrade.bloodmagic.solarPowered", "Solar Powered");
|
||||||
|
add("living_upgrade.bloodmagic.thaumRunicShielding", "Runic Shielding");
|
||||||
|
add("living_upgrade.bloodmagic.revealing", "Revealing");
|
||||||
|
add("living_upgrade.bloodmagic.experienced", "Experienced");
|
||||||
|
add("living_upgrade.bloodmagic.jump", "Strong Legs");
|
||||||
|
add("living_upgrade.bloodmagic.fallProtect", "Soft Fall");
|
||||||
|
add("living_upgrade.bloodmagic.graveDigger", "Grave Digger");
|
||||||
|
add("living_upgrade.bloodmagic.sprint_attack", "Charging Strike");
|
||||||
|
add("living_upgrade.bloodmagic.criticalStrike", "True Strike");
|
||||||
|
add("living_upgrade.bloodmagic.elytra", "Elytra");
|
||||||
|
add("living_upgrade.bloodmagic.nightSight", "Nocturnal Prowess");
|
||||||
|
add("living_upgrade.bloodmagic.repair", "Repairing");
|
||||||
|
|
||||||
|
add("living_upgrade.bloodmagic.slowness", "Limp Leg");
|
||||||
|
add("living_upgrade.bloodmagic.crippledArm", "Crippled Arm");
|
||||||
|
add("living_upgrade.bloodmagic.slippery", "Loose Traction");
|
||||||
|
add("living_upgrade.bloodmagic.battleHunger", "Battle Hungry");
|
||||||
|
add("living_upgrade.bloodmagic.quenched", "Quenched");
|
||||||
|
add("living_upgrade.bloodmagic.meleeDecrease", "Dulled Blade");
|
||||||
|
add("living_upgrade.bloodmagic.digSlowdown", "Weakened Pick");
|
||||||
|
add("living_upgrade.bloodmagic.stormTrooper", "Storm Trooper");
|
||||||
|
add("living_upgrade.bloodmagic.slowHeal", "Diseased");
|
||||||
|
add("living_upgrade.bloodmagic.disoriented", "Disoriented");
|
||||||
|
|
||||||
|
add("tooltip.bloodmagic.livingarmour.upgrade.level", "%s (Level %d)");
|
||||||
|
add("tooltip.bloodmagic.livingarmour.upgrade.progress", "%s (%d/100)");
|
||||||
|
add("tooltip.bloodmagic.livingarmour.upgrade.points", "Upgrade points: %s / %s");
|
||||||
|
|
||||||
|
add("tooltip.bloodmagic.livingarmour.extraExtraInfo", "&9-Hold shift + M for progress info-");
|
||||||
|
|
||||||
|
add("chat.bloodmagic.living_upgrade_level_increase", "%s has leveled up to %d");
|
||||||
|
|
||||||
// Guide
|
// Guide
|
||||||
add("guide.bloodmagic.name", "Sanguine Scientiem");
|
add("guide.bloodmagic.name", "Sanguine Scientiem");
|
||||||
add("guide.bloodmagic.landing_text", "\"It is my dear hope that by holding this tome in your hands, I may impart the knowledge of the lost art that is Blood Magic\"$(br)$(o)- Magus Arcana$()");
|
add("guide.bloodmagic.landing_text", "\"It is my dear hope that by holding this tome in your hands, I may impart the knowledge of the lost art that is Blood Magic\"$(br)$(o)- Magus Arcana$()");
|
||||||
|
@ -464,6 +510,13 @@ public class GeneratorLanguage extends LanguageProvider
|
||||||
|
|
||||||
addItem(BloodMagicItems.EXPERIENCE_TOME, "Tome of Peritia");
|
addItem(BloodMagicItems.EXPERIENCE_TOME, "Tome of Peritia");
|
||||||
|
|
||||||
|
addItem(BloodMagicItems.LIVING_HELMET, "Living Helmet");
|
||||||
|
addItem(BloodMagicItems.LIVING_PLATE, "Living Chestplate");
|
||||||
|
addItem(BloodMagicItems.LIVING_LEGGINGS, "Living Leggings");
|
||||||
|
addItem(BloodMagicItems.LIVING_BOOTS, "Living Boots");
|
||||||
|
|
||||||
|
addItem(BloodMagicItems.LIVING_TOME, "Living Armour Upgrade Tome");
|
||||||
|
|
||||||
// Alchemy Items
|
// Alchemy Items
|
||||||
addItem(BloodMagicItems.PLANT_OIL, "Plant Oil");
|
addItem(BloodMagicItems.PLANT_OIL, "Plant Oil");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ArmorMaterial;
|
||||||
|
import net.minecraft.item.IArmorMaterial;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
|
|
||||||
|
public class ArmorMaterialLiving implements IArmorMaterial
|
||||||
|
{
|
||||||
|
public static final IArmorMaterial INSTANCE = new ArmorMaterialLiving();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDurability(EquipmentSlotType slot)
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getDurability(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDamageReductionAmount(EquipmentSlotType slot)
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getDamageReductionAmount(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEnchantability()
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getEnchantability();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.util.SoundEvent getSoundEvent()
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getSoundEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ingredient getRepairMaterial()
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getRepairMaterial();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "livingarmour";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getToughness()
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getToughness();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getKnockbackResistance()
|
||||||
|
{
|
||||||
|
return ArmorMaterial.IRON.getKnockbackResistance();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package wayoftime.bloodmagic.common.item;
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -7,6 +8,7 @@ import net.minecraftforge.fml.RegistryObject;
|
||||||
import net.minecraftforge.registries.DeferredRegister;
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import wayoftime.bloodmagic.BloodMagic;
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
||||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||||
import wayoftime.bloodmagic.common.item.arc.ItemARCToolBase;
|
import wayoftime.bloodmagic.common.item.arc.ItemARCToolBase;
|
||||||
import wayoftime.bloodmagic.common.item.block.ItemBlockAlchemyTable;
|
import wayoftime.bloodmagic.common.item.block.ItemBlockAlchemyTable;
|
||||||
|
@ -32,7 +34,6 @@ import wayoftime.bloodmagic.common.registration.impl.BloodOrbDeferredRegister;
|
||||||
import wayoftime.bloodmagic.common.registration.impl.BloodOrbRegistryObject;
|
import wayoftime.bloodmagic.common.registration.impl.BloodOrbRegistryObject;
|
||||||
import wayoftime.bloodmagic.ritual.EnumRuneType;
|
import wayoftime.bloodmagic.ritual.EnumRuneType;
|
||||||
import wayoftime.bloodmagic.structures.ItemDungeonTester;
|
import wayoftime.bloodmagic.structures.ItemDungeonTester;
|
||||||
import wayoftime.bloodmagic.api.compat.EnumDemonWillType;
|
|
||||||
|
|
||||||
public class BloodMagicItems
|
public class BloodMagicItems
|
||||||
{
|
{
|
||||||
|
@ -129,6 +130,13 @@ public class BloodMagicItems
|
||||||
public static final RegistryObject<Item> WEAK_BLOOD_SHARD = BASICITEMS.register("weakbloodshard", () -> new ItemBase());
|
public static final RegistryObject<Item> WEAK_BLOOD_SHARD = BASICITEMS.register("weakbloodshard", () -> new ItemBase());
|
||||||
public static final RegistryObject<Item> EXPERIENCE_TOME = BASICITEMS.register("experiencebook", () -> new ItemExperienceBook());
|
public static final RegistryObject<Item> EXPERIENCE_TOME = BASICITEMS.register("experiencebook", () -> new ItemExperienceBook());
|
||||||
|
|
||||||
|
public static final RegistryObject<Item> LIVING_HELMET = BASICITEMS.register("livinghelmet", () -> new ItemLivingArmor(EquipmentSlotType.HEAD));
|
||||||
|
public static final RegistryObject<Item> LIVING_PLATE = BASICITEMS.register("livingplate", () -> new ItemLivingArmor(EquipmentSlotType.CHEST));
|
||||||
|
public static final RegistryObject<Item> LIVING_LEGGINGS = BASICITEMS.register("livingleggings", () -> new ItemLivingArmor(EquipmentSlotType.LEGS));
|
||||||
|
public static final RegistryObject<Item> LIVING_BOOTS = BASICITEMS.register("livingboots", () -> new ItemLivingArmor(EquipmentSlotType.FEET));
|
||||||
|
|
||||||
|
public static final RegistryObject<Item> LIVING_TOME = BASICITEMS.register("upgradetome", () -> new ItemLivingTome());
|
||||||
|
|
||||||
// Ritual stuffs
|
// Ritual stuffs
|
||||||
public static final RegistryObject<Item> WEAK_ACTIVATION_CRYSTAL = BASICITEMS.register("activationcrystalweak", () -> new ItemActivationCrystal(ItemActivationCrystal.CrystalType.WEAK));
|
public static final RegistryObject<Item> WEAK_ACTIVATION_CRYSTAL = BASICITEMS.register("activationcrystalweak", () -> new ItemActivationCrystal(ItemActivationCrystal.CrystalType.WEAK));
|
||||||
public static final RegistryObject<Item> AWAKENED_ACTIVATION_CRYSTAL = BASICITEMS.register("activationcrystalawakened", () -> new ItemActivationCrystal(ItemActivationCrystal.CrystalType.AWAKENED));
|
public static final RegistryObject<Item> AWAKENED_ACTIVATION_CRYSTAL = BASICITEMS.register("activationcrystalawakened", () -> new ItemActivationCrystal(ItemActivationCrystal.CrystalType.AWAKENED));
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
|
||||||
|
public interface ExpandedArmor
|
||||||
|
{
|
||||||
|
|
||||||
|
// Multimap<String, AttributeModifier> getAttributeModifiers(EquipmentSlotType slot, ItemStack stack);
|
||||||
|
|
||||||
|
void damageArmor(LivingEntity livingEntity, ItemStack stack, DamageSource source, float damage, EquipmentSlotType slot);
|
||||||
|
|
||||||
|
Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlotType slot, ItemStack stack);
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ArmorItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
import wayoftime.bloodmagic.core.living.ILivingContainer;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingStats;
|
||||||
|
|
||||||
|
public class ItemLivingArmor extends ArmorItem implements ILivingContainer, ExpandedArmor
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final int MAX_ABSORPTION = 100000;
|
||||||
|
|
||||||
|
public ItemLivingArmor(EquipmentSlotType slot)
|
||||||
|
{
|
||||||
|
super(ArmorMaterialLiving.INSTANCE, slot, new Item.Properties().maxStackSize(1).group(BloodMagic.TAB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArmorTexture(ItemStack stack, Entity entity, EquipmentSlotType slot, String type)
|
||||||
|
{
|
||||||
|
if (this == BloodMagicItems.LIVING_PLATE.get() || this == BloodMagicItems.LIVING_HELMET.get() || this == BloodMagicItems.LIVING_BOOTS.get())
|
||||||
|
{
|
||||||
|
return "bloodmagic:models/armor/livingarmour_layer_1.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this == BloodMagicItems.LIVING_LEGGINGS.get())
|
||||||
|
{
|
||||||
|
return "bloodmagic:models/armor/livingarmour_layer_2.png";
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlotType slot, ItemStack stack)
|
||||||
|
{
|
||||||
|
// Multimap<Attribute, AttributeModifier> modifiers = super.getAttributeModifiers(slot, stack);
|
||||||
|
Multimap<Attribute, AttributeModifier> modifiers = HashMultimap.create();
|
||||||
|
modifiers.putAll(super.getAttributeModifiers(slot, stack));
|
||||||
|
if (slot != EquipmentSlotType.CHEST)
|
||||||
|
return modifiers;
|
||||||
|
|
||||||
|
LivingStats stats = getLivingStats(stack);
|
||||||
|
if (stats == null)
|
||||||
|
return modifiers;
|
||||||
|
|
||||||
|
stats.getUpgrades().forEach((k, v) -> {
|
||||||
|
if (k.getAttributeProvider() != null)
|
||||||
|
k.getAttributeProvider().handleAttributes(stats, modifiers, UUID.nameUUIDFromBytes(k.getKey().toString().getBytes()), k, k.getLevel(v.intValue()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public ArmorProperties getProperties(EntityLivingBase player, @Nonnull ItemStack armor, DamageSource source, double damage, int slot) {
|
||||||
|
// if (source == DamageSource.DROWN || source == DamageSource.OUT_OF_WORLD)
|
||||||
|
// return new ArmorProperties(-1, 0D, 0);
|
||||||
|
//
|
||||||
|
// double armorReduction;
|
||||||
|
// double damageAmount = 0.25;
|
||||||
|
// double armorPenetrationReduction = 0;
|
||||||
|
//
|
||||||
|
// if (armor.getItem() == RegistrarBloodMagicItems.LIVING_ARMOR_FEET || armor.getItem() == RegistrarBloodMagicItems.LIVING_ARMOR_HEAD)
|
||||||
|
// damageAmount = 3d / 20d * 0.6;
|
||||||
|
// else if (armor.getItem() == RegistrarBloodMagicItems.LIVING_ARMOR_LEGS)
|
||||||
|
// damageAmount = 6d / 20d * 0.6;
|
||||||
|
// else if (armor.getItem() == RegistrarBloodMagicItems.LIVING_ARMOR_CHEST)
|
||||||
|
// damageAmount = 0.64;
|
||||||
|
//
|
||||||
|
// if (armor.getItem() == RegistrarBloodMagicItems.LIVING_ARMOR_CHEST) {
|
||||||
|
// armorReduction = 0.24 / 0.64; // This values puts it at iron level
|
||||||
|
//
|
||||||
|
// if (!LivingUtil.hasFullSet((EntityPlayer) player))
|
||||||
|
// return new ArmorProperties(-1, damageAmount * armorReduction, MAX_ABSORPTION);
|
||||||
|
//
|
||||||
|
// LivingStats stats = getLivingStats(armor);
|
||||||
|
// double protection = 1.0D;
|
||||||
|
// if (stats != null)
|
||||||
|
// for (Map.Entry<LivingUpgrade, Integer> entry : stats.getUpgrades().entrySet())
|
||||||
|
// if (entry.getKey().getArmorProvider() != null)
|
||||||
|
// protection *= 1 - entry.getKey().getArmorProvider().getProtection((EntityPlayer) player, stats, source, entry.getKey().getLevel(entry.getValue()));
|
||||||
|
//
|
||||||
|
// armorReduction += (1 - protection) * (1 - armorReduction);
|
||||||
|
// damageAmount *= armorReduction;
|
||||||
|
// return new ArmorProperties(-1, source.isUnblockable() ? 1 - protection : damageAmount, MAX_ABSORPTION);
|
||||||
|
// } else if (source.isUnblockable())
|
||||||
|
// return new ArmorProperties(-1, damageAmount * armorPenetrationReduction, MAX_ABSORPTION);
|
||||||
|
//
|
||||||
|
// return new ArmorProperties(-1, damageAmount, MAX_ABSORPTION);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items)
|
||||||
|
{
|
||||||
|
if (!isInGroup(group))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack stack = new ItemStack(this);
|
||||||
|
if (slot == EquipmentSlotType.CHEST)
|
||||||
|
updateLivingStats(stack, new LivingStats());
|
||||||
|
|
||||||
|
items.add(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items)
|
||||||
|
// {
|
||||||
|
// if (this.isInGroup(group))
|
||||||
|
// {
|
||||||
|
// for (EnumDemonWillType type : EnumDemonWillType.values())
|
||||||
|
// {
|
||||||
|
// ItemStack stack = new ItemStack(this);
|
||||||
|
// this.setCurrentType(type, stack);
|
||||||
|
// this.setWill(type, stack, maxWill);
|
||||||
|
// items.add(stack);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void damageArmor(LivingEntity livingEntity, ItemStack stack, DamageSource source, float damage, EquipmentSlotType slot)
|
||||||
|
{
|
||||||
|
if (slot == EquipmentSlotType.CHEST && damage > getMaxDamage() - stack.getDamage())
|
||||||
|
{
|
||||||
|
// livingEntity.attackEntityFrom(source, amount)
|
||||||
|
// }
|
||||||
|
livingEntity.attackEntityFrom(DamageSource.MAGIC, 2.0F);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stack.damage((int) damage, livingEntity, entity -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void addInformation(ItemStack stack, World world, List<ITextComponent> tooltip, ITooltipFlag flag)
|
||||||
|
{
|
||||||
|
ILivingContainer.appendLivingTooltip(getLivingStats(stack), tooltip, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.NonNullList;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
import wayoftime.bloodmagic.core.LivingArmorRegistrar;
|
||||||
|
import wayoftime.bloodmagic.core.living.ILivingContainer;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingStats;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUpgrade;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUtil;
|
||||||
|
|
||||||
|
public class ItemLivingTome extends Item implements ILivingContainer
|
||||||
|
{
|
||||||
|
|
||||||
|
public ItemLivingTome()
|
||||||
|
{
|
||||||
|
super(new Item.Properties().maxStackSize(1).group(BloodMagic.TAB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand)
|
||||||
|
{
|
||||||
|
ItemStack held = player.getHeldItem(hand);
|
||||||
|
|
||||||
|
LivingStats armorStats = LivingStats.fromPlayer(player, true);
|
||||||
|
if (armorStats == null)
|
||||||
|
return ActionResult.resultPass(held);
|
||||||
|
|
||||||
|
LivingStats tomeStats = getLivingStats(held);
|
||||||
|
if (tomeStats == null)
|
||||||
|
return ActionResult.resultPass(held);
|
||||||
|
|
||||||
|
boolean[] flag = new boolean[] { false };
|
||||||
|
tomeStats.getUpgrades().forEach((k, v) -> {
|
||||||
|
if (armorStats.getLevel(k.getKey()) >= tomeStats.getLevel(k.getKey()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LivingUtil.applyNewExperience(player, k, v); // FIXME set levels directly, don't add experience
|
||||||
|
flag[0] = true;
|
||||||
|
});
|
||||||
|
// LivingStats.toPlayer(player, armorStats);
|
||||||
|
if (flag[0])
|
||||||
|
{
|
||||||
|
held.shrink(1);
|
||||||
|
return ActionResult.resultSuccess(held);
|
||||||
|
} else
|
||||||
|
return ActionResult.resultPass(held);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items)
|
||||||
|
{
|
||||||
|
if (!isInGroup(group))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Entry<ResourceLocation, LivingUpgrade> entry : LivingArmorRegistrar.UPGRADE_MAP.entrySet())
|
||||||
|
{
|
||||||
|
LivingUpgrade upgrade = entry.getValue();
|
||||||
|
int exp = 0;
|
||||||
|
|
||||||
|
while ((exp = upgrade.getNextRequirement(exp)) != 0)
|
||||||
|
{
|
||||||
|
ItemStack tome = new ItemStack(this);
|
||||||
|
updateLivingStats(tome, new LivingStats().setMaxPoints(upgrade.getLevelCost(exp)).addExperience(upgrade.getKey(), exp));
|
||||||
|
items.add(tome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LivingArmorRegistrar.UPGRADE_MAP.forEach(upgrade -> {
|
||||||
|
// int exp = 0;
|
||||||
|
//
|
||||||
|
// while ((exp = upgrade.getNextRequirement(exp)) != 0)
|
||||||
|
// {
|
||||||
|
// ItemStack tome = new ItemStack(this);
|
||||||
|
// updateLivingStats(tome, new LivingStats().setMaxPoints(upgrade.getLevelCost(exp)).addExperience(upgrade.getKey(), exp));
|
||||||
|
// display.add(tome);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void addInformation(ItemStack stack, World world, List<ITextComponent> tooltip, ITooltipFlag flag)
|
||||||
|
{
|
||||||
|
ILivingContainer.appendLivingTooltip(getLivingStats(stack), tooltip, false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package wayoftime.bloodmagic.common.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
import wayoftime.bloodmagic.core.living.ILivingContainer;
|
||||||
|
|
||||||
|
public class ItemLivingTrainer extends Item implements ILivingContainer
|
||||||
|
{
|
||||||
|
public ItemLivingTrainer()
|
||||||
|
{
|
||||||
|
super(new Item.Properties().maxStackSize(1).group(BloodMagic.TAB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void addInformation(ItemStack stack, World world, List<ITextComponent> tooltip, ITooltipFlag flag)
|
||||||
|
{
|
||||||
|
ILivingContainer.appendLivingTooltip(getLivingStats(stack), tooltip, false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package wayoftime.bloodmagic.common.registration.impl;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import wayoftime.bloodmagic.common.registration.WrappedDeferredRegister;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUpgrade;
|
||||||
|
|
||||||
|
public class LivingUpgradeDeferredRegister extends WrappedDeferredRegister<LivingUpgrade>
|
||||||
|
{
|
||||||
|
public LivingUpgradeDeferredRegister(String modid)
|
||||||
|
{
|
||||||
|
super(modid, LivingUpgrade.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public BloodOrbRegistryObject<BloodOrb> register(String name, ResourceLocation rl, int tier, int capacity,
|
||||||
|
// int fillRate)
|
||||||
|
// {
|
||||||
|
// return register(name, () -> new BloodOrb(rl, tier, capacity, fillRate));
|
||||||
|
// }
|
||||||
|
|
||||||
|
public <ORB extends LivingUpgrade> LivingUpgradeRegistryObject<ORB> register(String name, Supplier<? extends ORB> sup)
|
||||||
|
{
|
||||||
|
return register(name, sup, LivingUpgradeRegistryObject::new);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package wayoftime.bloodmagic.common.registration.impl;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.RegistryObject;
|
||||||
|
import wayoftime.bloodmagic.common.registration.WrappedRegistryObject;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUpgrade;
|
||||||
|
|
||||||
|
public class LivingUpgradeRegistryObject<UP extends LivingUpgrade> extends WrappedRegistryObject<UP>
|
||||||
|
{
|
||||||
|
public LivingUpgradeRegistryObject(RegistryObject<UP> registryObject)
|
||||||
|
{
|
||||||
|
super(registryObject);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
package wayoftime.bloodmagic.core;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.io.Resources;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.entity.ai.attributes.Attributes;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
import wayoftime.bloodmagic.common.registration.impl.LivingUpgradeDeferredRegister;
|
||||||
|
import wayoftime.bloodmagic.common.registration.impl.LivingUpgradeRegistryObject;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUpgrade;
|
||||||
|
import wayoftime.bloodmagic.gson.Serializers;
|
||||||
|
|
||||||
|
public class LivingArmorRegistrar
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final LivingUpgradeDeferredRegister UPGRADES = new LivingUpgradeDeferredRegister(BloodMagic.MODID);
|
||||||
|
|
||||||
|
public static final Map<ResourceLocation, LivingUpgrade> UPGRADE_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
// public static final DefaultedRegistry<LivingUpgrade> UPGRADES = (DefaultedRegistry<LivingUpgrade>) createRegistry("livingarmor:upgrades", LivingUpgrade.DUMMY.getKey().toString(), () -> LivingUpgrade.DUMMY);
|
||||||
|
// private static final Map<String, ResourceLocation> DEFINITIONS = ((Supplier<Map<String, ResourceLocation>>) () -> {
|
||||||
|
// Map<String, ResourceLocation> def = new HashMap<>();
|
||||||
|
// def.put("arrow_protect", Paths.get(MinecraftForge.getInstance().getConfigDirectory().getAbsolutePath(), "livingarmor", "arrow_protect.json"));
|
||||||
|
// def.put("arrow_shot", Paths.get(FabricLoader.getInstance().getConfigDirectory().getAbsolutePath(), "livingarmor", "arrow_shot.json"));
|
||||||
|
// def.put("critical_strike", Paths.get(FabricLoader.getInstance().getConfigDirectory().getAbsolutePath(), "livingarmor", "critical_strike.json"));
|
||||||
|
// def.put("jump", Paths.get(FabricLoader.getInstance().getConfigDirectory().getAbsolutePath(), "livingarmor", "jump.json"));
|
||||||
|
// return def;
|
||||||
|
// }).get();
|
||||||
|
private static final Map<String, ResourceLocation> DEFINITIONS = ((Supplier<Map<String, ResourceLocation>>) () -> {
|
||||||
|
Map<String, ResourceLocation> def = new HashMap<>();
|
||||||
|
def.put("arrow_protect", BloodMagic.rl("arrow_protect"));
|
||||||
|
def.put("arrow_shot", BloodMagic.rl("arrow_shot"));
|
||||||
|
def.put("critical_strike", BloodMagic.rl("critical_strike"));
|
||||||
|
def.put("jump", BloodMagic.rl("jump"));
|
||||||
|
def.put("health", BloodMagic.rl("health"));
|
||||||
|
def.put("experience", BloodMagic.rl("experienced"));
|
||||||
|
def.put("sprint_attack", BloodMagic.rl("sprint_attack"));
|
||||||
|
def.put("self_sacrifice", BloodMagic.rl("self_sacrifice"));
|
||||||
|
def.put("speed", BloodMagic.rl("speed"));
|
||||||
|
return def;
|
||||||
|
}).get();
|
||||||
|
// private static final Map<String, Path> DEFINITIONS =
|
||||||
|
// ResourceUtil.gatherResources("/data", "living_armor", p ->
|
||||||
|
// FilenameUtils.getExtension(p.toFile().getName()).equals("json"))
|
||||||
|
// .stream()
|
||||||
|
// .collect(Collectors.toMap(key -> FilenameUtils.getBaseName(key.toFile().getName()), value -> value));
|
||||||
|
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
|
||||||
|
|
||||||
|
// public static final ItemLivingArmor LIVING_HELMET = new ItemLivingArmor(EquipmentSlotType.HEAD);
|
||||||
|
// public static final ItemLivingArmor LIVING_CHESTPLATE = new ItemLivingArmor(EquipmentSlotType.CHEST);
|
||||||
|
// public static final ItemLivingArmor LIVING_LEGGINGS = new ItemLivingArmor(EquipmentSlotType.LEGS);
|
||||||
|
// public static final ItemLivingArmor LIVING_BOOTS = new ItemLivingArmor(EquipmentSlotType.FEET);
|
||||||
|
// public static final ItemLivingTrainer TRAINER = new ItemLivingTrainer();
|
||||||
|
// public static final ItemLivingTome TOME = new ItemLivingTome();
|
||||||
|
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_ARROW_PROTECT = UPGRADES.register("arrow_protect", () -> parseDefinition("arrow_protect").withArmorProvider((player, stats, source, upgrade, level) -> {
|
||||||
|
if (source.isProjectile())
|
||||||
|
{
|
||||||
|
return upgrade.getBonusValue("protection", level).doubleValue();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}));
|
||||||
|
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_HEALTH = UPGRADES.register("health", () -> parseDefinition("health").withAttributeProvider((stats, attributeMap, uuid, upgrade, level) -> {
|
||||||
|
attributeMap.put(Attributes.MAX_HEALTH, new AttributeModifier(uuid, "Health Modifier", upgrade.getBonusValue("hp", level).intValue(), AttributeModifier.Operation.ADDITION));
|
||||||
|
}));
|
||||||
|
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_EXPERIENCE = UPGRADES.register("experienced", () -> parseDefinition("experienced"));
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_SPRINT_ATTACK = UPGRADES.register("sprint_attack", () -> parseDefinition("sprint_attack").withDamageProvider((player, weapon, damage, stats, attackedEntity, upgrade, level) -> {
|
||||||
|
if (player.isSprinting())
|
||||||
|
{
|
||||||
|
return damage * upgrade.getBonusValue("damage_boost", level).doubleValue();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}));
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_SELF_SACRIFICE = UPGRADES.register("self_sacrifice", () -> parseDefinition("self_sacrifice"));
|
||||||
|
public static final LivingUpgradeRegistryObject<LivingUpgrade> UPGRADE_SPEED = UPGRADES.register("speed", () -> parseDefinition("speed"));
|
||||||
|
|
||||||
|
// public static final LivingUpgrade UPGRADE_ARROW_PROTECT = parseDefinition("arrow_protect").withArmorProvider((player, stats, source, upgrade, level) -> {
|
||||||
|
// if (source.isProjectile())
|
||||||
|
// {
|
||||||
|
// return upgrade.getBonusValue("protection", level).doubleValue();
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// });
|
||||||
|
// public static final LivingUpgrade UPGRADE_ARROW_SHOT = parseDefinition("arrow_shot");
|
||||||
|
// public static final LivingUpgrade UPGRADE_CRITICAL_STRIKE = parseDefinition("critical_strike").withAttributeProvider((stats, attributeMap, uuid, upgrade, level) -> {
|
||||||
|
// attributeMap.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(uuid, "Weapon modifier", upgrade.getBonusValue("damage_boost", level).doubleValue(), AttributeModifier.Operation.ADDITION));
|
||||||
|
//// attributeMap.put(EntityAttributes.ATTACK_DAMAGE.getId(), AttributeModifiers.create(upgrade, "damage_boost", upgrade.getBonusValue("damage_boost", level).doubleValue(), EntityAttributeModifier.Operation.ADDITION));
|
||||||
|
//// attributeMap.put(EntityAttributes.ATTACK_DAMAGE.getId(), AttributeModifiers.create(upgrade, "damage_boost", level, EntityAttributeModifier.Operation.ADDITION));
|
||||||
|
// });
|
||||||
|
// public static final LivingUpgrade UPGRADE_JUMP = parseDefinition("jump");
|
||||||
|
|
||||||
|
public static void register()
|
||||||
|
{
|
||||||
|
registerUpgrade(UPGRADE_ARROW_PROTECT.get());
|
||||||
|
registerUpgrade(UPGRADE_HEALTH.get());
|
||||||
|
registerUpgrade(UPGRADE_EXPERIENCE.get());
|
||||||
|
registerUpgrade(UPGRADE_SPRINT_ATTACK.get());
|
||||||
|
registerUpgrade(UPGRADE_SELF_SACRIFICE.get());
|
||||||
|
registerUpgrade(UPGRADE_SPEED.get());
|
||||||
|
// Registry.register(UPGRADES, UPGRADE_ARROW_PROTECT.getKey(), UPGRADE_ARROW_PROTECT);
|
||||||
|
// Registry.register(UPGRADES, UPGRADE_ARROW_SHOT.getKey(), UPGRADE_ARROW_SHOT);
|
||||||
|
// Registry.register(UPGRADES, UPGRADE_CRITICAL_STRIKE.getKey(), UPGRADE_CRITICAL_STRIKE);
|
||||||
|
// Registry.register(UPGRADES, UPGRADE_JUMP.getKey(), UPGRADE_JUMP);
|
||||||
|
|
||||||
|
// Registry.register(Registry.ITEM, new ResourceLocation("livingarmor", "living_helmet"), LIVING_HELMET);
|
||||||
|
// Registry.register(Registry.ITEM, new Identifier("livingarmor", "living_chestplate"), LIVING_CHESTPLATE);
|
||||||
|
// Registry.register(Registry.ITEM, new Identifier("livingarmor", "living_leggings"), LIVING_LEGGINGS);
|
||||||
|
// Registry.register(Registry.ITEM, new Identifier("livingarmor", "living_boots"), LIVING_BOOTS);
|
||||||
|
// Registry.register(Registry.ITEM, new Identifier("livingarmor", "trainer"), TRAINER);
|
||||||
|
// Registry.register(Registry.ITEM, new Identifier("livingarmor", "tome"), TOME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerUpgrade(LivingUpgrade upgrade)
|
||||||
|
{
|
||||||
|
UPGRADE_MAP.put(upgrade.getKey(), upgrade);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LivingUpgrade parseDefinition(String fileName)
|
||||||
|
{
|
||||||
|
ResourceLocation path = DEFINITIONS.get(fileName);
|
||||||
|
if (path == null)
|
||||||
|
return LivingUpgrade.DUMMY;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
URL schematicURL = LivingUpgrade.class.getResource(resLocToResourcePath(path));
|
||||||
|
System.out.println("Attempting to load Living Armour Upgrade: " + schematicURL + ", path: " + resLocToResourcePath(path));
|
||||||
|
return Serializers.GSON.fromJson(Resources.toString(schematicURL, Charsets.UTF_8), LivingUpgrade.class);
|
||||||
|
// return GSON.fromJson(IOUtils.toString(path.toUri(), StandardCharsets.UTF_8), LivingUpgrade.class);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return LivingUpgrade.DUMMY;
|
||||||
|
}
|
||||||
|
// Path path = DEFINITIONS.get(fileName);
|
||||||
|
// if (path == null)
|
||||||
|
// return LivingUpgrade.DUMMY;
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// return GSON.fromJson(IOUtils.toString(path.toUri(), StandardCharsets.UTF_8), LivingUpgrade.class);
|
||||||
|
// } catch (Exception e)
|
||||||
|
// {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// return LivingUpgrade.DUMMY;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String resLocToResourcePath(ResourceLocation resourceLocation)
|
||||||
|
{
|
||||||
|
return "/data/" + resourceLocation.getNamespace() + "/living_armor/" + resourceLocation.getPath() + ".json";
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static <T> Registry<T> createRegistry(String registryId, String defaultId, Supplier<T> defaultProvider)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// Method _createRegistry = Registry.class.getDeclaredMethod("create", String.class, String.class, Supplier.class); // FIXME
|
||||||
|
// // yarn
|
||||||
|
// // name
|
||||||
|
// _createRegistry.setAccessible(true);
|
||||||
|
// return (Registry<T>) _createRegistry.invoke(null, registryId, defaultId, defaultProvider);
|
||||||
|
// } catch (Exception e)
|
||||||
|
// {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// MutableRegistry<T> registry = new DefaultedRegistry(defaultId, null, null);
|
||||||
|
// registry.add(new ResourceLocation(defaultId), defaultProvider.get());
|
||||||
|
// return registry;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package wayoftime.bloodmagic.core.living;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public interface ILivingContainer
|
||||||
|
{
|
||||||
|
default LivingStats getLivingStats(ItemStack stack)
|
||||||
|
{
|
||||||
|
if (!stack.hasTag() || !stack.getTag().contains("livingStats"))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return LivingStats.fromNBT(stack.getTag().getCompound("livingStats"));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void updateLivingStats(ItemStack stack, LivingStats stats)
|
||||||
|
{
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
if (stack.hasTag())
|
||||||
|
stack.getTag().remove("livingStats");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stack.hasTag())
|
||||||
|
stack.setTag(new CompoundNBT());
|
||||||
|
|
||||||
|
stack.getTag().put("livingStats", stats.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
static void appendLivingTooltip(LivingStats stats, List<ITextComponent> tooltip, boolean trainable)
|
||||||
|
{
|
||||||
|
if (stats != null)
|
||||||
|
{
|
||||||
|
if (trainable)
|
||||||
|
tooltip.add(new TranslationTextComponent("tooltip.bloodmagic.livingarmour.upgrade.points", stats.getUsedPoints(), stats.getMaxPoints()).mergeStyle(TextFormatting.GOLD));
|
||||||
|
|
||||||
|
stats.getUpgrades().forEach((k, v) -> {
|
||||||
|
if (k.getLevel(v.intValue()) <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean sneaking = Screen.hasShiftDown();
|
||||||
|
// if (!InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(), 340) || k.getNextRequirement(v) == 0)
|
||||||
|
if (!sneaking || k.getNextRequirement(v.intValue()) == 0)
|
||||||
|
tooltip.add(new TranslationTextComponent("%s %s", new TranslationTextComponent(k.getTranslationKey()), new TranslationTextComponent("enchantment.level." + k.getLevel(v.intValue()))));
|
||||||
|
else
|
||||||
|
tooltip.add(new TranslationTextComponent("%s %s", new TranslationTextComponent(k.getTranslationKey()), (": " + v.intValue() + "/" + k.getNextRequirement(v.intValue()))));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
150
src/main/java/wayoftime/bloodmagic/core/living/LivingStats.java
Normal file
150
src/main/java/wayoftime/bloodmagic/core/living/LivingStats.java
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
package wayoftime.bloodmagic.core.living;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import wayoftime.bloodmagic.core.LivingArmorRegistrar;
|
||||||
|
|
||||||
|
public class LivingStats
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final int DEFAULT_UPGRADE_POINTS = 100;
|
||||||
|
|
||||||
|
private final Map<LivingUpgrade, Double> upgrades;
|
||||||
|
private int maxPoints = DEFAULT_UPGRADE_POINTS;
|
||||||
|
|
||||||
|
public LivingStats(Map<LivingUpgrade, Double> upgrades)
|
||||||
|
{
|
||||||
|
this.upgrades = upgrades;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingStats()
|
||||||
|
{
|
||||||
|
this(Maps.newHashMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<LivingUpgrade, Double> getUpgrades()
|
||||||
|
{
|
||||||
|
return ImmutableMap.copyOf(upgrades);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingStats addExperience(ResourceLocation key, double experience)
|
||||||
|
{
|
||||||
|
// LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADES.getOrDefault(key);
|
||||||
|
LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADE_MAP.getOrDefault(key, LivingUpgrade.DUMMY);
|
||||||
|
double current = upgrades.getOrDefault(upgrade, 0d);
|
||||||
|
|
||||||
|
System.out.println("Upgrade: " + upgrade);
|
||||||
|
|
||||||
|
if (upgrade.getNextRequirement((int) current) == 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
upgrades.put(upgrade, current + experience);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel(ResourceLocation key)
|
||||||
|
{
|
||||||
|
LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADE_MAP.getOrDefault(key, LivingUpgrade.DUMMY);
|
||||||
|
// LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADES.getOrDefault(key);
|
||||||
|
return upgrade.getLevel(upgrades.getOrDefault(upgrade, 0d).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUsedPoints()
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
for (Map.Entry<LivingUpgrade, Double> applied : upgrades.entrySet())
|
||||||
|
{
|
||||||
|
double experience = applied.getValue();
|
||||||
|
int level = applied.getKey().getLevel((int) experience);
|
||||||
|
int cost = applied.getKey().getLevelCost(level);
|
||||||
|
total += cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPoints()
|
||||||
|
{
|
||||||
|
return maxPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingStats setMaxPoints(int maxPoints)
|
||||||
|
{
|
||||||
|
this.maxPoints = maxPoints;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundNBT serialize()
|
||||||
|
{
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
ListNBT statList = new ListNBT();
|
||||||
|
upgrades.forEach((k, v) -> {
|
||||||
|
CompoundNBT upgrade = new CompoundNBT();
|
||||||
|
upgrade.putString("key", k.getKey().toString());
|
||||||
|
upgrade.putDouble("exp", v);
|
||||||
|
statList.add(upgrade);
|
||||||
|
});
|
||||||
|
compound.put("upgrades", statList);
|
||||||
|
|
||||||
|
compound.putInt("maxPoints", maxPoints);
|
||||||
|
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deserialize(CompoundNBT nbt)
|
||||||
|
{
|
||||||
|
ListNBT statList = nbt.getList("upgrades", 10);
|
||||||
|
statList.forEach(tag -> {
|
||||||
|
if (!(tag instanceof CompoundNBT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADE_MAP.getOrDefault(new ResourceLocation(((CompoundNBT) tag).getString("key")), LivingUpgrade.DUMMY);
|
||||||
|
if (upgrade == LivingUpgrade.DUMMY)
|
||||||
|
return;
|
||||||
|
double experience = ((CompoundNBT) tag).getDouble("exp");
|
||||||
|
upgrades.put(upgrade, experience);
|
||||||
|
});
|
||||||
|
|
||||||
|
maxPoints = nbt.getInt("maxPoints");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LivingStats fromNBT(CompoundNBT statTag)
|
||||||
|
{
|
||||||
|
LivingStats stats = new LivingStats();
|
||||||
|
stats.deserialize(statTag);
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LivingStats fromPlayer(PlayerEntity player)
|
||||||
|
{
|
||||||
|
return fromPlayer(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LivingStats fromPlayer(PlayerEntity player, boolean createNew)
|
||||||
|
{
|
||||||
|
if (!LivingUtil.hasFullSet(player))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ItemStack chest = player.getItemStackFromSlot(EquipmentSlotType.CHEST);
|
||||||
|
LivingStats stats = ((ILivingContainer) chest.getItem()).getLivingStats(chest);
|
||||||
|
return stats == null && createNew ? new LivingStats() : stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void toPlayer(PlayerEntity player, LivingStats stats)
|
||||||
|
{
|
||||||
|
if (!LivingUtil.hasFullSet(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack chest = player.getItemStackFromSlot(EquipmentSlotType.CHEST);
|
||||||
|
((ILivingContainer) chest.getItem()).updateLivingStats(chest, stats);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,267 @@
|
||||||
|
package wayoftime.bloodmagic.core.living;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||||
|
|
||||||
|
@JsonAdapter(LivingUpgrade.Deserializer.class)
|
||||||
|
public class LivingUpgrade extends ForgeRegistryEntry<LivingUpgrade>
|
||||||
|
{
|
||||||
|
public static final LivingUpgrade DUMMY = new LivingUpgrade(new ResourceLocation("dummy"), levels -> levels.add(new Level(0, 0)));
|
||||||
|
|
||||||
|
private final ResourceLocation key;
|
||||||
|
private final Set<ResourceLocation> incompatible;
|
||||||
|
private final TreeMap<Integer, Integer> experienceToLevel;
|
||||||
|
private final Map<Integer, Integer> levelToCost;
|
||||||
|
private final Map<String, Bonus> bonuses;
|
||||||
|
private boolean isNegative;
|
||||||
|
private String translationKey = null;
|
||||||
|
private IAttributeProvider attributeProvider;
|
||||||
|
private IArmorProvider armorProvider;
|
||||||
|
private IDamageProvider damageProvider;
|
||||||
|
|
||||||
|
public LivingUpgrade(ResourceLocation key, Consumer<List<Level>> experienceMapper)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
this.incompatible = Sets.newHashSet();
|
||||||
|
this.experienceToLevel = Maps.newTreeMap();
|
||||||
|
this.levelToCost = Maps.newHashMap();
|
||||||
|
this.bonuses = Maps.newHashMap();
|
||||||
|
|
||||||
|
List<Level> levels = Lists.newArrayList();
|
||||||
|
experienceMapper.accept(levels);
|
||||||
|
|
||||||
|
for (int i = 0; i < levels.size(); i++)
|
||||||
|
{
|
||||||
|
Level level = levels.get(i);
|
||||||
|
experienceToLevel.put(level.experienceNeeded, i + 1);
|
||||||
|
levelToCost.put(i + 1, level.upgradeCost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade withBonusSet(String id, Consumer<List<Number>> modifiers)
|
||||||
|
{
|
||||||
|
// List<Number> values = DefaultedList.of();
|
||||||
|
List<Number> values = new ArrayList<Number>();
|
||||||
|
modifiers.accept(values);
|
||||||
|
if (values.size() != levelToCost.size())
|
||||||
|
throw new RuntimeException("Bonus size and level size must be the same.");
|
||||||
|
|
||||||
|
bonuses.put(id, new Bonus(id, values));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number getBonusValue(String id, int level)
|
||||||
|
{
|
||||||
|
List<Number> modifiers = bonuses.getOrDefault(id, Bonus.DEFAULT).modifiers;
|
||||||
|
if (modifiers.isEmpty() || level == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return modifiers.get(level - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade withAttributeProvider(IAttributeProvider attributeProvider)
|
||||||
|
{
|
||||||
|
this.attributeProvider = attributeProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAttributeProvider getAttributeProvider()
|
||||||
|
{
|
||||||
|
return attributeProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade withArmorProvider(IArmorProvider armorProvider)
|
||||||
|
{
|
||||||
|
this.armorProvider = armorProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IArmorProvider getArmorProvider()
|
||||||
|
{
|
||||||
|
return armorProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade withDamageProvider(IDamageProvider damageProvider)
|
||||||
|
{
|
||||||
|
this.damageProvider = damageProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDamageProvider getDamageProvider()
|
||||||
|
{
|
||||||
|
return damageProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTranslationKey()
|
||||||
|
{
|
||||||
|
return translationKey == null ? translationKey = Util.makeTranslationKey("living_upgrade", key)
|
||||||
|
: translationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNegative()
|
||||||
|
{
|
||||||
|
return isNegative;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompatible(ResourceLocation otherUpgrade)
|
||||||
|
{
|
||||||
|
return !incompatible.contains(otherUpgrade);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade addIncompatibility(ResourceLocation key, ResourceLocation... otherKeys)
|
||||||
|
{
|
||||||
|
incompatible.add(key);
|
||||||
|
Collections.addAll(incompatible, otherKeys);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevel(int experience)
|
||||||
|
{
|
||||||
|
Map.Entry<Integer, Integer> floor = experienceToLevel.floorEntry(experience);
|
||||||
|
return floor == null ? 0 : floor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNextRequirement(int experience)
|
||||||
|
{
|
||||||
|
Integer ret = experienceToLevel.ceilingKey(experience + 1);
|
||||||
|
return ret == null ? 0 : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLevelCost(int level)
|
||||||
|
{
|
||||||
|
return levelToCost.getOrDefault(level, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLocation getKey()
|
||||||
|
{
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade asDowngrade()
|
||||||
|
{
|
||||||
|
this.isNegative = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return key.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IAttributeProvider
|
||||||
|
{
|
||||||
|
void handleAttributes(LivingStats stats, Multimap<Attribute, AttributeModifier> modifiers, UUID uuid, LivingUpgrade upgrade, int level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IArmorProvider
|
||||||
|
{
|
||||||
|
double getProtection(PlayerEntity player, LivingStats stats, DamageSource source, LivingUpgrade upgrade, int level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IDamageProvider
|
||||||
|
{
|
||||||
|
double getAdditionalDamage(PlayerEntity player, ItemStack weapon, double damage, LivingStats stats, LivingEntity attacked, LivingUpgrade upgrade, int level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Level
|
||||||
|
{
|
||||||
|
@SerializedName("xp")
|
||||||
|
private final int experienceNeeded;
|
||||||
|
@SerializedName("cost")
|
||||||
|
private final int upgradeCost;
|
||||||
|
|
||||||
|
public Level(int experienceNeeded, int upgradeCost)
|
||||||
|
{
|
||||||
|
this.experienceNeeded = experienceNeeded;
|
||||||
|
this.upgradeCost = upgradeCost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Bonus
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final Bonus DEFAULT = new Bonus("null", Collections.emptyList());
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final List<Number> modifiers;
|
||||||
|
|
||||||
|
public Bonus(String id, List<Number> modifiers)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.modifiers = modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Deserializer implements JsonDeserializer<LivingUpgrade>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public LivingUpgrade deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException
|
||||||
|
{
|
||||||
|
JsonObject json = element.getAsJsonObject();
|
||||||
|
ResourceLocation id = new ResourceLocation(json.getAsJsonPrimitive("id").getAsString());
|
||||||
|
List<Level> levels = context.deserialize(json.getAsJsonArray("levels"), new TypeToken<List<Level>>()
|
||||||
|
{
|
||||||
|
}.getType());
|
||||||
|
boolean negative = json.has("negative") && json.getAsJsonPrimitive("negative").getAsBoolean();
|
||||||
|
|
||||||
|
LivingUpgrade upgrade = new LivingUpgrade(id, upgradeLevels -> upgradeLevels.addAll(levels));
|
||||||
|
if (negative)
|
||||||
|
upgrade.asDowngrade();
|
||||||
|
|
||||||
|
if (json.has("incompatibilities"))
|
||||||
|
{
|
||||||
|
String[] incompatibilities = context.deserialize(json.getAsJsonArray("incompatibilities"), String[].class);
|
||||||
|
for (String incompatible : incompatibilities)
|
||||||
|
upgrade.addIncompatibility(new ResourceLocation(incompatible));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.has("bonuses"))
|
||||||
|
{
|
||||||
|
Map<String, Number[]> bonuses = context.deserialize(json.getAsJsonObject("bonuses"), new TypeToken<Map<String, Number[]>>()
|
||||||
|
{
|
||||||
|
}.getType());
|
||||||
|
bonuses.forEach((k, v) -> upgrade.withBonusSet(k, numbers -> Collections.addAll(numbers, v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return upgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
176
src/main/java/wayoftime/bloodmagic/core/living/LivingUtil.java
Normal file
176
src/main/java/wayoftime/bloodmagic/core/living/LivingUtil.java
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package wayoftime.bloodmagic.core.living;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ArmorItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import wayoftime.bloodmagic.common.item.ItemLivingTrainer;
|
||||||
|
import wayoftime.bloodmagic.core.util.PlayerUtil;
|
||||||
|
import wayoftime.bloodmagic.event.LivingEquipmentEvent;
|
||||||
|
|
||||||
|
public class LivingUtil
|
||||||
|
{
|
||||||
|
public static LivingStats applyNewExperience(PlayerEntity player, LivingUpgrade upgrade, double experience)
|
||||||
|
{
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(player, true);
|
||||||
|
if (stats == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!canTrain(player, upgrade, upgrade.getLevel((int) experience)))
|
||||||
|
return stats;
|
||||||
|
|
||||||
|
LivingEquipmentEvent.GainExperience event = new LivingEquipmentEvent.GainExperience(player, stats, upgrade, experience);
|
||||||
|
// EventResult result = LivingEquipmentEvent.EXPERIENCE_GAIN.invoker().gainExperience(event);
|
||||||
|
MinecraftForge.EVENT_BUS.post(event);
|
||||||
|
if (event.isCanceled())
|
||||||
|
return stats;
|
||||||
|
|
||||||
|
experience = event.getExperience();
|
||||||
|
|
||||||
|
double currentExperience = stats.getUpgrades().getOrDefault(upgrade, 0d);
|
||||||
|
double requiredForLevel = upgrade.getNextRequirement((int) currentExperience) - currentExperience;
|
||||||
|
|
||||||
|
// If we're going to level up from this, check points
|
||||||
|
if (requiredForLevel <= experience)
|
||||||
|
{
|
||||||
|
int currentPoints = stats.getUsedPoints();
|
||||||
|
// If we're already capped or somehow over the cap, we don't want to add
|
||||||
|
// experience
|
||||||
|
if (currentPoints >= stats.getMaxPoints())
|
||||||
|
return stats;
|
||||||
|
|
||||||
|
int nextPointCost = upgrade.getLevelCost(upgrade.getLevel((int) currentExperience) + 1);
|
||||||
|
// If there's no more levels in this upgrade, we don't want to add experience
|
||||||
|
if (nextPointCost == -1)
|
||||||
|
return stats;
|
||||||
|
|
||||||
|
// If applying this new level will go over our cap, we don't want to add
|
||||||
|
// experience
|
||||||
|
if (currentPoints + nextPointCost > stats.getMaxPoints())
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newLevel = upgrade.getLevel((int) (currentExperience + experience));
|
||||||
|
if (upgrade.getLevel((int) currentExperience) != newLevel)
|
||||||
|
{
|
||||||
|
LivingEquipmentEvent.LevelUp levelUpEvent = new LivingEquipmentEvent.LevelUp(player, stats, upgrade);
|
||||||
|
// LivingEquipmentEvent.LEVEL_UP.invoker().levelUp(levelUpEvent);
|
||||||
|
MinecraftForge.EVENT_BUS.post(levelUpEvent);
|
||||||
|
|
||||||
|
player.sendStatusMessage(new TranslationTextComponent("chat.bloodmagic.living_upgrade_level_increase", new TranslationTextComponent(upgrade.getTranslationKey()), newLevel), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Adding experience!");
|
||||||
|
|
||||||
|
stats.addExperience(upgrade.getKey(), experience);
|
||||||
|
LivingStats.toPlayer(player, stats);
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getDamageReceivedForArmour(PlayerEntity player, DamageSource source, double damage)
|
||||||
|
{
|
||||||
|
// System.out.println("Initial damage from " + source + ": " + damage);
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(player, true);
|
||||||
|
if (stats == null)
|
||||||
|
return damage;
|
||||||
|
|
||||||
|
Map<LivingUpgrade, Double> upgrades = stats.getUpgrades();
|
||||||
|
for (Entry<LivingUpgrade, Double> entry : upgrades.entrySet())
|
||||||
|
{
|
||||||
|
LivingUpgrade upgrade = entry.getKey();
|
||||||
|
if (upgrade.getArmorProvider() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int level = upgrade.getLevel(entry.getValue().intValue());
|
||||||
|
damage *= 1 - upgrade.getArmorProvider().getProtection(player, stats, source, upgrade, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Final damage: " + damage);
|
||||||
|
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getAdditionalDamage(PlayerEntity player, ItemStack weapon, LivingEntity attackedEntity, double damage)
|
||||||
|
{
|
||||||
|
// System.out.println("Initial damage from " + source + ": " + damage);
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(player, true);
|
||||||
|
if (stats == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
double additionalDamage = 0;
|
||||||
|
|
||||||
|
Map<LivingUpgrade, Double> upgrades = stats.getUpgrades();
|
||||||
|
for (Entry<LivingUpgrade, Double> entry : upgrades.entrySet())
|
||||||
|
{
|
||||||
|
LivingUpgrade upgrade = entry.getKey();
|
||||||
|
if (upgrade.getArmorProvider() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int level = upgrade.getLevel(entry.getValue().intValue());
|
||||||
|
if (upgrade.getDamageProvider() == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
additionalDamage += upgrade.getDamageProvider().getAdditionalDamage(player, weapon, damage, stats, attackedEntity, upgrade, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Final damage: " + damage);
|
||||||
|
|
||||||
|
return additionalDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canTrain(PlayerEntity player, LivingUpgrade upgrade, int currentLevel)
|
||||||
|
{
|
||||||
|
ItemStack trainer = PlayerUtil.findItem(player, stack -> stack.getItem() instanceof ItemLivingTrainer && stack.hasTag() && stack.getTag().contains("livingStats"));
|
||||||
|
if (trainer.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
String mode = trainer.getTag().getString("livingLock");
|
||||||
|
LivingStats stats = ((ILivingContainer) trainer.getItem()).getLivingStats(trainer);
|
||||||
|
|
||||||
|
int levelLimit = stats.getLevel(upgrade.getKey());
|
||||||
|
if (mode.equalsIgnoreCase("whitelist"))
|
||||||
|
{
|
||||||
|
return levelLimit != 0 && levelLimit > currentLevel;
|
||||||
|
} else if (mode.equalsIgnoreCase("blacklist"))
|
||||||
|
{
|
||||||
|
return levelLimit == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasFullSet(PlayerEntity player)
|
||||||
|
{
|
||||||
|
for (ItemStack stack : player.inventory.armorInventory)
|
||||||
|
if (stack.isEmpty() || !(stack.getItem() instanceof ILivingContainer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void applyAttributes(Multimap<Attribute, AttributeModifier> attributes, ItemStack stack, PlayerEntity player, EquipmentSlotType slot)
|
||||||
|
{
|
||||||
|
if (player == null || !hasFullSet(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Multimap<Attribute, AttributeModifier> newAttributes = ((ArmorItem) stack.getItem()).getAttributeModifiers(slot, stack);
|
||||||
|
// newAttributes.values().forEach(e -> e.setSerialize(false));
|
||||||
|
attributes.putAll(newAttributes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package wayoftime.bloodmagic.core.living;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
|
||||||
|
public class ProjectileArmorProvider implements LivingUpgrade.IArmorProvider
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public double getProtection(PlayerEntity player, LivingStats stats, DamageSource source, LivingUpgrade upgrade, int level)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
src/main/java/wayoftime/bloodmagic/core/util/PlayerUtil.java
Normal file
57
src/main/java/wayoftime/bloodmagic/core/util/PlayerUtil.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package wayoftime.bloodmagic.core.util;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import net.minecraft.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import wayoftime.bloodmagic.common.item.ExpandedArmor;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUtil;
|
||||||
|
|
||||||
|
public class PlayerUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
public static ItemStack findItem(PlayerEntity player, Predicate<ItemStack> requirements)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check offhand first
|
||||||
|
ItemStack offHand = player.getHeldItemOffhand();
|
||||||
|
if (requirements.test(offHand))
|
||||||
|
return offHand;
|
||||||
|
|
||||||
|
// Check inventory next
|
||||||
|
for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++)
|
||||||
|
{
|
||||||
|
ItemStack foundStack = player.inventory.getStackInSlot(slot);
|
||||||
|
if (!foundStack.isEmpty() && requirements.test(foundStack))
|
||||||
|
return foundStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Multimap<Attribute, AttributeModifier> handle(PlayerEntity player, Multimap<Attribute, AttributeModifier> existing)
|
||||||
|
{
|
||||||
|
|
||||||
|
ItemStack chest = player.getItemStackFromSlot(EquipmentSlotType.CHEST);
|
||||||
|
boolean hasFullSet = LivingUtil.hasFullSet(player);
|
||||||
|
|
||||||
|
if (hasFullSet && existing == null)
|
||||||
|
{
|
||||||
|
existing = ((ExpandedArmor) chest.getItem()).getAttributeModifiers(EquipmentSlotType.CHEST, chest);
|
||||||
|
player.getAttributeManager().reapplyModifiers(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasFullSet && existing != null)
|
||||||
|
{
|
||||||
|
player.getAttributeManager().removeModifiers(existing);
|
||||||
|
existing = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package wayoftime.bloodmagic.core.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystemAlreadyExistsException;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import wayoftime.bloodmagic.BloodMagic;
|
||||||
|
|
||||||
|
public class ResourceUtil
|
||||||
|
{
|
||||||
|
public static Set<Path> gatherResources(String home, String following, Predicate<Path> predicate)
|
||||||
|
{
|
||||||
|
FileSystem fileSystem = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
URL url = ResourceUtil.class.getResource(home);
|
||||||
|
if (url != null)
|
||||||
|
{
|
||||||
|
URI uri = url.toURI();
|
||||||
|
Path path;
|
||||||
|
if (uri.getScheme().equals("file"))
|
||||||
|
{
|
||||||
|
path = Paths.get(ResourceUtil.class.getResource(home + "/" + following).toURI());
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (!uri.getScheme().equals("jar"))
|
||||||
|
{
|
||||||
|
BloodMagic.LOGGER.error("Unsupported URI scheme {}", uri.getScheme());
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap());
|
||||||
|
} catch (FileSystemAlreadyExistsException e)
|
||||||
|
{
|
||||||
|
fileSystem = FileSystems.getFileSystem(uri);
|
||||||
|
}
|
||||||
|
path = fileSystem.getPath(home + "/" + following);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Files.walk(path).filter(predicate).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(fileSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Path> gatherResources(String home, String following)
|
||||||
|
{
|
||||||
|
return gatherResources(home, following, p -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation addContext(ResourceLocation rl, String context)
|
||||||
|
{
|
||||||
|
return new ResourceLocation(rl.getNamespace(), context + rl.getPath());
|
||||||
|
}
|
||||||
|
}
|
27
src/main/java/wayoftime/bloodmagic/core/util/Value.java
Normal file
27
src/main/java/wayoftime/bloodmagic/core/util/Value.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package wayoftime.bloodmagic.core.util;
|
||||||
|
|
||||||
|
public final class Value<T>
|
||||||
|
{
|
||||||
|
private T value;
|
||||||
|
|
||||||
|
private Value(T t)
|
||||||
|
{
|
||||||
|
this.value = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value<T> set(T t)
|
||||||
|
{
|
||||||
|
this.value = t;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Value<T> of(T t)
|
||||||
|
{
|
||||||
|
return new Value<>(t);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package wayoftime.bloodmagic.event;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingStats;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUpgrade;
|
||||||
|
|
||||||
|
public class LivingEquipmentEvent extends Event
|
||||||
|
{
|
||||||
|
|
||||||
|
// public static final Event<OnExperienceGain> EXPERIENCE_GAIN = EventFactory.createArrayBacked(OnExperienceGain.class, handlers -> e -> {
|
||||||
|
// for (OnExperienceGain gain : handlers) if (gain.gainExperience(e) == EventResult.CANCEL)
|
||||||
|
// return EventResult.CANCEL;
|
||||||
|
//
|
||||||
|
// return EventResult.PASS;
|
||||||
|
// });
|
||||||
|
// public static final Event<OnLevelUp> LEVEL_UP = EventFactory.createArrayBacked(OnLevelUp.class, handlers -> e -> {
|
||||||
|
// for (OnLevelUp levelUp : handlers) levelUp.levelUp(e);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// public interface OnExperienceGain
|
||||||
|
// {
|
||||||
|
// EventResult gainExperience(GainExperience event);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public interface OnLevelUp
|
||||||
|
// {
|
||||||
|
// void levelUp(LevelUp event);
|
||||||
|
// }
|
||||||
|
|
||||||
|
private final PlayerEntity player;
|
||||||
|
private final LivingStats stats;
|
||||||
|
|
||||||
|
private LivingEquipmentEvent(PlayerEntity player, LivingStats stats)
|
||||||
|
{
|
||||||
|
this.player = player;
|
||||||
|
this.stats = stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerEntity getPlayer()
|
||||||
|
{
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingStats getStats()
|
||||||
|
{
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GainExperience extends LivingEquipmentEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
private final LivingUpgrade upgrade;
|
||||||
|
private double experience;
|
||||||
|
|
||||||
|
public GainExperience(PlayerEntity player, LivingStats stats, LivingUpgrade upgrade, double experience)
|
||||||
|
{
|
||||||
|
super(player, stats);
|
||||||
|
this.upgrade = upgrade;
|
||||||
|
this.experience = experience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade getUpgrade()
|
||||||
|
{
|
||||||
|
return upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getExperience()
|
||||||
|
{
|
||||||
|
return experience;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExperience(double experience)
|
||||||
|
{
|
||||||
|
this.experience = experience;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LevelUp extends LivingEquipmentEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
private final LivingUpgrade upgrade;
|
||||||
|
|
||||||
|
public LevelUp(PlayerEntity player, LivingStats stats, LivingUpgrade upgrade)
|
||||||
|
{
|
||||||
|
super(player, stats);
|
||||||
|
|
||||||
|
this.upgrade = upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LivingUpgrade getUpgrade()
|
||||||
|
{
|
||||||
|
return upgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/wayoftime/bloodmagic/event/LivingEvent.java
Normal file
30
src/main/java/wayoftime/bloodmagic/event/LivingEvent.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package wayoftime.bloodmagic.event;
|
||||||
|
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
|
||||||
|
public class LivingEvent extends Event
|
||||||
|
{
|
||||||
|
|
||||||
|
// public static final Event<Jump> JUMP = EventFactory.createArrayBacked(Jump.class, handlers -> e -> {
|
||||||
|
// for (Jump handler : handlers) if (handler.onJump(e) == EventResult.CANCEL)
|
||||||
|
// return EventResult.CANCEL;
|
||||||
|
//
|
||||||
|
// return EventResult.PASS;
|
||||||
|
// });
|
||||||
|
// public static final Event<Damage> DAMAGE = EventFactory.createArrayBacked(Damage.class, handlers -> (e, s, d) -> {
|
||||||
|
// for (Damage handler : handlers) if (handler.onDamage(e, s, d) == EventResult.CANCEL)
|
||||||
|
// return EventResult.CANCEL;
|
||||||
|
//
|
||||||
|
// return EventResult.PASS;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// public interface Jump
|
||||||
|
// {
|
||||||
|
// EventResult onJump(LivingEntity livingEntity);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public interface Damage
|
||||||
|
// {
|
||||||
|
// EventResult onDamage(LivingEntity livingEntity, DamageSource source, Value<Float> damage);
|
||||||
|
// }
|
||||||
|
}
|
|
@ -623,4 +623,112 @@ public class Utils
|
||||||
|
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public static float getModifiedDamage(LivingEntity attackedEntity, DamageSource source, float amount)
|
||||||
|
// {
|
||||||
|
// if (!attackedEntity.isInvulnerableTo(source))
|
||||||
|
// {
|
||||||
|
// if (amount <= 0)
|
||||||
|
// return 0;
|
||||||
|
//
|
||||||
|
// amount = applyArmor(attackedEntity, Iterables.toArray(attackedEntity.getEquipmentAndArmor(), ItemStack.class), source, amount);
|
||||||
|
// if (amount <= 0)
|
||||||
|
// return 0;
|
||||||
|
// amount = applyPotionDamageCalculations(attackedEntity, source, amount);
|
||||||
|
//
|
||||||
|
// return amount;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static float applyArmor(LivingEntity entity, ItemStack[] inventory, DamageSource source, double damage)
|
||||||
|
// {
|
||||||
|
// damage *= 25;
|
||||||
|
// ArrayList<ArmorProperties> dmgVals = new ArrayList<>();
|
||||||
|
// for (int x = 0; x < inventory.length; x++)
|
||||||
|
// {
|
||||||
|
// ItemStack stack = inventory[x];
|
||||||
|
// if (stack.isEmpty())
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// ArmorProperties prop = null;
|
||||||
|
// if (stack.getItem() instanceof ISpecialArmor)
|
||||||
|
// {
|
||||||
|
// ISpecialArmor armor = (ISpecialArmor) stack.getItem();
|
||||||
|
// prop = armor.getProperties(entity, stack, source, damage / 25D, x).copy();
|
||||||
|
// } else if (stack.getItem() instanceof ArmorItem && !source.isUnblockable())
|
||||||
|
// {
|
||||||
|
// ArmorItem armor = (ArmorItem) stack.getItem();
|
||||||
|
// prop = new ArmorProperties(0, armor.damageReduceAmount / 25D, Integer.MAX_VALUE);
|
||||||
|
// }
|
||||||
|
// if (prop != null)
|
||||||
|
// {
|
||||||
|
// prop.Slot = x;
|
||||||
|
// dmgVals.add(prop);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (dmgVals.size() > 0)
|
||||||
|
// {
|
||||||
|
// ArmorProperties[] props = dmgVals.toArray(new ArmorProperties[dmgVals.size()]);
|
||||||
|
// int level = props[0].Priority;
|
||||||
|
// double ratio = 0;
|
||||||
|
// for (ArmorProperties prop : props)
|
||||||
|
// {
|
||||||
|
// if (level != prop.Priority)
|
||||||
|
// {
|
||||||
|
// damage -= (damage * ratio);
|
||||||
|
// ratio = 0;
|
||||||
|
// level = prop.Priority;
|
||||||
|
// }
|
||||||
|
// ratio += prop.AbsorbRatio;
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// damage -= (damage * ratio);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return (float) (damage / 25.0F);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static float applyPotionDamageCalculations(LivingEntity attackedEntity, DamageSource source, float damage)
|
||||||
|
// {
|
||||||
|
// Effect resistance = Effects.RESISTANCE;
|
||||||
|
//
|
||||||
|
// if (source.isDamageAbsolute())
|
||||||
|
// {
|
||||||
|
// return damage;
|
||||||
|
// } else
|
||||||
|
// {
|
||||||
|
// if (attackedEntity.isPotionActive(resistance) && source != DamageSource.OUT_OF_WORLD)
|
||||||
|
// {
|
||||||
|
// int i = (attackedEntity.getActivePotionEffect(resistance).getAmplifier() + 1) * 5;
|
||||||
|
// int j = 25 - i;
|
||||||
|
// float f = damage * (float) j;
|
||||||
|
// damage = f / 25.0F;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (damage <= 0.0F)
|
||||||
|
// {
|
||||||
|
// return 0.0F;
|
||||||
|
// } else
|
||||||
|
// {
|
||||||
|
// int k = EnchantmentHelper.getEnchantmentModifierDamage(attackedEntity.getArmorInventoryList(), source);
|
||||||
|
//
|
||||||
|
// if (k > 20)
|
||||||
|
// {
|
||||||
|
// k = 20;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (k > 0 && k <= 20)
|
||||||
|
// {
|
||||||
|
// int l = 25 - k;
|
||||||
|
// float f1 = damage * (float) l;
|
||||||
|
// damage = f1 / 25.0F;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return damage;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,30 @@
|
||||||
package wayoftime.bloodmagic.util.handler.event;
|
package wayoftime.bloodmagic.util.handler.event;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.enchantment.Enchantments;
|
import net.minecraft.enchantment.Enchantments;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.EquipmentSlotType;
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.potion.EffectInstance;
|
||||||
|
import net.minecraft.potion.Effects;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.common.Tags;
|
import net.minecraftforge.common.Tags;
|
||||||
import net.minecraftforge.common.ToolType;
|
import net.minecraftforge.common.ToolType;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingDamageEvent;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingHealEvent;
|
||||||
|
import net.minecraftforge.event.entity.living.LivingHurtEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerXpEvent;
|
import net.minecraftforge.event.entity.player.PlayerXpEvent;
|
||||||
import net.minecraftforge.event.world.BlockEvent.BlockToolInteractEvent;
|
import net.minecraftforge.event.world.BlockEvent.BlockToolInteractEvent;
|
||||||
|
@ -26,10 +37,14 @@ import wayoftime.bloodmagic.common.item.BloodOrb;
|
||||||
import wayoftime.bloodmagic.common.item.IBindable;
|
import wayoftime.bloodmagic.common.item.IBindable;
|
||||||
import wayoftime.bloodmagic.common.item.IBloodOrb;
|
import wayoftime.bloodmagic.common.item.IBloodOrb;
|
||||||
import wayoftime.bloodmagic.common.item.ItemExperienceBook;
|
import wayoftime.bloodmagic.common.item.ItemExperienceBook;
|
||||||
|
import wayoftime.bloodmagic.core.LivingArmorRegistrar;
|
||||||
import wayoftime.bloodmagic.core.data.Binding;
|
import wayoftime.bloodmagic.core.data.Binding;
|
||||||
import wayoftime.bloodmagic.core.data.SoulNetwork;
|
import wayoftime.bloodmagic.core.data.SoulNetwork;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingStats;
|
||||||
|
import wayoftime.bloodmagic.core.living.LivingUtil;
|
||||||
import wayoftime.bloodmagic.demonaura.WorldDemonWillHandler;
|
import wayoftime.bloodmagic.demonaura.WorldDemonWillHandler;
|
||||||
import wayoftime.bloodmagic.event.ItemBindEvent;
|
import wayoftime.bloodmagic.event.ItemBindEvent;
|
||||||
|
import wayoftime.bloodmagic.event.SacrificeKnifeUsedEvent;
|
||||||
import wayoftime.bloodmagic.network.DemonAuraClientPacket;
|
import wayoftime.bloodmagic.network.DemonAuraClientPacket;
|
||||||
import wayoftime.bloodmagic.potion.BMPotionUtils;
|
import wayoftime.bloodmagic.potion.BMPotionUtils;
|
||||||
import wayoftime.bloodmagic.potion.BloodMagicPotions;
|
import wayoftime.bloodmagic.potion.BloodMagicPotions;
|
||||||
|
@ -100,6 +115,95 @@ public class GenericHandler
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
// Called when an entity is set to be hurt. Called before vanilla armour
|
||||||
|
// calculations.
|
||||||
|
public void onLivingHurt(LivingHurtEvent event)
|
||||||
|
{
|
||||||
|
Entity sourceEntity = event.getSource().getTrueSource();
|
||||||
|
LivingEntity living = event.getEntityLiving();
|
||||||
|
|
||||||
|
if (sourceEntity instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity sourcePlayer = (PlayerEntity) sourceEntity;
|
||||||
|
if (LivingUtil.hasFullSet(sourcePlayer))
|
||||||
|
{
|
||||||
|
ItemStack mainWeapon = sourcePlayer.getActiveItemStack();
|
||||||
|
double additionalDamage = LivingUtil.getAdditionalDamage(sourcePlayer, mainWeapon, living, event.getAmount());
|
||||||
|
event.setAmount((float) (event.getAmount() + additionalDamage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (living instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity player = (PlayerEntity) living;
|
||||||
|
if (LivingUtil.hasFullSet(player))
|
||||||
|
{
|
||||||
|
event.setAmount((float) LivingUtil.getDamageReceivedForArmour(player, event.getSource(), event.getAmount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
// Called after armour calculations (including LivingHurtEvent) are parsed.
|
||||||
|
// Damage that the player should receive after armour/absorption hearts.
|
||||||
|
public void onLivingDamage(LivingDamageEvent event)
|
||||||
|
{
|
||||||
|
Entity sourceEntity = event.getSource().getTrueSource();
|
||||||
|
LivingEntity living = event.getEntityLiving();
|
||||||
|
|
||||||
|
if (sourceEntity instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity sourcePlayer = (PlayerEntity) sourceEntity;
|
||||||
|
if (LivingUtil.hasFullSet(sourcePlayer))
|
||||||
|
{
|
||||||
|
if (sourcePlayer.isSprinting())
|
||||||
|
{
|
||||||
|
LivingUtil.applyNewExperience(sourcePlayer, LivingArmorRegistrar.UPGRADE_SPRINT_ATTACK.get(), event.getAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (living instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity player = (PlayerEntity) living;
|
||||||
|
if (LivingUtil.hasFullSet(player))
|
||||||
|
{
|
||||||
|
if (event.getSource().isProjectile())
|
||||||
|
{
|
||||||
|
// LivingStats stats = LivingStats.fromPlayer(player);
|
||||||
|
// stats.addExperience(LivingArmorRegistrar.TEST_UPGRADE.get().getKey(), 10);
|
||||||
|
LivingUtil.applyNewExperience(player, LivingArmorRegistrar.UPGRADE_ARROW_PROTECT.get(), event.getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
|
public void onExperiencePickupHighest(PlayerXpEvent.PickupXp event)
|
||||||
|
{
|
||||||
|
LivingEntity living = event.getEntityLiving();
|
||||||
|
if (living instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity player = (PlayerEntity) living;
|
||||||
|
if (LivingUtil.hasFullSet(player))
|
||||||
|
{
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(player);
|
||||||
|
double expModifier = 1 + LivingArmorRegistrar.UPGRADE_EXPERIENCE.get().getBonusValue("exp", stats.getLevel(LivingArmorRegistrar.UPGRADE_EXPERIENCE.get().getKey())).doubleValue();
|
||||||
|
System.out.println("Experience modifier: " + expModifier);
|
||||||
|
|
||||||
|
int xp = event.getOrb().xpValue;
|
||||||
|
|
||||||
|
event.getOrb().xpValue = ((int) Math.floor(xp * expModifier) + (player.world.rand.nextDouble() < (xp * expModifier) % 1
|
||||||
|
? 1
|
||||||
|
: 0));
|
||||||
|
|
||||||
|
LivingUtil.applyNewExperience(player, LivingArmorRegistrar.UPGRADE_EXPERIENCE.get(), event.getOrb().getXpValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onHoe(BlockToolInteractEvent event)
|
public void onHoe(BlockToolInteractEvent event)
|
||||||
{
|
{
|
||||||
|
@ -185,4 +289,85 @@ public class GenericHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onHeal(LivingHealEvent event)
|
||||||
|
{
|
||||||
|
LivingEntity living = event.getEntityLiving();
|
||||||
|
if (living instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity player = (PlayerEntity) living;
|
||||||
|
if (LivingUtil.hasFullSet(player))
|
||||||
|
{
|
||||||
|
LivingUtil.applyNewExperience(player, LivingArmorRegistrar.UPGRADE_HEALTH.get(), event.getAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onSelfSacrifice(SacrificeKnifeUsedEvent event)
|
||||||
|
{
|
||||||
|
if (LivingUtil.hasFullSet(event.player))
|
||||||
|
{
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(event.player);
|
||||||
|
double bonus = LivingArmorRegistrar.UPGRADE_SELF_SACRIFICE.get().getBonusValue("self_mod", stats.getLevel(LivingArmorRegistrar.UPGRADE_SELF_SACRIFICE.get().getKey())).doubleValue();
|
||||||
|
event.lpAdded = (int) Math.round(event.lpAdded * (1 + bonus));
|
||||||
|
LivingUtil.applyNewExperience(event.player, LivingArmorRegistrar.UPGRADE_SELF_SACRIFICE.get(), event.healthDrained);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<UUID, Double> posXMap = new HashMap<>();
|
||||||
|
public static Map<UUID, Double> posZMap = new HashMap<>();
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
|
public void onEntityUpdate(LivingEvent.LivingUpdateEvent event)
|
||||||
|
{
|
||||||
|
if (event.getEntity().world.isRemote)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.getEntityLiving() instanceof PlayerEntity)
|
||||||
|
{
|
||||||
|
PlayerEntity player = (PlayerEntity) event.getEntityLiving();
|
||||||
|
float percentIncrease = 0;
|
||||||
|
|
||||||
|
if (LivingUtil.hasFullSet(player))
|
||||||
|
{
|
||||||
|
LivingStats stats = LivingStats.fromPlayer(player);
|
||||||
|
percentIncrease += LivingArmorRegistrar.UPGRADE_SPEED.get().getBonusValue("speed_modifier", stats.getLevel(LivingArmorRegistrar.UPGRADE_SPEED.get().getKey())).doubleValue();
|
||||||
|
if (player.isSprinting())
|
||||||
|
{
|
||||||
|
int speedTime = LivingArmorRegistrar.UPGRADE_SPEED.get().getBonusValue("speed_time", stats.getLevel(LivingArmorRegistrar.UPGRADE_SPEED.get().getKey())).intValue();
|
||||||
|
if (speedTime > 0)
|
||||||
|
{
|
||||||
|
int speedLevel = LivingArmorRegistrar.UPGRADE_SPEED.get().getBonusValue("speed_level", stats.getLevel(LivingArmorRegistrar.UPGRADE_SPEED.get().getKey())).intValue();
|
||||||
|
player.addPotionEffect(new EffectInstance(Effects.SPEED, speedTime, speedLevel, true, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double distance = 0;
|
||||||
|
|
||||||
|
if (posXMap.containsKey(player.getUniqueID()))
|
||||||
|
{
|
||||||
|
distance = Math.sqrt((player.getPosX() - posXMap.get(player.getUniqueID())) * (player.getPosX() - posXMap.get(player.getUniqueID())) + (player.getPosZ() - posZMap.get(player.getUniqueID())) * (player.getPosZ() - posZMap.get(player.getUniqueID())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("Distance travelled: " + distance);
|
||||||
|
if (player.isOnGround() && distance > 0 && distance < 50)
|
||||||
|
{
|
||||||
|
distance *= (1 + percentIncrease);
|
||||||
|
LivingUtil.applyNewExperience(player, LivingArmorRegistrar.UPGRADE_SPEED.get(), distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (percentIncrease > 0 && (player.isOnGround()) && (Math.abs(player.moveForward) > 0 || Math.abs(player.moveStrafing) > 0))
|
||||||
|
{
|
||||||
|
player.travel(new Vector3d(player.moveStrafing * percentIncrease, 0, player.moveForward * percentIncrease));
|
||||||
|
}
|
||||||
|
|
||||||
|
posXMap.put(player.getUniqueID(), player.getPosX());
|
||||||
|
posZMap.put(player.getUniqueID(), player.getPosZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:arrow_protect",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 30, "cost": 4 },
|
||||||
|
{ "xp": 200, "cost": 9 },
|
||||||
|
{ "xp": 400, "cost": 16 },
|
||||||
|
{ "xp": 800, "cost": 30 },
|
||||||
|
{ "xp": 1500, "cost": 60 },
|
||||||
|
{ "xp": 2500, "cost": 90 },
|
||||||
|
{ "xp": 3500, "cost": 125 },
|
||||||
|
{ "xp": 5000, "cost": 165 },
|
||||||
|
{ "xp": 7000, "cost": 210 },
|
||||||
|
{ "xp": 15000, "cost": 250 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"protection": [
|
||||||
|
0.1,
|
||||||
|
0.3,
|
||||||
|
0.4,
|
||||||
|
0.6,
|
||||||
|
0.7,
|
||||||
|
0.75,
|
||||||
|
0.77,
|
||||||
|
0.8,
|
||||||
|
0.83,
|
||||||
|
0.85
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:arrow_shot",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 50, "cost": 20 },
|
||||||
|
{ "xp": 200, "cost": 50 },
|
||||||
|
{ "xp": 700, "cost": 90 },
|
||||||
|
{ "xp": 1500, "cost": 160 },
|
||||||
|
{ "xp": 3000, "cost": 290 }
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:critical_strike",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 200, "cost": 5 },
|
||||||
|
{ "xp": 800, "cost": 12 },
|
||||||
|
{ "xp": 1300, "cost": 22 },
|
||||||
|
{ "xp": 2500, "cost": 35 },
|
||||||
|
{ "xp": 3000, "cost": 49 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"damage_boost": [
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.3,
|
||||||
|
0.4,
|
||||||
|
0.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
53
src/main/resources/data/bloodmagic/living_armor/digging.json
Normal file
53
src/main/resources/data/bloodmagic/living_armor/digging.json
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:digging",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 128, "cost": 5 },
|
||||||
|
{ "xp": 512, "cost": 10 },
|
||||||
|
{ "xp": 1024, "cost": 18 },
|
||||||
|
{ "xp": 2048, "cost": 32 },
|
||||||
|
{ "xp": 8192, "cost": 60 },
|
||||||
|
{ "xp": 16000, "cost": 90 },
|
||||||
|
{ "xp": 32000, "cost": 140 },
|
||||||
|
{ "xp": 50000, "cost": 180 },
|
||||||
|
{ "xp": 80000, "cost": 240 },
|
||||||
|
{ "xp": 150000, "cost": 300 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"speed_time": [
|
||||||
|
0,
|
||||||
|
50,
|
||||||
|
60,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
150,
|
||||||
|
150,
|
||||||
|
150
|
||||||
|
],
|
||||||
|
"speed_level": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"speed_modifier": [
|
||||||
|
1.1,
|
||||||
|
1.2,
|
||||||
|
1.3,
|
||||||
|
1.4,
|
||||||
|
1.5,
|
||||||
|
1.6,
|
||||||
|
1.8,
|
||||||
|
2,
|
||||||
|
2.2,
|
||||||
|
2.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:experienced",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 100, "cost": 7 },
|
||||||
|
{ "xp": 400, "cost": 13 },
|
||||||
|
{ "xp": 1000, "cost": 22 },
|
||||||
|
{ "xp": 1600, "cost": 40 },
|
||||||
|
{ "xp": 3200, "cost": 65 },
|
||||||
|
{ "xp": 5000, "cost": 90 },
|
||||||
|
{ "xp": 7000, "cost": 130 },
|
||||||
|
{ "xp": 9200, "cost": 180 },
|
||||||
|
{ "xp": 11500, "cost": 250 },
|
||||||
|
{ "xp": 14000, "cost": 350 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"exp": [
|
||||||
|
0.15,
|
||||||
|
0.3,
|
||||||
|
0.45,
|
||||||
|
0.6,
|
||||||
|
0.75,
|
||||||
|
0.9,
|
||||||
|
1.05,
|
||||||
|
1.2,
|
||||||
|
1.35,
|
||||||
|
1.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:fall_protect",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 30, "cost": 2 },
|
||||||
|
{ "xp": 200, "cost": 5 },
|
||||||
|
{ "xp": 400, "cost": 9 },
|
||||||
|
{ "xp": 800, "cost": 15 },
|
||||||
|
{ "xp": 1500, "cost": 25 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"protection": [
|
||||||
|
0.2,
|
||||||
|
0.4,
|
||||||
|
0.6,
|
||||||
|
0.8,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:fire_resist",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 1200, "cost": 2 },
|
||||||
|
{ "xp": 3600, "cost": 6 },
|
||||||
|
{ "xp": 12000, "cost": 14 },
|
||||||
|
{ "xp": 24000, "cost": 25 },
|
||||||
|
{ "xp": 30000, "cost": 40 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"cooldown_time": [
|
||||||
|
6000,
|
||||||
|
4800,
|
||||||
|
4800,
|
||||||
|
3600,
|
||||||
|
2400
|
||||||
|
],
|
||||||
|
"resist_duration": [
|
||||||
|
600,
|
||||||
|
600,
|
||||||
|
800,
|
||||||
|
1000,
|
||||||
|
1200
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
29
src/main/resources/data/bloodmagic/living_armor/health.json
Normal file
29
src/main/resources/data/bloodmagic/living_armor/health.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:health",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 80, "cost": 5 },
|
||||||
|
{ "xp": 200, "cost": 12 },
|
||||||
|
{ "xp": 340, "cost": 20 },
|
||||||
|
{ "xp": 540, "cost": 35 },
|
||||||
|
{ "xp": 800, "cost": 49 },
|
||||||
|
{ "xp": 1600, "cost": 78 },
|
||||||
|
{ "xp": 2800, "cost": 110 },
|
||||||
|
{ "xp": 5000, "cost": 160 },
|
||||||
|
{ "xp": 7600, "cost": 215 },
|
||||||
|
{ "xp": 10000, "cost": 320 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"hp": [
|
||||||
|
4,
|
||||||
|
8,
|
||||||
|
12,
|
||||||
|
16,
|
||||||
|
20,
|
||||||
|
26,
|
||||||
|
32,
|
||||||
|
38,
|
||||||
|
44,
|
||||||
|
50
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
41
src/main/resources/data/bloodmagic/living_armor/jump.json
Normal file
41
src/main/resources/data/bloodmagic/living_armor/jump.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:jump",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 10, "cost": 3 },
|
||||||
|
{ "xp": 20, "cost": 6 },
|
||||||
|
{ "xp": 30, "cost": 11 },
|
||||||
|
{ "xp": 40, "cost": 23 },
|
||||||
|
{ "xp": 40, "cost": 37 },
|
||||||
|
{ "xp": 40, "cost": 50 },
|
||||||
|
{ "xp": 40, "cost": 70 },
|
||||||
|
{ "xp": 40, "cost": 100 },
|
||||||
|
{ "xp": 40, "cost": 140 },
|
||||||
|
{ "xp": 40, "cost": 200 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"jump": [
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.3,
|
||||||
|
0.4,
|
||||||
|
0.5,
|
||||||
|
0.7,
|
||||||
|
0.75,
|
||||||
|
0.9,
|
||||||
|
1.1,
|
||||||
|
1.3
|
||||||
|
],
|
||||||
|
"fall": [
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.3,
|
||||||
|
0.4,
|
||||||
|
0.5,
|
||||||
|
0.6,
|
||||||
|
0.7,
|
||||||
|
0.75,
|
||||||
|
0.8,
|
||||||
|
0.85
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:self_sacrifice",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 30, "cost": 7 },
|
||||||
|
{ "xp": 200, "cost": 13 },
|
||||||
|
{ "xp": 400, "cost": 22 },
|
||||||
|
{ "xp": 700, "cost": 40 },
|
||||||
|
{ "xp": 1100, "cost": 65 },
|
||||||
|
{ "xp": 1500, "cost": 90 },
|
||||||
|
{ "xp": 2000, "cost": 130 },
|
||||||
|
{ "xp": 2800, "cost": 180 },
|
||||||
|
{ "xp": 3600, "cost": 250 },
|
||||||
|
{ "xp": 5000, "cost": 350 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"self_mod": [
|
||||||
|
0.15,
|
||||||
|
0.3,
|
||||||
|
0.45,
|
||||||
|
0.6,
|
||||||
|
0.75,
|
||||||
|
0.9,
|
||||||
|
1.05,
|
||||||
|
1.2,
|
||||||
|
1.35,
|
||||||
|
1.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
53
src/main/resources/data/bloodmagic/living_armor/speed.json
Normal file
53
src/main/resources/data/bloodmagic/living_armor/speed.json
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:speed",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 200, "cost": 3 },
|
||||||
|
{ "xp": 1000, "cost": 7 },
|
||||||
|
{ "xp": 2000, "cost": 13 },
|
||||||
|
{ "xp": 4000, "cost": 26 },
|
||||||
|
{ "xp": 7000, "cost": 42 },
|
||||||
|
{ "xp": 15000, "cost": 60 },
|
||||||
|
{ "xp": 25000, "cost": 90 },
|
||||||
|
{ "xp": 35000, "cost": 130 },
|
||||||
|
{ "xp": 50000, "cost": 180 },
|
||||||
|
{ "xp": 70000, "cost": 250 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"speed_time": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
20,
|
||||||
|
60,
|
||||||
|
60,
|
||||||
|
100,
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"speed_level": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"speed_modifier": [
|
||||||
|
0.1,
|
||||||
|
0.2,
|
||||||
|
0.3,
|
||||||
|
0.4,
|
||||||
|
0.5,
|
||||||
|
0.7,
|
||||||
|
0.9,
|
||||||
|
1.1,
|
||||||
|
1.3,
|
||||||
|
1.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"id": "bloodmagic:sprint_attack",
|
||||||
|
"levels": [
|
||||||
|
{ "xp": 200, "cost": 3 },
|
||||||
|
{ "xp": 800, "cost": 7 },
|
||||||
|
{ "xp": 1300, "cost": 15 },
|
||||||
|
{ "xp": 2500, "cost": 25 },
|
||||||
|
{ "xp": 3800, "cost": 40 }
|
||||||
|
],
|
||||||
|
"bonuses": {
|
||||||
|
"damage_boost": [
|
||||||
|
0.5,
|
||||||
|
0.75,
|
||||||
|
1,
|
||||||
|
1.25,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
"kb": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue