Leo32
Getting back into it...
- Joined
- Sep 21, 2007
- Messages
- 987
- Solutions
- 14
- Reaction score
- 532
This is a spell knights can use to stun.
It's basically a Leona Q, it's damage is similar to a brutal strike, with the damage scaling off of the player's SKILL_SHIELD.
Because of the power of a stun, its duration does not increase - I have it at 3 seconds by default which halves to 1.5 on players.
spells.xml
custom/shield bash.lua
Source edits are required:
Condition
enums.h
after:
add:
luascript.cpp
after:
add:
condition.cpp
after:
add:
after:
add:
player.cpp
after:
add:
You will then need to add checks to stop monsters from moving/changing direction, and stop players from attacking when stunned:
Monsters
monster.cpp
after:
add:
after:
add:
after:
add:
after:
add:
after:
add:
after:
add:
Players
game.cpp
after:
add:
after:
add:
replace:
with: (We apply CONDITION_MUTE in the script to make use of this timer AND to stop players from casting instant spells)
player.cpp (stop being able to attack)
after:
add:
spells.cpp (stop being able to use runes)
after:
add:
It's basically a Leona Q, it's damage is similar to a brutal strike, with the damage scaling off of the player's SKILL_SHIELD.
Because of the power of a stun, its duration does not increase - I have it at 3 seconds by default which halves to 1.5 on players.
spells.xml
XML:
<instant group="attack" name="Shield Bash" words="shield bash" lvl="15" mana="80" prem="1" aggressive="1" needtarget="1" range="1" exhaustion="10000" groupcooldown="2000" script="custom/shield bash.lua">
<vocation name="..." />
</instant>
custom/shield bash.lua
Lua:
local checkWeaponSlots = {
CONST_SLOT_LEFT,
CONST_SLOT_RIGHT
}
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
combat:setParameter(COMBAT_PARAM_BLOCKARMOR, 1)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLOCKHIT)
function stunAnimation(stunnedcreature, stunnedpos, counter)
if counter ~= 0 and Creature(stunnedcreature) then
stunnedpos:sendMagicEffect(CONST_ME_STUN)
counter = counter - 1
addEvent(stunAnimation, 500, stunnedcreature, stunnedpos, counter)
end
return true
end
function onCastSpell(creature, var)
local stunDuration = 3000
local shield = 0
-- Check for shield
for i = 1,#checkWeaponSlots do -- Check what weapon is being used
if creature:getSlotItem(checkWeaponSlots[i]) ~= nil then
local weaponLiteral = creature:getSlotItem(checkWeaponSlots[i]) -- weapon object
local itemType = ItemType(weaponLiteral:getId()) -- itemtype object
local weaponType = itemType:getWeaponType()
if weaponType > 0 then
if weaponType == WEAPON_SHIELD then
shield = 1
end
end
end
end
-- No weapon
if shield == 0 then
creature:sendCancelMessage("This spell requires a shield.")
creaturePos:sendMagicEffect(CONST_ME_POFF)
return false
end
-- Check if target is Player
local stunCreature = Creature(var.number)
if stunCreature:isPlayer() then
stunDuration = stunDuration / 2 -- Halve stunDuration if Player
end
-- Stun
local stun = Condition(CONDITION_STUN)
stun:setParameter(CONDITION_PARAM_TICKS, stunDuration)
stunCreature:addCondition(stun)
-- Mute
local mute = Condition(CONDITION_MUTED)
mute:setParameter(CONDITION_PARAM_TICKS, stunDuration)
stunCreature:addCondition(mute)
-- Add animation
addEvent(stunAnimation, 0, stunCreature.uid, stunCreature:getPosition(), (stunDuration / 1000) * 2)
-- Damage formula
local skill = creature:getSkillLevel(SKILL_SHIELD)
local skillTotal = skill * (skill / 2)
local levelTotal = creature:getLevel() / 5
local min, max = -(((skillTotal * 0.02) + 4) + (levelTotal)), -(((skillTotal * 0.04) + 9) + (levelTotal))
combat:setFormula(COMBAT_FORMULA_SKILL, 0, min, 0, max)
-- Execute Damage
return combat:execute(creature, var)
end
Source edits are required:
Condition
enums.h
after:
C++:
CONDITION_SPELLGROUPCOOLDOWN = 1 << 27,
C++:
CONDITION_STUN = 1 << 28,
luascript.cpp
after:
C++:
registerEnum(CONDITION_SPELLGROUPCOOLDOWN)
C++:
registerEnum(CONDITION_STUN)
condition.cpp
after:
C++:
case CONDITION_MANASHIELD:
return new ConditionGeneric(id, type, ticks, buff, subId);
C++:
case CONDITION_STUN:
return new ConditionGeneric(id, type, ticks, buff, subId);
after:
C++:
switch (conditionType) {
case CONDITION_MANASHIELD:
icons |= ICON_MANASHIELD;
break;
C++:
case CONDITION_STUN:
icons |= ICON_DAZZLED;
break;
player.cpp
after:
C++:
case CONDITION_BLEEDING:
sendTextMessage(MESSAGE_STATUS_DEFAULT, "You are bleeding.");
break;
C++:
case CONDITION_STUN:
sendTextMessage(MESSAGE_STATUS_DEFAULT, "You have been stunned.");
break;
You will then need to add checks to stop monsters from moving/changing direction, and stop players from attacking when stunned:
Monsters
monster.cpp
after:
C++:
bool updateLook = true;
bool resetTicks = interval != 0;
attackTicks += interval;
C++:
if (hasCondition(CONDITION_STUN)) {
updateLook = false;
}
C++:
if (isHostile()) {
const Position& targetPos = target->getPosition();
uint32_t distance = std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos));
for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
if (spellBlock.range != 0 && distance <= spellBlock.range) {
return g_game.isSightClear(pos, targetPos, true);
}
}
return false;
}
C++:
if (hasCondition(CONDITION_STUN)) {
return false;
}
after:
C++:
inRange = true;
C++:
if (hasCondition(CONDITION_STUN)) {
return false;
}
after:
C++:
bool resetTicks = true;
defenseTicks += interval;
C++:
if (hasCondition(CONDITION_STUN)) {
defenseTicks = 0;
}
after:
C++:
if (isIdle || getHealth() <= 0) {
//we dont have anyone watching might aswell stop walking
eventWalk = 0;
return false;
}
C++:
if (hasCondition(CONDITION_STUN)) {
return false;
}
after:
C++:
const Position& creaturePos = getPosition();
C++:
if (hasCondition(CONDITION_STUN)) {
return false;
}
Players
game.cpp
after:
C++:
if (creature->getDirection() == dir) {
return false;
}
C++:
if (creature->hasCondition(CONDITION_STUN)) {
return false;
}
after:
C++:
creature->setLastPosition(creature->getPosition());
const Position& currentPos = creature->getPosition();
Position destPos = getNextPosition(direction, currentPos);
Player* player = creature->getPlayer();
C++:
if (creature->hasCondition(CONDITION_STUN)) {
return RETURNVALUE_NOTPOSSIBLE;
}
replace:
C++:
ss << "You are still muted for " << muteTime << " seconds.";
C++:
ss << "You are still ";
if (player->hasCondition(CONDITION_STUN)) {
ss << "stunned";
} else {
ss << "muted";
}
ss << " for " << muteTime << " seconds.";
player.cpp (stop being able to attack)
after:
C++:
if (hasCondition(CONDITION_PACIFIED)) {
return;
}
C++:
if (hasCondition(CONDITION_STUN)) {
sendCancelTarget(); // might need to add a 0 inbetween the brackets if you use older TFS build
return;
}
spells.cpp (stop being able to use runes)
after:
C++:
if (!playerSpellCheck(player)) {
return false;
}
add:
C++:
if (player->hasCondition(CONDITION_STUN)) {
return false;
}
Last edited: