Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Summer Update Mechanics (12.7) #9

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const
if (params.valueCallback) {
params.valueCallback->getMinMaxValues(player, damage, params.useCharges);
} else if (formulaType == COMBAT_FORMULA_LEVELMAGIC) {
int32_t levelFormula = player->getLevel() * 2 + player->getMagicLevel() * 3;
int32_t levelFormula = player->getLevel() * 2 + (player->getMagicLevel() + player->getSpecializedMagicLevel(damage.primary.type)) * 3;
damage.primary.value = normal_random(
static_cast<int32_t>(levelFormula * mina + minb),
static_cast<int32_t>(levelFormula * maxa + maxb)
Expand Down Expand Up @@ -859,7 +859,7 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage& da
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE);
// Charm low blow rune)
if (target && target->getMonster()) {
if (!damage.cleave && target && target->getMonster()) {
uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0);
if (playerCharmRaceid != 0) {
MonsterType* mType = g_monsters.getMonsterType(target->getName());
Expand Down Expand Up @@ -1057,7 +1057,7 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage& damage, bool u
case COMBAT_FORMULA_LEVELMAGIC: {
//onGetPlayerMinMaxValues(player, level, maglevel)
lua_pushnumber(L, player->getLevel());
lua_pushnumber(L, player->getMagicLevel());
lua_pushnumber(L, player->getMagicLevel() + player->getSpecializedMagicLevel(damage.primary.type));
parameters += 2;
break;
}
Expand Down
3 changes: 3 additions & 0 deletions src/creatures/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ class Creature : virtual public Thing
virtual void onCreatureMove(Creature* creature, const Tile* newTile, const Position& newPos,
const Tile* oldTile, const Position& oldPos, bool teleport);

virtual uint32_t getReflectPercent(CombatType_t combatType) const { return 0; }
virtual uint32_t getReflectFlat(CombatType_t combatType) const { return 0; }

virtual void onAttackedCreatureDisappear(bool) {}
virtual void onFollowCreatureDisappear(bool) {}

Expand Down
2 changes: 2 additions & 0 deletions src/creatures/creatures_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ struct CombatDamage {
bool critical;
int affected;
bool extension;
bool cleave;
std::string exString;

CombatDamage() {
Expand All @@ -778,6 +779,7 @@ struct CombatDamage {
critical = false;
affected = 1;
extension = false;
cleave = false;
exString = "";
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/creatures/monsters/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ bool Monster::canWalkOnFieldType(CombatType_t combatType) const
}
}

uint32_t Monster::getReflectValue(CombatType_t reflectType) const {
uint32_t Monster::getReflectPercent(CombatType_t reflectType) const {
auto it = mType->info.reflectMap.find(reflectType);
if (it != mType->info.reflectMap.end()) {
return it->second;
Expand Down
2 changes: 1 addition & 1 deletion src/creatures/monsters/monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class Monster final : public Creature
this->spawnMonster = newSpawnMonster;
}

uint32_t getReflectValue(CombatType_t combatType) const;
uint32_t getReflectPercent(CombatType_t combatType) const override;
uint32_t getHealingCombatValue(CombatType_t healingType) const;

bool canWalkOnFieldType(CombatType_t combatType) const;
Expand Down
4 changes: 2 additions & 2 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2220,7 +2220,7 @@ BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_
}
}
}
if (attacker) {
/*if (attacker) {
const int16_t& reflectPercent = it.abilities->reflectPercent[combatTypeToIndex(combatType)];
if (reflectPercent != 0) {
CombatParams params;
Expand All @@ -2234,7 +2234,7 @@ BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_

Combat::doCombatHealth(this, attacker, reflectDamage, params);
}
}
}*/
}

uint8_t slots = Item::items[item->getID()].imbuingSlots;
Expand Down
72 changes: 72 additions & 0 deletions src/creatures/players/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,70 @@ class Player final : public Creature, public Cylinder
Party* getParty() const {
return party;
}

uint32_t getReflectPercent(CombatType_t combatType) const override {
return reflectMapPercent[combatTypeToIndex(combatType)];
}
uint32_t getReflectFlat(CombatType_t combatType) const override {
return reflectMapFlat[combatTypeToIndex(combatType)];
}

void setReflectPercent(CombatType_t combatType, int32_t value) {
this->reflectMapPercent[combatTypeToIndex(combatType)] = std::max(0, this->reflectMapPercent[combatTypeToIndex(combatType)] + value);
}
void setReflectFlat(CombatType_t combatType, int32_t value) {
this->reflectMapFlat[combatTypeToIndex(combatType)] = std::max(0, this->reflectMapFlat[combatTypeToIndex(combatType)] + value);
}

uint16_t getCleavePercent() const {
return cleavePercent;
}

void setCleavePercent(uint16_t value) {
cleavePercent += value;
}

int32_t getPerfectShotDamage(uint8_t range) const {
auto it = perfectShot.find(range);
if (it != perfectShot.end())
return it->second;
return 0;
}

void setPerfectShotDamage(uint8_t range, int32_t damage) {
int32_t actualDamage = getPerfectShotDamage(range);
bool aboveZero = (actualDamage != 0);
actualDamage += damage;
if (actualDamage == 0 && aboveZero)
perfectShot.erase(range);
else
perfectShot[range] = actualDamage;
}

int32_t getSpecializedMagicLevel(CombatType_t combat) const {
return specializedMagicLevel[combatTypeToIndex(combat)];
}

void setSpecializedMagicLevel(CombatType_t combat, int32_t value) {
specializedMagicLevel[combatTypeToIndex(combat)] = std::max(0, specializedMagicLevel[combatTypeToIndex(combat)] + value);
}

int32_t getMagicShieldCapacityFlat() const {
return magicShieldCapacityFlat;
}

int16_t getMagicShieldCapacityPercent() const {
return magicShieldCapacityPercent;
}

void setMagicShieldCapacityFlat(int32_t value) {
magicShieldCapacityFlat += value;
}

void setMagicShieldCapacityPercent(int16_t value) {
magicShieldCapacityPercent += value;
}

PartyShields_t getPartyShield(const Player* player) const;
bool isInviting(const Player* player) const;
bool isPartner(const Player* player) const;
Expand Down Expand Up @@ -2108,6 +2172,14 @@ class Player final : public Creature, public Cylinder
bool marketMenu = false; // Menu option 'show in market'
bool exerciseTraining = false;

int16_t reflectPercent[COMBAT_COUNT] = { 0 };
int32_t reflectFlat[COMBAT_COUNT] = { 0 };
uint16_t cleavePercent = 0;
std::map<uint8_t, int32_t> perfectShot;
int32_t specializedMagicLevel[COMBAT_COUNT] = { 0 };
int32_t magicShieldCapacityFlat = 0;
int16_t magicShieldCapacityPercent = 0;

static uint32_t playerAutoID;

void updateItemsLight(bool internal = false);
Expand Down
45 changes: 34 additions & 11 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5447,13 +5447,14 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
CombatDamage damageReflected;

BlockType_t primaryBlockType, secondaryBlockType;
if (damage.primary.type != COMBAT_NONE) {
if (!damage.extension && damage.primary.type != COMBAT_NONE) {
// Damage reflection primary
if (attacker && target->getMonster()) {
uint32_t primaryReflect = target->getMonster()->getReflectValue(damage.primary.type);
if (primaryReflect > 0) {
if (attacker) {
uint32_t primaryReflectPercent = target->getReflectPercent(damage.primary.type);
uint32_t primaryReflectFlat = target->getReflectFlat(damage.primary.type);
if (primaryReflectPercent > 0 || primaryReflectFlat > 0) {
damageReflected.primary.value = std::ceil((damage.primary.value) * (primaryReflectPercent / 100.)) + std::min(damage.primary.value, static_cast<int32_t>(primaryReflectFlat));
damageReflected.primary.type = damage.primary.type;
damageReflected.primary.value = std::ceil((damage.primary.value) * (primaryReflect / 100.));
damageReflected.extension = true;
damageReflected.exString = "(damage reflection)";
canReflect = true;
Expand All @@ -5476,20 +5477,21 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
primaryBlockType = BLOCK_NONE;
}

if (damage.secondary.type != COMBAT_NONE) {
if (!damage.extension && damage.secondary.type != COMBAT_NONE) {
// Damage reflection secondary
if (attacker && target->getMonster()) {
uint32_t secondaryReflect = target->getMonster()->getReflectValue(damage.secondary.type);
if (secondaryReflect > 0) {
if (attacker) {
uint32_t secondaryReflectPercent = target->getReflectPercent(damage.secondary.type);
uint32_t secondaryReflectFlat = target->getReflectFlat(damage.secondary.type);
if (secondaryReflectPercent > 0 || secondaryReflectFlat > 0) {
if (!canReflect) {
damageReflected.primary.type = damage.secondary.type;
damageReflected.primary.value = std::ceil((damage.secondary.value) * (secondaryReflect / 100.));
damageReflected.primary.value = std::ceil((damage.secondary.value) * (secondaryReflectPercent / 100.)) + std::min(damage.secondary.value, static_cast<int32_t>(secondaryReflectFlat));
damageReflected.extension = true;
damageReflected.exString = "(damage reflection)";
canReflect = true;
} else {
damageReflected.secondary.type = damage.secondary.type;
damageReflected.secondary.value = std::ceil((damage.secondary.value) * (secondaryReflect / 100.));
damageReflected.secondary.value = std::ceil((damage.secondary.value) * (secondaryReflectPercent / 100.)) + std::min(damage.secondary.value, static_cast<int32_t>(secondaryReflectFlat));
}
}
}
Expand Down Expand Up @@ -5738,6 +5740,27 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage
damage.primary.value = std::abs(damage.primary.value);
damage.secondary.value = std::abs(damage.secondary.value);

bool perfectShot = false;
if (attackerPlayer && damage.extension == false && damage.origin == ORIGIN_RANGED && target == attackerPlayer->getAttackedCreature()) {
const Position& targetPos = target->getPosition();
const Position& attackerPos = attacker->getPosition();
if (targetPos.z == attackerPos.z) {
int32_t distanceX = Position::getDistanceX(targetPos, attackerPos);
int32_t distanceY = Position::getDistanceY(targetPos, attackerPos);
int32_t damageX = attackerPlayer->getPerfectShotDamage(distanceX);
int32_t damageY = attackerPlayer->getPerfectShotDamage(distanceY);
if (damageX != 0 || damageY != 0) {
int32_t totalDamage = damageX;
if (distanceX != distanceY)
totalDamage += damageY;
if (damage.critical)
totalDamage += (totalDamage * attackerPlayer->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE));
damage.primary.value += totalDamage;
perfectShot = true;
}
}
}

TextMessage message;
message.position = targetPos;

Expand Down
Loading