zakius
Enter the Ninja!
Vampiric weapons 0.3
Well, cause I and probably more people wanted to have lifestealing weapons, here it comes: code allowing you to make it easy!
in items.h find
and go to first ; after that, add
before it.
in items.cpp under
add
and under
add
in item.h under
add
and under
add
in weapons.cpp under
change combat::doCombatHealth line to
in combat.cpp change all
function to
and next function to
and whole
to
under
add
in combat.h under
add
change
to
,
to
to
now rebuild all and you can just put in items.xml attribute lifestealpercent to regen health or manastealpercent to regen mana ammount based on hit.
Also you can add/change this attribute in lua just like attack or armor
hmm, I dont have any inteligent idea how to describe it in text shown onLook, but if you have any nice idea I'll add info how to do it
(guys who have prev version: in weapons.cpp delete
)
updated again, now supports lifesteal attribute in any eq part
Well, cause I and probably more people wanted to have lifestealing weapons, here it comes: code allowing you to make it easy!
in items.h find
Code:
int32_t attack, extraAttack,
Code:
, lifestealpercent, manastealpercent
in items.cpp under
Code:
armor = 0;
Code:
lifestealpercent = manastealpercent = 0;
Code:
else if(tmpStrValue == "attack")//rand
{
if(readXMLInteger(itemAttributesNode, "value", intValue))
it.attack = intValue;
}
Code:
else if(tmpStrValue == "lifestealpercent")//rand
{
if(readXMLInteger(itemAttributesNode, "value", intValue))
it.lifestealpercent = intValue;
}
else if(tmpStrValue == "manastealpercent")//rand
{
if(readXMLInteger(itemAttributesNode, "value", intValue))
it.manastealpercent = intValue;
}
in item.h under
Code:
int32_t getAttack() const;
Code:
int32_t getLifestealPercent() const;
int32_t getManastealPercent() const;
Code:
inline int32_t Item::getAttack() const
{
const int32_t* v = getIntegerAttribute("attack");
if(v)
return *v;
return items[id].attack;
}
Code:
inline int32_t Item::getLifestealPercent() const
{
const int32_t* v = getIntegerAttribute("lifestealpercent");
if(v)
return *v;
return items[id].lifestealpercent;
}
inline int32_t Item::getManastealPercent() const
{
const int32_t* v = getIntegerAttribute("manastealpercent");
if(v)
return *v;
return items[id].manastealpercent;
}
Code:
bool Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int32_t damageModifier) const
{
if(isScripted())
{
LuaVariant var;
var.type = VARIANT_NUMBER;
var.number = target->getID();
executeUseWeapon(player, var);
}
else
{
int32_t damage = (getWeaponDamage(player, target, item) * damageModifier) / 100;
Code:
int32_t lifestealpercent=0;
int32_t manastealpercent=0;
Item* item = NULL;
for(int32_t slot = SLOT_FIRST; slot < SLOT_LAST; ++slot)
{
if(! player->getInventoryItem((slots_t)slot) || slot == 10) continue;
item = player->getInventoryItem((slots_t)slot);
const ItemType& it = Item::items[item->getID()];
if (((slot == 5 || slot == 6) && (it.weaponType!=WEAPON_SWORD && it.weaponType!=WEAPON_CLUB &&
it.weaponType!=WEAPON_AXE && it.weaponType!=WEAPON_DIST && it.weaponType!=WEAPON_SHIELD && it.weaponType!=WEAPON_FIST))) continue;
lifestealpercent+=item->getLifestealPercent();
manastealpercent+=item->getManastealPercent();
}
Combat::doCombatHealth(player, target, damage, damage, params, lifestealpercent, manastealpercent);
Code:
void Combat::doCombatHealth(Creature* caster, Creature* target, int32_t minChange, int32_t maxChange, const CombatParams& params)
Code:
void Combat::doCombatHealth(Creature* caster, Creature* target, int32_t minChange, int32_t maxChange, const CombatParams& params, int lifestealpercent, int manastealpercent)
{
if(params.isAggressive && (caster == target || Combat::canDoCombat(caster, target) != RET_NOERROR))
return;
Combat2Var var;
var.minChange = minChange;
var.maxChange = maxChange;
CombatHealthFunc(caster, target, params, (void*)&var, lifestealpercent, manastealpercent);
if(params.targetCallback)
params.targetCallback->onTargetCombat(caster, target);
if(params.effects.impact != MAGIC_EFFECT_NONE && (!caster || !caster->isGhost()
|| g_config.getBool(ConfigManager::GHOST_SPELL_EFFECTS)))
g_game.addMagicEffect(target->getPosition(), params.effects.impact);
if(caster && params.effects.distance != SHOOT_EFFECT_NONE)
addDistanceEffect(caster, caster->getPosition(), target->getPosition(), params.effects.distance);
}
Code:
void Combat::doCombatHealth(Creature* caster, const Position& pos, const CombatArea* area,
int32_t minChange, int32_t maxChange, const CombatParams& params, int lifestealpercent, int manastealpercent)
{
Combat2Var var;
var.minChange = minChange;
var.maxChange = maxChange;
bool lol=CombatHealthFunc;
CombatFunc(caster, pos, area, params, lol, (void*)&var);
}
Code:
bool Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatParams& params, void* data
Code:
bool Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatParams& params, void* data, int lifestealpercent, int manastealpercent)
{
int32_t change = 0;
if(Combat2Var* var = (Combat2Var*)data)
{
change = var->change;
if(!change)
change = random_range(var->minChange, var->maxChange, DISTRO_NORMAL);
}
if(g_game.combatBlockHit(params.combatType, caster, target, change, params.blockedByShield, params.blockedByArmor))
return false;
if(change < 0 && caster && caster->getPlayer() && target->getPlayer() && target->getPlayer()->getSkull() != SKULL_BLACK)
change = change / 2;
if(!g_game.combatChangeHealth(params.combatType, caster, target, change, params.effects.hit, params.effects.color))
return false;
int32_t lifestolen = int32_t(change * lifestealpercent / 100);
CombatParams lifesteal;
lifesteal.combatType=COMBAT_HEALING;
lifesteal.isAggressive=false;
if(lifestolen<0)
Combat::doCombatHealth(caster, caster, -lifestolen, -lifestolen, lifesteal);
int32_t manastolen = int32_t(change * manastealpercent / 100);
CombatParams manasteal;
manasteal.combatType=COMBAT_MANADRAIN;
manasteal.isAggressive=false;
if(manastolen>0)
Combat::doCombatMana(caster, caster, -manastolen, -manastolen, manasteal);
CombatConditionFunc(caster, target, params, NULL);
CombatDispelFunc(caster, target, params, NULL);
return true;
}
Code:
void Combat::CombatFunc(Creature* caster, const Position& pos, const CombatArea* area,
const CombatParams& params, COMBATFUNC func, void* data)
{
std::list<Tile*> tileList;
if(caster)
getCombatArea(caster->getPosition(), pos, area, tileList);
else
getCombatArea(pos, pos, area, tileList);
Combat2Var* var = (Combat2Var*)data;
if(var && !params.differentAreaDamage)
var->change = random_range(var->minChange, var->maxChange, DISTRO_NORMAL);
uint32_t maxX = 0, maxY = 0, diff;
//calculate the max viewable range
for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
{
diff = std::abs((*it)->getPosition().x - pos.x);
if(diff > maxX)
maxX = diff;
diff = std::abs((*it)->getPosition().y - pos.y);
if(diff > maxY)
maxY = diff;
}
SpectatorVec list;
g_game.getSpectators(list, pos, false, true, maxX + Map::maxViewportX, maxX + Map::maxViewportX,
maxY + Map::maxViewportY, maxY + Map::maxViewportY);
Tile* tile = NULL;
for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
{
if(!(tile = (*it)) || canDoCombat(caster, (*it), params.isAggressive) != RET_NOERROR)
continue;
bool skip = true;
if(CreatureVector* creatures = tile->getCreatures())
{
for(CreatureVector::iterator cit = creatures->begin(), cend = creatures->end(); skip && cit != cend; ++cit)
{
if(params.targetPlayersOrSummons && !(*cit)->getPlayer() && !(*cit)->isPlayerSummon())
continue;
if(params.targetCasterOrTopMost)
{
if(caster && caster->getTile() == tile)
{
if((*cit) == caster)
skip = false;
}
else if((*cit) == tile->getTopCreature())
skip = false;
if(skip)
continue;
}
if(!params.isAggressive || (caster != (*cit) && Combat::canDoCombat(caster, (*cit)) == RET_NOERROR))
{
func(caster, (*cit), params, (void*)var);
if(params.targetCallback)
params.targetCallback->onTargetCombat(caster, (*cit));
}
}
}
combatTileEffects(list, caster, tile, params);
}
postCombatEffects(caster, pos, params);
}
Code:
void Combat::CombatFunc(Creature* caster, const Position& pos, const CombatArea* area,
const CombatParams& params, bool hmm, void* data)
{
std::list<Tile*> tileList;
if(caster)
getCombatArea(caster->getPosition(), pos, area, tileList);
else
getCombatArea(pos, pos, area, tileList);
Combat2Var* var = (Combat2Var*)data;
if(var && !params.differentAreaDamage)
var->change = random_range(var->minChange, var->maxChange, DISTRO_NORMAL);
uint32_t maxX = 0, maxY = 0, diff;
//calculate the max viewable range
for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
{
diff = std::abs((*it)->getPosition().x - pos.x);
if(diff > maxX)
maxX = diff;
diff = std::abs((*it)->getPosition().y - pos.y);
if(diff > maxY)
maxY = diff;
}
SpectatorVec list;
g_game.getSpectators(list, pos, false, true, maxX + Map::maxViewportX, maxX + Map::maxViewportX,
maxY + Map::maxViewportY, maxY + Map::maxViewportY);
Tile* tile = NULL;
for(std::list<Tile*>::iterator it = tileList.begin(); it != tileList.end(); ++it)
{
if(!(tile = (*it)) || canDoCombat(caster, (*it), params.isAggressive) != RET_NOERROR)
continue;
bool skip = true;
if(CreatureVector* creatures = tile->getCreatures())
{
for(CreatureVector::iterator cit = creatures->begin(), cend = creatures->end(); skip && cit != cend; ++cit)
{
if(params.targetPlayersOrSummons && !(*cit)->getPlayer() && !(*cit)->isPlayerSummon())
continue;
if(params.targetCasterOrTopMost)
{
if(caster && caster->getTile() == tile)
{
if((*cit) == caster)
skip = false;
}
else if((*cit) == tile->getTopCreature())
skip = false;
if(skip)
continue;
}
if(!params.isAggressive || (caster != (*cit) && Combat::canDoCombat(caster, (*cit)) == RET_NOERROR))
{
CombatHealthFunc(caster, (*cit), params, (void*)var);
if(params.targetCallback)
params.targetCallback->onTargetCombat(caster, (*cit));
}
}
}
combatTileEffects(list, caster, tile, params);
}
postCombatEffects(caster, pos, params);
}
Code:
static void CombatFunc(Creature* caster, const Position& pos,
const CombatArea* area, const CombatParams& params, COMBATFUNC func, void* data);
Code:
static void CombatFunc(Creature* caster, const Position& pos, const CombatArea* area, const CombatParams& params, bool, void* data);
Code:
static bool CombatHealthFunc(Creature* caster, Creature* target, const CombatParams& params, void* data);
Code:
static bool CombatHealthFunc(Creature* caster, Creature* target, const CombatParams& params, void* data, int lifestealpercent=0, int manastealpercent=0);
Code:
static void doCombatHealth(Creature* caster, Creature* target,
int32_t minChange, int32_t maxChange, const CombatParams& params);
Code:
static void doCombatHealth(Creature* caster, Creature* target,
int32_t minChange, int32_t maxChange, const CombatParams& params, int lifestealpercent=0, int manastealpercent=0);
Code:
static void doCombatHealth(Creature* caster, const Position& pos,
const CombatArea* area, int32_t minChange, int32_t maxChange, const CombatParams& params);
Code:
static void doCombatHealth(Creature* caster, const Position& pos,
const CombatArea* area, int32_t minChange, int32_t maxChange, const CombatParams& params, int lifestealpercent=0, int manastealpercent=0);
Also you can add/change this attribute in lua just like attack or armor
hmm, I dont have any inteligent idea how to describe it in text shown onLook, but if you have any nice idea I'll add info how to do it
(guys who have prev version: in weapons.cpp delete
Code:
if(item->getLifestealPercent())
{
int32_t lifestolen = int32_t(damage * item->getLifestealPercent() / 100);
CombatParams lifesteal;
lifesteal.combatType=COMBAT_HEALING;
lifesteal.isAggressive=false;
Combat::doCombatHealth(player, player, -lifestolen, -lifestolen, lifesteal);
}
if(item->getManastealPercent())
{
int32_t manastolen = int32_t(damage * item->getManastealPercent() / 100);
CombatParams manasteal;
manasteal.combatType=COMBAT_MANADRAIN;
manasteal.isAggressive=false;
Combat::doCombatMana(player, player, -manastolen, -manastolen, manasteal);
}
Last edited: