Skip to content

Commit

Permalink
[Feature] Breakable mana shield (otland#3848)
Browse files Browse the repository at this point in the history
Co-authored-by: Evil Puncker <[email protected]>
Co-authored-by: Sarah Wesker <[email protected]>
Co-authored-by: Łukasz Zbiżek <[email protected]>
Co-authored-by: AKnopik PC <[email protected]>
Co-authored-by: Ramon Bernardo <[email protected]>
  • Loading branch information
6 people authored Apr 6, 2023
1 parent c287a65 commit 87ca1d6
Show file tree
Hide file tree
Showing 20 changed files with 328 additions and 45 deletions.
3 changes: 3 additions & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ rateLoot = 2
rateMagic = 3
rateSpawn = 1

-- Breakable Mana Shield
useBreakableManaShield = true

-- Monster Despawn Config
-- despawnRange is the amount of floors a monster can be from its spawn position
-- despawnRadius is how many tiles away it can be from its spawn position
Expand Down
18 changes: 9 additions & 9 deletions data/XML/vocations.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<vocations>
<vocation id="0" clientid="0" name="None" description="none" gaincap="10" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" allowPvp="0" fromvoc="0">
<vocation id="0" clientid="0" name="None" description="none" magicshield="0" gaincap="10" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" allowPvp="0" fromvoc="0">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
Expand All @@ -10,7 +10,7 @@
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="1" clientid="3" name="Sorcerer" description="a sorcerer" gaincap="10" gainhp="5" gainmana="30" gainhpticks="6" gainhpamount="5" gainmanaticks="3" gainmanaamount="5" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="1" noPongKickTime="40">
<vocation id="1" clientid="3" name="Sorcerer" description="a sorcerer" magicshield="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="6" gainhpamount="5" gainmanaticks="3" gainmanaamount="5" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="1" noPongKickTime="40">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
Expand All @@ -20,7 +20,7 @@
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="2" clientid="4" name="Druid" description="a druid" gaincap="10" gainhp="5" gainmana="30" gainhpticks="6" gainhpamount="5" gainmanaticks="3" gainmanaamount="5" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="2" noPongKickTime="40">
<vocation id="2" clientid="4" name="Druid" description="a druid" magicshield="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="6" gainhpamount="5" gainmanaticks="3" gainmanaamount="5" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="2" noPongKickTime="40">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="1.8" />
Expand All @@ -30,7 +30,7 @@
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="3" clientid="2" name="Paladin" description="a paladin" gaincap="20" gainhp="10" gainmana="15" gainhpticks="4" gainhpamount="5" gainmanaticks="4" gainmanaamount="5" manamultiplier="1.4" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="3" noPongKickTime="50">
<vocation id="3" clientid="2" name="Paladin" description="a paladin" magicshield="0" gaincap="20" gainhp="10" gainmana="15" gainhpticks="4" gainhpamount="5" gainmanaticks="4" gainmanaamount="5" manamultiplier="1.4" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="3" noPongKickTime="50">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.2" />
<skill id="1" multiplier="1.2" />
Expand All @@ -40,7 +40,7 @@
<skill id="5" multiplier="1.1" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="4" clientid="1" name="Knight" description="a knight" gaincap="25" gainhp="15" gainmana="5" gainhpticks="3" gainhpamount="5" gainmanaticks="6" gainmanaamount="5" manamultiplier="3.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="4">
<vocation id="4" clientid="1" name="Knight" description="a knight" magicshield="0" gaincap="25" gainhp="15" gainmana="5" gainhpticks="3" gainhpamount="5" gainmanaticks="6" gainmanaamount="5" manamultiplier="3.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="4">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.1" />
<skill id="1" multiplier="1.1" />
Expand All @@ -50,7 +50,7 @@
<skill id="5" multiplier="1.1" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="5" clientid="13" name="Master Sorcerer" description="a master sorcerer" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="10" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="1" noPongKickTime="40">
<vocation id="5" clientid="13" name="Master Sorcerer" description="a master sorcerer" magicshield="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="10" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="1" noPongKickTime="40">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
Expand All @@ -60,7 +60,7 @@
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="6" clientid="14" name="Elder Druid" description="an elder druid" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="10" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="2" noPongKickTime="40">
<vocation id="6" clientid="14" name="Elder Druid" description="an elder druid" magicshield="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="10" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="2" noPongKickTime="40">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="1.8" />
Expand All @@ -70,7 +70,7 @@
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="7" clientid="12" name="Royal Paladin" description="a royal paladin" gaincap="20" gainhp="10" gainmana="15" gainhpticks="3" gainhpamount="10" gainmanaticks="3" gainmanaamount="10" manamultiplier="1.4" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="3" noPongKickTime="50">
<vocation id="7" clientid="12" name="Royal Paladin" description="a royal paladin" magicshield="0" gaincap="20" gainhp="10" gainmana="15" gainhpticks="3" gainhpamount="10" gainmanaticks="3" gainmanaamount="10" manamultiplier="1.4" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="3" noPongKickTime="50">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.2" />
<skill id="1" multiplier="1.2" />
Expand All @@ -80,7 +80,7 @@
<skill id="5" multiplier="1.1" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="8" clientid="11" name="Elite Knight" description="an elite knight" gaincap="25" gainhp="15" gainmana="5" gainhpticks="2" gainhpamount="10" gainmanaticks="4" gainmanaamount="10" manamultiplier="3.0" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="4">
<vocation id="8" clientid="11" name="Elite Knight" description="an elite knight" magicshield="0" gaincap="25" gainhp="15" gainmana="5" gainhpticks="2" gainhpamount="10" gainmanaticks="4" gainmanaamount="10" manamultiplier="3.0" attackspeed="2000" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="4">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.1" />
<skill id="1" multiplier="1.1" />
Expand Down
1 change: 1 addition & 0 deletions data/actions/actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
<action fromid="8472" toid="8474" script="others/potions.lua" />
<action itemid="8704" script="others/potions.lua" />
<action fromid="26029" toid="26031" script="others/potions.lua" />
<action itemid="38219" script="others/potions.lua" />

<!-- Other -->
<action itemid="430" script="others/teleport.lua" />
Expand Down
18 changes: 18 additions & 0 deletions data/actions/scripts/others/potions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ bullseye:setParameter(CONDITION_PARAM_SKILL_DISTANCE, 5)
bullseye:setParameter(CONDITION_PARAM_SKILL_SHIELD, -10)
bullseye:setParameter(CONDITION_PARAM_BUFF_SPELL, true)

local manaShield = Condition(CONDITION_MANASHIELD_BREAKABLE)
manaShield:setParameter(CONDITION_PARAM_TICKS, 3 * 60 * 1000)

local function magicShieldCapacity(player)
manaShield:setParameter(CONDITION_PARAM_MANASHIELD_BREAKABLE, math.min(player:getMaxMana(), 300 + 7.6 * player:getLevel() + 7 * player:getMagicLevel()))
end

local potions = {
[6558] = { -- flask of demonic blood
transform = {7588, 7589},
Expand Down Expand Up @@ -52,6 +59,14 @@ local potions = {
description = "Only paladins may drink this potion.",
text = "You feel more accurate."
},
[38219] = { -- magic shield potion
condition = manaShield,
vocations = {1, 2, 5, 6},
level = 14,
effect = CONST_ME_ENERGYAREA,
description = "Only sorcerers and druids of level 14 or above may drink this potion.",
capacity = magicShieldCapacity
},
[7588] = { -- strong health potion
health = {250, 350},
vocations = {
Expand Down Expand Up @@ -178,6 +193,9 @@ function onUse(player, item, fromPosition, target, toPosition, isHotkey)
end

if potion.condition then
if potion.capacity then
potion.capacity(player)
end
player:addCondition(potion.condition)
player:say(potion.text, TALKTYPE_POTION)
player:getPosition():sendMagicEffect(potion.effect)
Expand Down
26 changes: 26 additions & 0 deletions data/scripts/spells/cancel_magic_shield.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
if configManager.getBoolean(configKeys.MANASHIELD_BREAKABLE) then
local combat = Combat()
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, 0)

local cancelMagicShield = Spell(SPELL_INSTANT)

function cancelMagicShield.onCastSpell(creature, var)
creature:removeCondition(CONDITION_MANASHIELD_BREAKABLE)
return combat:execute(creature, var)
end

cancelMagicShield:name("Cancel Magic Shield")
cancelMagicShield:id(44)
cancelMagicShield:words("exana vita")
cancelMagicShield:level(14)
cancelMagicShield:mana(50)
cancelMagicShield:group("support")
cancelMagicShield:isAggressive(false)
cancelMagicShield:isSelfTarget(true)
cancelMagicShield:cooldown(2000)
cancelMagicShield:groupCooldown(2000)
cancelMagicShield:needLearn(false)
cancelMagicShield:vocation("druid;true", "elder druid;true", "sorcerer;true", "master sorcerer;true")
cancelMagicShield:register()
end
48 changes: 48 additions & 0 deletions data/scripts/spells/magic_shield.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- Old mana shield
local combat = Combat()
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local condition = Condition(CONDITION_MANASHIELD)
condition:setParameter(CONDITION_PARAM_TICKS, 60 * 1000)
combat:addCondition(condition)

-- New mana shield
local combatBreakableManaShield = Combat()
combatBreakableManaShield:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combatBreakableManaShield:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

local conditionBreakableManaShield = Condition(CONDITION_MANASHIELD_BREAKABLE)
conditionBreakableManaShield:setParameter(CONDITION_PARAM_TICKS, 60 * 1000)

local magicShield = Spell(SPELL_INSTANT)

function magicShield.onCastSpell(creature, variant)
if configManager.getBoolean(configKeys.MANASHIELD_BREAKABLE) then
local player = creature:getPlayer()
if player then
conditionBreakableManaShield:setParameter(CONDITION_PARAM_MANASHIELD_BREAKABLE, math.min(player:getMaxMana(), 300 + 7.6 * player:getLevel() + 7 * player:getMagicLevel()))
player:addCondition(conditionBreakableManaShield)
return combatBreakableManaShield:execute(creature, variant)
end
end
return combat:execute(creature, variant)
end

magicShield:name("Magic Shield")
magicShield:id(44)
magicShield:words("utamo vita")
magicShield:level(14)
magicShield:mana(50)
magicShield:group("support")
magicShield:isAggressive(false)
magicShield:isSelfTarget(true)
if configManager.getBoolean(configKeys.MANASHIELD_BREAKABLE) then
magicShield:cooldown(14000)
else
magicShield:cooldown(2000)
end
magicShield:groupCooldown(2000)
magicShield:needLearn(false)
magicShield:vocation("druid;true", "elder druid;true", "sorcerer;true", "master sorcerer;true")
magicShield:register()
11 changes: 0 additions & 11 deletions data/spells/scripts/support/magic_shield.lua

This file was deleted.

6 changes: 0 additions & 6 deletions data/spells/spells.xml
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,6 @@
<vocation name="Royal Paladin" />
<vocation name="Elite Knight" />
</instant>
<instant group="support" spellid="44" name="Magic Shield" words="utamo vita" level="14" mana="50" aggressive="0" selftarget="1" cooldown="2000" groupcooldown="2000" needlearn="0" script="support/magic_shield.lua">
<vocation name="Sorcerer" />
<vocation name="Druid" />
<vocation name="Master Sorcerer" />
<vocation name="Elder Druid" />
</instant>
<instant group="support" spellid="132" name="Protector" words="utamo tempo" level="55" mana="200" premium="1" aggressive="0" selftarget="1" cooldown="2000" groupcooldown="2000" needlearn="0" script="support/protector.lua">
<vocation name="Knight" />
<vocation name="Elite Knight" />
Expand Down
107 changes: 106 additions & 1 deletion src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,10 @@ Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, in
case CONDITION_PACIFIED:
case CONDITION_MANASHIELD:
return new ConditionGeneric(id, type, ticks, buff, subId, aggressive);

case CONDITION_ROOT:
return new ConditionGeneric(id, type, ticks, buff, subId, aggressive);
case CONDITION_MANASHIELD_BREAKABLE:
return new ConditionManaShield(id, type, ticks, buff, subId);

default:
return nullptr;
Expand Down Expand Up @@ -1969,3 +1970,107 @@ bool ConditionDrunk::setParam(ConditionParam_t param, int32_t value)
}
}
}

bool ConditionManaShield::startCondition(Creature* creature)
{
if (!Condition::startCondition(creature)) {
return false;
}

if (Player* player = creature->getPlayer()) {
const auto& conditionManaShield = static_cast<const ConditionManaShield&>(*this);
manaShield = conditionManaShield.manaShield;
maxManaShield = conditionManaShield.manaShield;
player->sendStats();
return true;
}
return false;
}

void ConditionManaShield::endCondition(Creature* creature)
{
if (Player* player = creature->getPlayer()) {
player->sendStats();
}
}

void ConditionManaShield::addCondition(Creature* creature, const Condition* addCondition)
{
if (Player* player = creature->getPlayer()) {
endCondition(player);
setTicks(addCondition->getTicks());

const auto& conditionManaShield = static_cast<const ConditionManaShield&>(*addCondition);
manaShield = conditionManaShield.manaShield;
maxManaShield = conditionManaShield.manaShield;
player->sendStats();
}
}

bool ConditionManaShield::unserializeProp(ConditionAttr_t attr, PropStream& propStream)
{
if (attr == CONDITIONATTR_MANASHIELD_BREAKABLE_MANA) {
return propStream.read<uint16_t>(manaShield);
}

if (attr == CONDITIONATTR_MANASHIELD_BREAKABLE_MAXMANA) {
return propStream.read<uint16_t>(maxManaShield);
}
return Condition::unserializeProp(attr, propStream);
}

int32_t ConditionManaShield::onDamageTaken(Player* player, int32_t manaChange)
{
if (!player) {
return 0;
}

if (manaChange > manaShield) {
return manaChange - manaShield;
}

manaShield -= manaChange;

player->sendStats();
return 0;
}

void ConditionManaShield::serialize(PropWriteStream& propWriteStream)
{
Condition::serialize(propWriteStream);

propWriteStream.write<uint8_t>(CONDITIONATTR_MANASHIELD_BREAKABLE_MANA);
propWriteStream.write<uint16_t>(manaShield);
propWriteStream.write<uint8_t>(CONDITIONATTR_MANASHIELD_BREAKABLE_MAXMANA);
propWriteStream.write<uint16_t>(maxManaShield);
}

bool ConditionManaShield::setParam(ConditionParam_t param, int32_t value)
{
bool ret = Condition::setParam(param, value);

switch (param) {
case CONDITION_PARAM_MANASHIELD_BREAKABLE:
manaShield = value;
return true;

default:
return ret;
}
}

uint32_t ConditionManaShield::getIcons() const
{
uint32_t icons = Condition::getIcons();

switch (conditionType) {
case CONDITION_MANASHIELD_BREAKABLE:
icons |= ICON_MANASHIELD_BREAKABLE;
break;

default:
break;
}

return icons;
}
Loading

0 comments on commit 87ca1d6

Please sign in to comment.