diarmaint
New Member
- Joined
- Oct 6, 2012
- Messages
- 26
- Reaction score
- 0
Defense system of magical ability, like dbko
I really need this system, everyone I tried did not work, someone help me?
dbko 8.0
my test doesn't work
no error, but it doesn't work
I really need this system, everyone I tried did not work, someone help me?
dbko 8.0
Lua:
bool Game::combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange)
{
const Position& targetPos = target->getPosition();
uint64_t uptime = 0;
Status* status = Status::instance();
if(status){
uptime = status->getUptime();
}
if(uptime < 60){
return false;
}
if(healthChange > 0){
if(target->getHealth() <= 0){
return false;
}
target->changeHealth(healthChange);
}
else{
SpectatorVec list;
getSpectators(list, targetPos, true);
if(!target->isAttackable() || Combat::canDoCombat(attacker, target) != RET_NOERROR){
addMagicEffect(list, targetPos, NM_ME_PUFF);
return true;
}
int32_t damage = -healthChange;
if(damage != 0){
if(combatType != COMBAT_UNDEFINEDDAMAGE && attacker->getMonster() && target->getMonster()){
return false;
}
if(target->getPlayer()){
if(target->getPlayer() && combatType != COMBAT_PHYSICALDAMAGE){
if(combatType != COMBAT_UNDEFINEDDAMAGE || combatType != COMBAT_NONE){
target->getPlayer()->addSkillAdvance(SKILL_FISH, 1);
}
}
if(target->getPlayer() && combatType != COMBAT_PHYSICALDAMAGE){
if(random_range(1, 100) <= 10 + (target->getPlayer()->getSkill(SKILL_FISH, SKILL_LEVEL) / 5)){
if(combatType != COMBAT_UNDEFINEDDAMAGE || combatType != COMBAT_NONE){
target->getPlayer()->sendMiss();
return false;
}
}
}
}
if(target->hasCondition(CONDITION_MANASHIELD)){
int32_t manaDamage = std::min(target->getMana(), damage);
damage = std::max((int32_t)0, damage - manaDamage);
if(manaDamage != 0){
target->drainMana(attacker, manaDamage);
std::stringstream ss;
ss << manaDamage;
addMagicEffect(list, targetPos, NM_ME_LOSE_ENERGY);
addAnimatedText(list, targetPos, TEXTCOLOR_BLUE, ss.str());
}
}
Player* targetPlayer = target->getPlayer();
if(targetPlayer)
{
if(damage >= targetPlayer->getHealth())
{
//scripting event - onPrepareDeath
CreatureEvent* eventPrepareDeath = targetPlayer->getCreatureEvent(CREATURE_EVENT_PREPAREDEATH);
if(eventPrepareDeath)
eventPrepareDeath->executeOnPrepareDeath(targetPlayer, attacker);
}
}
damage = std::min(target->getHealth(), damage);
if(damage > 0){
target->drainHealth(attacker, combatType, damage);
addCreatureHealth(list, target);
TextColor_t textColor = TEXTCOLOR_NONE;
uint8_t hitEffect = 0;
switch(combatType){
case COMBAT_PHYSICALDAMAGE:
{
Item* splash = NULL;
switch(target->getRace()){
case RACE_VENOM:
textColor = TEXTCOLOR_LIGHTGREEN;
hitEffect = NM_ME_BLOCKHIT;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
break;
case RACE_BLOOD:
textColor = TEXTCOLOR_RED;
hitEffect = NM_ME_DRAW_BLOOD;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
break;
case RACE_UNDEAD:
textColor = TEXTCOLOR_LIGHTGREY;
hitEffect = NM_ME_HIT_AREA;
break;
case RACE_FIRE:
textColor = TEXTCOLOR_ORANGE;
hitEffect = NM_ME_DRAW_BLOOD;
break;
default:
break;
}
if(splash){
internalAddItem(target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
startDecay(splash);
}
break;
}
case COMBAT_ENERGYDAMAGE:
{
textColor = TEXTCOLOR_LIGHTBLUE;
hitEffect = NM_ME_ENERGY_DAMAGE;
break;
}
case COMBAT_POISONDAMAGE:
{
textColor = TEXTCOLOR_LIGHTGREEN;
hitEffect = NM_ME_BLOCKHIT;
break;
}
case COMBAT_DROWNDAMAGE:
{
textColor = TEXTCOLOR_LIGHTBLUE;
hitEffect = NM_ME_LOSE_ENERGY;
break;
}
case COMBAT_FIREDAMAGE:
{
textColor = TEXTCOLOR_ORANGE;
hitEffect = NM_ME_HITBY_FIRE;
break;
}
case COMBAT_LIFEDRAIN:
{
textColor = TEXTCOLOR_RED;
hitEffect = NM_ME_MAGIC_BLOOD;
break;
}
default:
break;
}
if(textColor != TEXTCOLOR_NONE){
std::stringstream ss;
ss << damage;
addMagicEffect(list, targetPos, hitEffect);
addAnimatedText(list, targetPos, textColor, ss.str());
}
}
}
}
return true;
}
my test doesn't work
Lua:
bool Game::combatChangeHealth(const CombatParams& params, Creature* attacker, Creature* target, int32_t healthChange, bool force)
{
const Position& targetPos = target->getPosition();
int32_t lifeLeech, manaLeech, lifeAbsorb, manaAbsorb = 0;
if (healthChange > 0)
{
if (!force && target->getHealth() <= 0)
return false;
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for (CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if (!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHGAIN, params.combatType, healthChange))
deny = true;
}
if (deny)
return false;
int32_t oldHealth = target->getHealth();
target->gainHealth(attacker, healthChange);
if (oldHealth != target->getHealth() && g_config.getBool(ConfigManager::SHOW_HEALTH_CHANGE) && !target->isGhost() &&
(g_config.getBool(ConfigManager::SHOW_HEALTH_CHANGE_MONSTER) || !target->getMonster()))
{
const SpectatorVec& list = getSpectators(targetPos);
if (params.combatType != COMBAT_HEALING)
addMagicEffect(list, targetPos, MAGIC_EFFECT_WRAPS_BLUE);
SpectatorVec textList;
for (SpectatorVec::const_iterator it = list.begin(); it != list.end(); ++it)
{
if (!(*it)->getPlayer())
continue;
if ((*it) != attacker && (*it) != target && (*it)->getPosition().z == target->getPosition().z)
textList.push_back(*it);
}
healthChange = (target->getHealth() - oldHealth);
std::string plural = (healthChange != 1 ? "s." : ".");
std::stringstream ss;
char buffer[20];
sprintf(buffer, "+%d", healthChange);
addAnimatedText(list, targetPos, COLOR_MAYABLUE, buffer);
if (!textList.empty())
{
if (!attacker)
ss << ucfirst(target->getNameDescription()) << " is healed for " << healthChange << " hitpoint" << plural;
else if (attacker != target)
ss << ucfirst(attacker->getNameDescription()) << " heals " << target->getNameDescription() << " for " << healthChange << " hitpoint" << plural;
else
{
ss << ucfirst(attacker->getNameDescription()) << " heals ";
if (Player* attackerPlayer = attacker->getPlayer())
ss << (attackerPlayer->getSex(false) == PLAYERSEX_FEMALE ? "herself" : "himself") << " for " << healthChange << " hitpoint" << plural;
else
ss << "itself for " << healthChange << " hitpoint" << plural;
}
addStatsMessage(textList, MSG_HEALED_OTHERS, ss.str(), targetPos);
ss.str("");
}
Player* player = NULL;
if (attacker && (player = attacker->getPlayer()))
{
if (attacker != target)
ss << "You healed " << target->getNameDescription() << " for " << healthChange << " hitpoint" << plural;
else
ss << "You healed yourself for " << healthChange << " hitpoint" << plural;
player->sendStatsMessage(MSG_HEALED, ss.str(), targetPos);
ss.str("");
}
if ((player = target->getPlayer()) && attacker != target)
{
if (attacker)
ss << ucfirst(attacker->getNameDescription()) << " heals you for " << healthChange << " hitpoint" << plural;
else
ss << "You are healed for " << healthChange << " hitpoint" << plural;
player->sendStatsMessage(MSG_HEALED, ss.str(), targetPos);
}
}
}
else
{
const SpectatorVec& list = getSpectators(targetPos);
if (target->getHealth() < 1 || Combat::canDoCombat(attacker, target, true) != RET_NOERROR)
{
addMagicEffect(list, targetPos, MAGIC_EFFECT_POFF);
return true;
}
int32_t elementDamage = 0;
if (params.element.damage && params.element.type != COMBAT_NONE)
elementDamage = -params.element.damage;
int32_t damage = -healthChange;
if (damage > 0)
{
if (!params.combatType == COMBAT_ENERGYDAMAGE && target && target->getPlayer())
{
double damageChange = 0;
int32_t skillFish = target->getPlayer()->getSkill(SKILL_FISH, SKILL_LEVEL);
if (skillFish >= 10)
damageChange = std::ceil(skillFish * 0.1 * damage / 100);
if ((int32_t)damageChange != 0)
{
damage -= (int32_t)damageChange;
char buffer[150];
sprintf(buffer, "%d hitpoint%s has been absorbed by your resistance.", (int32_t)damageChange, ((int32_t)damageChange == 1 ? "" : "s"));
target->getPlayer()->addSkillAdvance(SKILL_FISH, 1, true);
target->getPlayer()->sendTextMessage(MSG_EVENT_DEFAULT, buffer);
}
}
if (target->hasCondition(CONDITION_MANASHIELD) && params.combatType != COMBAT_UNDEFINEDDAMAGE)
{
int32_t manaDamage = std::min(target->getMana(), damage + elementDamage);
damage = std::max((int32_t)0, damage + elementDamage - manaDamage);
elementDamage = 0; // TODO: I don't know how it works ;(
if (manaDamage && combatChangeMana(attacker, target, -manaDamage, params.combatType, true))
addMagicEffect(list, targetPos, MAGIC_EFFECT_LOSE_ENERGY);
}
damage = std::min(target->getHealth(), damage);
if (damage > 0)
{
Player* player = NULL;
if (attacker && (player = attacker->getPlayer()))
{
if (random_range(1, 100) < attacker->getPlayer()->getCriticalHitChance())
{
damage = damage * 2;
//addAnimatedText(attacker->getPosition(), COLOR_LIGHTGREEN, "Critical!");
addMagicEffect(attacker->getPosition(), MAGIC_EFFECT_EXPLOSION_AREA);
}
}
if ((player = target->getPlayer()) && (attacker != target) && target == player)
{
if (random_range(1, 100) < target->getPlayer()->getDodgeChance())
{
damage = damage * 0.5;
addAnimatedText(target->getPosition(), COLOR_WHITE, "Dodge!");
addMagicEffect(attacker->getPosition(), MAGIC_EFFECT_BLOCKHIT);
}
}
bool deny = false;
CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
for (CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
{
if (!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHLOSS, params.combatType, damage))
deny = true;
}
if (deny)
return false;
target->drainHealth(attacker, params.combatType, damage);
if (elementDamage)
target->drainHealth(attacker, params.element.type, elementDamage);
Color_t textColor = COLOR_NONE;
MagicEffect_t magicEffect = MAGIC_EFFECT_NONE;
addCreatureHealth(list, target);
if (params.combatType == COMBAT_PHYSICALDAMAGE)
{
Item* splash = NULL;
switch (target->getRace())
{
case RACE_VENOM:
textColor = COLOR_LIGHTGREEN;
magicEffect = MAGIC_EFFECT_POISON;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
break;
case RACE_BLOOD:
textColor = COLOR_RED;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
break;
case RACE_UNDEAD:
textColor = COLOR_GREY;
magicEffect = MAGIC_EFFECT_HIT_AREA;
break;
case RACE_FIRE:
textColor = COLOR_ORANGE;
magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
break;
case RACE_ENERGY:
textColor = COLOR_PURPLE;
magicEffect = MAGIC_EFFECT_PURPLEENERGY;
break;
default:
break;
}
if (splash)
{
internalAddItem(NULL, target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
startDecay(splash);
}
}
else
getCombatDetails(params.combatType, magicEffect, textColor);
if (params.effects.hit != MAGIC_EFFECT_UNKNOWN)
magicEffect = params.effects.hit;
if (params.effects.color != COLOR_UNKNOWN)
textColor = params.effects.color;
if (textColor < COLOR_NONE && magicEffect < MAGIC_EFFECT_NONE)
{
addMagicEffect(list, targetPos, magicEffect);
SpectatorVec textList;
for (SpectatorVec::const_iterator it = list.begin(); it != list.end(); ++it)
{
if (!(*it)->getPlayer())
continue;
if ((*it) != attacker && (*it) != target && (*it)->getPosition().z == target->getPosition().z)
textList.push_back(*it);
}
if (elementDamage)
{
getCombatDetails(params.element.type, magicEffect, textColor);
addMagicEffect(list, targetPos, magicEffect);
}
std::stringstream ss;
char buffer[20];
sprintf(buffer, "-%d", damage);
addAnimatedText(list, targetPos, textColor, buffer);
int32_t totalDamage = damage + elementDamage;
std::string plural = (totalDamage != 1 ? "s" : "");
if (!textList.empty())
{
if (!attacker)
ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << ".";
else if (attacker != target)
ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to an attack by " << attacker->getNameDescription() << ".";
else
ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to a self attack.";
addStatsMessage(textList, MSG_DAMAGE_OTHERS, ss.str(), targetPos);
ss.str("");
}
Player* player = NULL;
if (attacker && (player = attacker->getPlayer()))
{
if (attacker != target)
ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to your attack.";
else
ss << "You lose " << totalDamage << " hitpoint" << plural << " due to your attack.";
player->sendStatsMessage(MSG_DAMAGE_DEALT, ss.str(), targetPos);
ss.str("");
}
if ((player = target->getPlayer()) && attacker != target)
{
if (attacker)
ss << "You lose " << totalDamage << " hitpoint" << plural << " due to an attack by " << attacker->getNameDescription() << ".";
else
ss << "You lose " << totalDamage << " hitpoint" << plural << ".";
player->sendStatsMessage(MSG_DAMAGE_RECEIVED, ss.str(), targetPos);
}
if (attacker && (player = attacker->getPlayer()))
{
if (attacker->getPlayer()->getLifeLeech() > 0)
{
lifeLeech = damage * (attacker->getPlayer()->getLifeLeech() * 0.01);
if (damage > 0)
{
combatChangeHealth(params, target, attacker, lifeLeech, true);
}
}
if (attacker->getPlayer()->getManaLeech() > 0)
{
manaLeech = damage * (attacker->getPlayer()->getManaLeech() * 0.01);
if (damage > 0)
{
combatChangeMana(target, attacker, manaLeech, params.combatType, true);
}
}
}