enums.h
under the last attribute in itemAttrTypes (ITEM_ATTRIBUTE_DOORID = 1 << 22, if you haven't edited it, and use the number after << + 1 for reflection)
[code=cpp]ITEM_ATTRIBUTE_REFLECTION = 1 << 23,[/code]
under ORIGIN_RANGED in CombatOrigin
[code=cpp]ORIGIN_REFLECT,[/code]
item.h
in: [code=cpp]inline static bool isIntAttrType[/code]
take the hex value (default is 0x7FFE13) and use bitwise or ( | ) with (1 << 23) and replace the hex with the new value you get (you can do this at Lua: demo) with this code:
[code=lua]print(string.format("0x%x", 0x7FFE13 | (1 << 23)))[/code]
you should now get 0xFFFE13, replace the value in isIntAttrType with the new hex value we have
under int8_t getHitChance, put:
[code=cpp] int32_t getReflection() const {
if (hasAttribute(ITEM_ATTRIBUTE_REFLECTION)) {
return getIntAttr(ITEM_ATTRIBUTE_REFLECTION);
}
return items[id].reflection;
}[/code]
item.cpp
find this code:
[code=cpp] int32_t attack, defense, extraDefense;
if (item) {
attack = item->getAttack();
defense = item->getDefense();
extraDefense = item->getExtraDefense();
} else {
attack = it.attack;
defense = it.defense;
extraDefense = it.extraDefense;
}[/code]
replace it with:
[code=cpp] int32_t attack, defense, extraDefense, reflection;
if (item) {
attack = item->getAttack();
defense = item->getDefense();
extraDefense = item->getExtraDefense();
reflection = item->getReflection();
} else {
attack = it.attack;
defense = it.defense;
extraDefense = it.extraDefense;
reflection = it.reflection;
}[/code]
find this piece of code (should be around line 896)
[code=cpp] if (defense != 0 || extraDefense != 0) {
if (begin) {
begin = false;
s << " (";
} else {
s << ", ";
}
s << "Def:" << defense;
if (extraDefense != 0) {
s << ' ' << std::showpos << extraDefense << std::noshowpos;
}
}[/code]
and put this below the code above
[code=cpp] if (reflection != 0) {
if (begin) {
begin = false;
s << " (";
} else {
s << ", ";
}
s << "Reflection: " << reflection << std::noshowpos << "%";
}[/code]
items.h
under
[code=cpp]int32_t defense = 0;[/code]
put
[code=cpp]int32_t reflection = 0;[/code]
items.cpp
find:
[code=cpp] } else if (tmpStrValue == "defense") {
it.defense = pugi::cast<int32_t>(valueAttribute.value());[/code]
put this under it:
[code=cpp] } else if (tmpStrValue == "reflect") {
it.reflection = pugi::cast<int32_t>(valueAttribute.value());[/code]
player.h
under [code=cpp]int32_t getArmor() const final;[/code]
put [code=cpp]int32_t getReflection() const;[/code]
player.cpp
under: [code=cpp]int32_t Player::getArmor() const
{
int32_t armor = 0;
static const slots_t armorSlots[] = {CONST_SLOT_HEAD, CONST_SLOT_NECKLACE, CONST_SLOT_ARMOR, CONST_SLOT_LEGS, CONST_SLOT_FEET, CONST_SLOT_RING};
for (slots_t slot : armorSlots) {
Item* inventoryItem = inventory[slot];
if (inventoryItem) {
armor += inventoryItem->getArmor();
}
}
return static_cast<int32_t>(armor * vocation->armorMultiplier);
}[/code]
put: [code=cpp]int32_t Player::getReflection() const
{
int32_t reflection = 0;
static const slots_t armorSlots[] = { CONST_SLOT_HEAD, CONST_SLOT_NECKLACE, CONST_SLOT_ARMOR, CONST_SLOT_LEGS, CONST_SLOT_FEET, CONST_SLOT_RING, CONST_SLOT_LEFT, CONST_SLOT_RIGHT };
for (slots_t slot : armorSlots) {
Item* inventoryItem = inventory[slot];
if (inventoryItem) {
reflection += inventoryItem->getReflection();
}
}
return reflection;
}[/code]
game.cpp
inside of [code=cpp]bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)[/code]
under: [code=cpp]target->drainMana(attacker, manaDamage);[/code]
put: [code=cpp]
// mana reflect
if (targetPlayer && damage.origin != ORIGIN_REFLECT) {
int32_t reflection = targetPlayer->getReflection();
if (reflection != 0) {
CombatDamage reflectDamage;
reflectDamage.primary.value = static_cast<int32_t>(-damage.primary.value * (reflection / 100.0));
reflectDamage.secondary.value = static_cast<int32_t>(-damage.secondary.value * (reflection / 100.0));
reflectDamage.primary.type = damage.primary.type;
reflectDamage.secondary.type = damage.secondary.type;
reflectDamage.origin = ORIGIN_REFLECT; // create a new origin ORIGIN_REFLECT to avoid infinite reflection between 2 players
combatChangeHealth(target, attacker, reflectDamage);
}
}[/code]
under: target->drainHealth(attacker, realDamage);
put:
[code=cpp]
// reflect health
if (targetPlayer && damage.origin != ORIGIN_REFLECT) {
int32_t reflection = targetPlayer->getReflection();
if (reflection != 0) {
CombatDamage reflectDamage;
reflectDamage.primary.value = static_cast<int32_t>(-damage.primary.value * (reflection / 100.0));
reflectDamage.secondary.value = static_cast<int32_t>(-damage.secondary.value * (reflection / 100.0));
reflectDamage.primary.type = damage.primary.type;
reflectDamage.secondary.type = damage.secondary.type;
reflectDamage.origin = ORIGIN_REFLECT;
combatChangeHealth(target, attacker, reflectDamage);
}
}[/code]
the rest of the code is for scripting purposes, so this isn't 100% necessary if you aren't planning on tampering with reflection using lua
luascript.h
under: [code=cpp]static int luaItemTypeGetArmor(lua_State* L);[/code]
put: [code=cpp]static int luaItemTypeGetReflection(lua_State* L);[/code]
luascript.cpp
under: [code=cpp]registerEnum(ITEM_ATTRIBUTE_DOORID)[/code]
put: [code=cpp]registerEnum(ITEM_ATTRIBUTE_REFLECTION)[/code]
under: [code=cpp]registerEnum(ORIGIN_RANGED)[/code]
put: [code=cpp]registerEnum(ORIGIN_REFLECT)[/code]
under: [code=cpp]registerMethod("ItemType", "getArmor", LuaScriptInterface::luaItemTypeGetArmor);[/code]
put: [code=cpp]registerMethod("ItemType", "getReflection", LuaScriptInterface::luaItemTypeGetReflection);[/code]
under: [code=cpp]int LuaScriptInterface::luaItemTypeGetArmor(lua_State* L)
{
// itemType:getArmor()
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
if (itemType) {
lua_pushnumber(L, itemType->armor);
} else {
lua_pushnil(L);
}
return 1;
}[/code]
put: [code=cpp]int LuaScriptInterface::luaItemTypeGetReflection(lua_State* L)
{
// itemType:getReflection()
const ItemType* itemType = getUserdata<const ItemType>(L, -1);
if (itemType) {
lua_pushnumber(L, itemType->reflection);
} else {
lua_pushnil(L);
}
return 1;
}[/code]
now you can use ITEM_ATTRIBUTE_REFLECTION, ORIGIN_REFLECT, and itemType:getReflection() in your scripts
you can set reflection inside of items.xml with: [code=xml]<attribute key="reflect" value="10"/>[/code]
you can set reflection of items with lua using: [code=lua]item:setAttribute(ITEM_ATTRIBUTE_REFLECTION, 10)[/code]
also forgot, inside of game.cpp in bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
put
[code=cpp] if (!target) {
return false;
}[/code]
at the top of the function, otherwise it will crash when stepping on magic fields that damage you