diff --git a/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt b/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt new file mode 100644 index 000000000..c195a6f98 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt @@ -0,0 +1,147 @@ +package content.global.handlers.item + +import content.global.handlers.item.equipment.special.DragonfireSwingHandler +import core.ServerConstants +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.global.action.DropListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatPulse.Companion.swing +import core.game.node.entity.combat.InteractionType +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.item.ItemPlugin +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.minutesToTicks +import core.tools.secondsToTicks +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * Handles the dragonfire shield options. + */ + +class DragonfireShieldListener: InteractionListener { + + val dragonfireShields = intArrayOf(Items.DRAGONFIRE_SHIELD_11283, Items.DRAGONFIRE_SHIELD_11284) + val dfsEmptyAnim = 6700 + val dfsEmptyGfx = 1160 + val dfsRecharge = if (ServerConstants.BETTER_DFS) secondsToTicks(30) else minutesToTicks(2) + + override fun defineListeners() { + + on(dragonfireShields, IntType.ITEM, "operate") { player, node -> + val usingAttack = !getAttribute(player, "dfs_spec", false) + if (!usingAttack) { + if (!player.settings.isSpecialToggled) { + setVarp(player, 301, 0) + } + player.removeAttribute("dfs_spec") + player.properties.combatPulse.temporaryHandler = null + return@on true + } + val notCharged = node.asItem().id == Items.DRAGONFIRE_SHIELD_11284 || node.asItem().charge < 20 + if (notCharged) { + sendMessage(player, "Your shield has no charges left.") + return@on true + } + if (player.locks.isLocked("dfs_recharge")) { + sendMessage(player, "Your dragonfire shield is recharging.") + return@on true + } + setVarp(player, 301, 1) + player.setAttribute("dfs_spec", true) + val attack = SwitchAttack(null, Animation.create(6696), Graphics.create(1165), Graphics(1167, 96), Projectile.create(player, null, 1166, 36, 36, 80, 70, 0, 11)) + val handler: DragonfireSwingHandler = object : DragonfireSwingHandler(false, 25, attack, true) { + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + if (entity is Player) { + if (!player.settings.isSpecialToggled) { + setVarp(player, 301, 0) + } + removeAttribute(player, "dfs_spec") + val shield = player.equipment[EquipmentContainer.SLOT_SHIELD] + if (shield == null || shield.id != Items.DRAGONFIRE_SHIELD_11283) { + return -1 + } + playGlobalAudio(entity.getLocation(), Sounds.DRAGONSLAYER_SHIELDFIRE_3761) + delayEntity(player, 3) + shield.charge -= 20 + if (shield.charge < 20 && node.asItem().slot == EquipmentContainer.SLOT_SHIELD) { + replaceSlot(player, node.asItem().slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283), Container.EQUIPMENT) + } + EquipmentContainer.updateBonuses(player) + player.locks.lock("dfs_recharge", dfsRecharge) + } + return super.swing(entity, victim, state) + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + playGlobalAudio(victim!!.location, Sounds.FIRESTRIKE_HIT_161, 20) + super.visualizeImpact(entity, victim, state) + } + } + attack.handler = handler + val victim = player.properties.combatPulse.getVictim() + if (player.properties.combatPulse.isAttacking && handler.canSwing(player, victim!!) == InteractionType.STILL_INTERACT) { + swing(player, victim, handler) + return@on true + } + player.properties.combatPulse.temporaryHandler = handler + return@on true + } + + on(dragonfireShields, IntType.ITEM, "empty") { player, node -> + replaceSlot(player, node.asItem().slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283)) + visualize(player, dfsEmptyAnim, dfsEmptyGfx) + sendMessage(player, "You release the charges.") + playGlobalAudio(player.location, Sounds.DRAGONSLAYER_SHIELD_EMPTY_3760) + return@on true + } + + on(dragonfireShields, IntType.ITEM, "inspect") { player, node -> + if (node.asItem().id == Items.DRAGONFIRE_SHIELD_11284) { + sendMessage(player, "The shield has no charges.") + return@on true + } + sendMessage(player, "The shield has " + node.asItem().charge / 20 + " charges.") + return@on true + } + + on(dragonfireShields, IntType.ITEM, "drop") { player, node -> + var shield = node.asItem() + val slot = shield.slot + if (shield.id == Items.DRAGONFIRE_SHIELD_11283) { + replaceSlot(player, shield.slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283)) + shield = player.inventory.get(slot) + } + DropListener.drop(player, shield) + return@on true + } + } +} + +/** + * Drops the uncharged dragonfire shield item id on death. + */ + +@Initializable +class DFSItemPlugin : ItemPlugin() { + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + register(Items.DRAGONFIRE_SHIELD_11283) + return this + } + + override fun getDeathItem(item: Item?): Item { + return Item(Items.DRAGONFIRE_SHIELD_11284) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/DragonfireShieldPlugin.java b/Server/src/main/content/global/handlers/item/DragonfireShieldPlugin.java deleted file mode 100644 index 78f464d07..000000000 --- a/Server/src/main/content/global/handlers/item/DragonfireShieldPlugin.java +++ /dev/null @@ -1,149 +0,0 @@ -package content.global.handlers.item; - -import core.cache.def.impl.ItemDefinition; -import core.game.container.impl.EquipmentContainer; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.InteractionType; -import core.game.node.entity.combat.equipment.SwitchAttack; -import content.global.handlers.item.equipment.special.DragonfireSwingHandler; -import core.game.node.entity.impl.Projectile; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.node.item.ItemPlugin; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import core.game.node.entity.combat.CombatPulse; -import core.game.world.GameWorld; -import core.plugin.ClassScanner; -import org.rs09.consts.Sounds; - -import java.util.concurrent.TimeUnit; - -import static core.api.ContentAPIKt.*; - -/** - * Handles the dragonfire shield options. - * @author Emperor - */ -@Initializable -public final class DragonfireShieldPlugin extends OptionHandler { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ItemDefinition.forId(11283).getHandlers().put("option:empty", this); - ItemDefinition.forId(11283).getHandlers().put("option:inspect", this); - ItemDefinition.forId(11283).getHandlers().put("option:operate", this); - ItemDefinition.forId(11284).getHandlers().put("option:inspect", this); - ItemDefinition.forId(11284).getHandlers().put("option:operate", this); - ClassScanner.definePlugin(new DFSItemPlugin()); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - Item item = (Item) node; - switch (option) { - case "operate": - boolean usingAttack = !player.getAttribute("dfs_spec", false); - if (!usingAttack) { - if (!player.getSettings().isSpecialToggled()) { - setVarp(player, 301, 0); - } - player.removeAttribute("dfs_spec"); - player.getProperties().getCombatPulse().setTemporaryHandler(null); - return true; - } - boolean notCharged = item.getId() == 11284 || item.getCharge() < 20; - if (player.getSavedData().getGlobalData().getOverChargeDelay() <= System.currentTimeMillis()) { - item.setCharge(1020); - player.sendMessage("You use the power from the overcharge lords & charge your shield."); - notCharged = false; - player.getSavedData().getGlobalData().setOverChargeDelay(System.currentTimeMillis() + (GameWorld.getSettings().isDevMode() ? TimeUnit.SECONDS.toMillis(10) : TimeUnit.MINUTES.toMicros(10))); - } - if (notCharged) { - player.getPacketDispatch().sendMessage("Your shield has no charges left."); - return true; - } - if (player.getLocks().isLocked("dfs_recharge")) { - player.getPacketDispatch().sendMessage("Your dragonfire shield is recharging."); - return true; - } - setVarp(player, 301, 1); - player.setAttribute("dfs_spec", true); - SwitchAttack attack = new SwitchAttack(null, Animation.create(6696), Graphics.create(1165), new Graphics(1167, 96), Projectile.create(player, null, 1166, 36, 36, 80, 70, 0, 11)); - DragonfireSwingHandler handler = new DragonfireSwingHandler(false, 26, attack, true) { - @Override - public int swing(Entity entity, Entity victim, BattleState state) { - if (entity instanceof Player) { - Player player = (Player) entity; - if (!player.getSettings().isSpecialToggled()) { - setVarp(player, 301, 0); - } - player.removeAttribute("dfs_spec"); - playGlobalAudio(entity.getLocation(), Sounds.DRAGONSLAYER_SHIELDFIRE_3761); - Item shield = player.getEquipment().get(EquipmentContainer.SLOT_SHIELD); - if (shield == null || shield.getId() != 11283) { - return -1; - } - shield.setCharge(shield.getCharge() - 20); - if (shield.getCharge() < 1) { - player.getEquipment().replace(new Item(11284), EquipmentContainer.SLOT_SHIELD); - } - EquipmentContainer.updateBonuses(player); - player.getLocks().lock("dfs_recharge",50); - } - return super.swing(entity, victim, state); - } - @Override - public void visualizeImpact(Entity entity, Entity victim, BattleState state) { - playGlobalAudio(victim.getLocation(), Sounds.FIRESTRIKE_HIT_161, 20); - super.visualizeImpact(entity, victim, state); - } - - }; - attack.setHandler(handler); - Entity victim = player.getProperties().getCombatPulse().getVictim(); - if (player.getProperties().getCombatPulse().isAttacking() && handler.canSwing(player, victim) == InteractionType.STILL_INTERACT) { - CombatPulse.Companion.swing(player, victim, handler); - return true; - } - player.getProperties().getCombatPulse().setTemporaryHandler(handler); - return true; - case "empty": - player.getInventory().replace(new Item(11284), item.getSlot()); - player.graphics(Graphics.create(1160)); - player.getPacketDispatch().sendMessage("You release the charges."); - playGlobalAudio(player.getLocation(), Sounds.DRAGONSLAYER_SHIELD_EMPTY_3760); - return true; - case "inspect": - if (item.getId() == 11284) { - player.getPacketDispatch().sendMessage("The shield has no charges."); - return true; - } - player.getPacketDispatch().sendMessage("The shield has " + (item.getCharge() / 20) + " charges."); - return true; - } - return false; - } - - public class DFSItemPlugin extends ItemPlugin { - - @Override - public Plugin newInstance(Object arg) throws Throwable { - register(11283); - return this; - } - - @Override - public Item getDeathItem(Item item) { - return new Item(11284); - } - - } - -} diff --git a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt new file mode 100644 index 000000000..3b5f498ad --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt @@ -0,0 +1,89 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import java.util.* + +/** + * Handles items with "empty" options + */ +class EmptyOptionListener : InteractionListener { + + override fun defineListeners() { + + on(IntType.ITEM, "empty", "empty bowl") { player, node -> + if (node.name.contains("brew") || node.name.contains("potion") || node.name.lowercase(Locale.getDefault()).contains("poison") || node.name.lowercase(Locale.getDefault()).contains("serum") || node.name.contains("cure") || node.name.contains("mix") || node.name.contains("balm")) { + if (removeItem(player, node.id)) { + addItem(player, EmptyItem.getEmpty(Items.POTION_195)!!) + playAudio(player, EmptyItem.getEmptyAudio(Items.POTION_195)!!) + } + return@on true + } + if (EmptyItem.emptyItemMap[node.id] != null) { + if (removeItem(player, node.id)) { + addItem(player, EmptyItem.getEmpty(node.id)!!) + if (EmptyItem.getEmptyAudio(node.id) != -1) playAudio(player, EmptyItem.getEmptyAudio(node.id)!!) + EmptyItem.getEmptyMessage(node.id)?.let { sendMessage(player, it) } + } + } + return@on true + } + } + + enum class EmptyItem(var fullId: Int, var emptyId: Int, var emptyMessage: String, var audioId: Int = -1) { + POT_OF_FLOUR(Items.POT_OF_FLOUR_1933, Items.EMPTY_POT_1931, "You empty the contents of the pot onto the floor."), + POT_OF_CORNFLOUR(Items.POT_OF_CORNFLOUR_7468, Items.EMPTY_POT_1931, "You empty the contents of the pot onto the floor."), + BONE_MEAL(Items.BONEMEAL_4255, Items.EMPTY_POT_1931, "You empty the pot of crushed bones."), + BUCKET_OF_SAND(Items.BUCKET_OF_SAND_1783, Items.BUCKET_1925, "You empty the contents of the bucket onto the floor.", Sounds.SAND_BUCKET_2584), + BUCKET_OF_MILK(Items.BUCKET_OF_MILK_1927, Items.BUCKET_1925, "You empty the contents of the bucket onto the floor.", Sounds.LIQUID_2401), + BUCKET_OF_WATER(Items.BUCKET_OF_WATER_1929, Items.BUCKET_1925, "You empty the contents of the bucket onto the floor.", Sounds.LIQUID_2401), + BUCKET_OF_COMPOST(Items.COMPOST_6032, Items.BUCKET_1925, "You empty the bucket of compost."), + BUCKET_OF_SUPERCOMPOST(Items.SUPERCOMPOST_6034, Items.BUCKET_1925, "You empty the bucket of supercompost."), + BUCKET_OF_SLIME(Items.BUCKET_OF_SLIME_4286, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401), + VIAL_OF_WATER(Items.VIAL_OF_WATER_227, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), + BOWL_OF_WATER(Items.BOWL_OF_WATER_1921, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + JUG_OF_WATER(Items.JUG_OF_WATER_1937, Items.JUG_1935, "You empty the contents of the jug onto the floor.", Sounds.LIQUID_2401), + BURNT_PIE(Items.BURNT_PIE_2329, Items.PIE_DISH_2313, "You empty the pie dish."), + POTION(Items.POTION_195, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), + BURNT_STEW(Items.BURNT_STEW_2005, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA(Items.NETTLE_TEA_4239, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_WATER(Items.NETTLE_WATER_4237, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA_MILKY(Items.NETTLE_TEA_4240, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + BURNT_CURRY(Items.BURNT_CURRY_2013, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."), + BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."), + BURNT_ONION(Items.BURNT_ONION_7092, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."), + BURNT_MUSHROOM(Items.BURNT_MUSHROOM_7094, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."); + + companion object { + var emptyItemMap = HashMap() + var emptyMessageMap = HashMap() + var emptyAudioMap = HashMap() + + init { + for (item in values()) { + emptyItemMap.putIfAbsent(item.fullId, item.emptyId) + emptyMessageMap.putIfAbsent(item.fullId, item.emptyMessage) + emptyAudioMap.putIfAbsent(item.fullId, item.audioId) + } + } + + fun getEmpty(id: Int): Int? { + return emptyItemMap[id] + } + + fun getEmptyMessage(id: Int): String? { + return emptyMessageMap[id] + } + + fun getEmptyAudio(id: Int): Int? { + return emptyAudioMap[id] + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/EmptyOptionPlugin.java b/Server/src/main/content/global/handlers/item/EmptyOptionPlugin.java deleted file mode 100644 index ac51b226b..000000000 --- a/Server/src/main/content/global/handlers/item/EmptyOptionPlugin.java +++ /dev/null @@ -1,108 +0,0 @@ -package content.global.handlers.item; - -import core.cache.def.impl.ItemDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import java.util.HashMap; - -import static core.api.ContentAPIKt.playAudio; - -/** - * Handles items with "empty" options - * @author ceik - */ -@Initializable -public final class EmptyOptionPlugin extends OptionHandler { - public static final int BUCKET = 1925; - public static final int VIAL = 229; - public static final String BUCKET_EMPTY_MSG = "You empty the contents of the bucket onto the floor."; - @Override - public boolean handle(Player player, Node node, String option) { - if (node.getName().contains("brew") || node.getName().contains("potion") || node.getName().toLowerCase().contains("poison") || node.getName().contains("serum")) { - player.getInventory().remove(node.asItem()); - player.getInventory().add(EmptyItem.getEmpty(91)); - return true; - } - if(EmptyItem.emptyItemMap.get(node.getId()) != null){ - player.getInventory().remove(node.asItem()); - playAudio(player, Sounds.LIQUID_2401, 0 ,1); - player.getInventory().add(EmptyItem.getEmpty(node.getId())); - player.getPacketDispatch().sendMessage(EmptyItem.getEmptyMessage(node.getId())); - } else { - player.debug("Unhandled empty option! ITEM ID: " + node.getId()); - } - return true; - } - - @Override - public boolean isWalk() { - return false; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ItemDefinition.setOptionHandler("empty", this); - ItemDefinition.setOptionHandler("empty dish", this); - ItemDefinition.setOptionHandler("empty bowl", this); - return this; - } - public enum EmptyItem{ - POT_OF_FLOUR(1933, 1931, "You empty the contents of the pot onto the floor."), - POT_OF_CORNFLOUR(7468, 1931, "You empty the contents of the pot onto the floor."), - BONE_MEAL(4255, 1931, "You empty the pot of crushed bones."), - BUCKET_OF_SAND(1783, BUCKET, BUCKET_EMPTY_MSG), - BUCKET_OF_MILK(1927, BUCKET, BUCKET_EMPTY_MSG), - BUCKET_OF_WATER(1929, BUCKET, BUCKET_EMPTY_MSG), - BUCKET_OF_COMPOST(6032, BUCKET, "You empty the bucket of compost."), - BUCKET_OF_SUPERCOMPOST(6034, BUCKET, "You empty the bucket of supercompost."), - BUCKET_OF_SLIME(4286, BUCKET, "You empty the contents of the bucket on the floor."), - VIAL_OF_WATER(227, VIAL, "You empty the vial."), - BOWL_OF_WATER(1921, 1923, "You empty the contents of the bowl onto the floor."), - JUG_OF_WATER(1937, 1935, "You empty the contents of the jug onto the floor."), - BURNT_PIE(2329, 2313, "You empty the pie dish."), - POTION(91, VIAL,null), - BURNT_STEW(2005, 1923, "You empty the contents of the bowl onto the floor."), - NETTLE_TEA(4239, 1923, "You empty the contents of the bowl onto the floor."), - NETTLE_WATER(4237, 1923, "You empty the contents of the bowl onto the floor."), - NETTLE_TEA_MILKY(4240, 1923, "You empty the contents of the bowl onto the floor."), - BURNT_CURRY(2013, 1923, "You empty the contents of the bowl onto the floor."), - BURNT_GNOMEBOWL(2175, 2166, "You empty the contents of the gnomebowl onto the floor."), - BURNT_EGG(7090, 1923, "You empty the contents of the bowl onto the floor."), - BURNT_ONION(7092, 1923, "You empty the contents of the bowl onto the floor."), - BURNT_MUSHROOM(7094, 1923, "You empty the contents of the bowl onto the floor."); - - - - int fullId, emptyId; - String emptyMessage; - EmptyItem(int fullId, int emptyId, String emptyMessage){ - this.fullId = fullId; - this.emptyId = emptyId; - this.emptyMessage = emptyMessage; - } - - public static HashMap emptyItemMap = new HashMap<>(); - public static HashMap emptyMessageMap = new HashMap<>(); - - static{ - for(EmptyItem item : EmptyItem.values()){ - emptyItemMap.putIfAbsent(item.fullId,item.emptyId); - emptyMessageMap.putIfAbsent(item.fullId,item.emptyMessage); - } - } - - public static Item getEmpty(int id){ - return new Item(emptyItemMap.get(id)); - } - - public static String getEmptyMessage(int id){ - return emptyMessageMap.get(id); - } - } -} diff --git a/Server/src/main/core/ServerConstants.kt b/Server/src/main/core/ServerConstants.kt index 53bd6c9a2..4899816b2 100644 --- a/Server/src/main/core/ServerConstants.kt +++ b/Server/src/main/core/ServerConstants.kt @@ -305,5 +305,8 @@ class ServerConstants { @JvmField var BETTER_AGILITY_PYRAMID_GP = true + + @JvmField + var BETTER_DFS = true } } diff --git a/Server/src/main/core/game/system/config/ServerConfigParser.kt b/Server/src/main/core/game/system/config/ServerConfigParser.kt index f422e01b1..9d24882a8 100644 --- a/Server/src/main/core/game/system/config/ServerConfigParser.kt +++ b/Server/src/main/core/game/system/config/ServerConfigParser.kt @@ -159,6 +159,7 @@ object ServerConfigParser { ServerConstants.GRAFANA_PATH = data.getPath("integrations.grafana_log_path") ServerConstants.GRAFANA_LOGGING = data.getBoolean("integrations.grafana_logging", false) ServerConstants.GRAFANA_TTL_DAYS = data.getLong("integrations.grafana_log_ttl_days", 7L).toInt() + ServerConstants.BETTER_DFS = data.getBoolean("world.better_dfs", true) val logLevel = data.getString("server.log_level", "VERBOSE").uppercase() ServerConstants.LOG_LEVEL = parseEnumEntry(logLevel) ?: LogLevel.VERBOSE diff --git a/Server/worldprops/default.conf b/Server/worldprops/default.conf index b5f664ccd..f94c0649d 100644 --- a/Server/worldprops/default.conf +++ b/Server/worldprops/default.conf @@ -93,6 +93,8 @@ revenant_population = 30 i_want_to_cheat = false #better agility pyramid gp reward (gp reward = 1000 + ((agility level / 99) * 9000)) better_agility_pyramid_gp = true +#better dragonfire shield attack (30 second cooldown instead of 2 minutes) +better_dfs = true [paths] #path to the data folder, which contains the cache subfolder and such