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

fix: condition and combat immunities/suppression/damage #1405

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
26 changes: 1 addition & 25 deletions src/creatures/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ void Creature::onCreatureWalk() {

void Creature::onWalk(Direction &dir) {
if (hasCondition(CONDITION_DRUNK)) {
uint32_t r = uniform_random(0, 20);
uint32_t r = uniform_random(0, 60);
if (r <= DIRECTION_DIAGONAL_MASK) {
if (r < DIRECTION_DIAGONAL_MASK) {
dir = static_cast<Direction>(r);
Expand Down Expand Up @@ -1405,30 +1405,6 @@ bool Creature::hasCondition(ConditionType_t type, uint32_t subId /* = 0*/) const
return false;
}

bool Creature::isImmune(CombatType_t type) const {
return hasBitSet(static_cast<uint32_t>(type), getDamageImmunities());
}

bool Creature::isImmune(ConditionType_t type) const {
try {
return type == getConditionImmunities().at(type);
} catch (const std::out_of_range &exception) {
g_logger().error("[{}] invalid index {}, error code: {}", __FUNCTION__, static_cast<uint8_t>(type), exception.what());
}

return false;
}

bool Creature::isSuppress(ConditionType_t type) const {
try {
return type == getConditionSuppressions().at(type);
} catch (const std::out_of_range &exception) {
g_logger().error("[{}] invalid index {}, error code: {}", __FUNCTION__, static_cast<uint8_t>(type), exception.what());
}

return false;
}

int64_t Creature::getStepDuration(Direction dir) const {
int64_t stepDuration = getStepDuration();
if ((dir & DIRECTION_DIAGONAL_MASK) != 0) {
Expand Down
20 changes: 8 additions & 12 deletions src/creatures/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,21 +346,17 @@ class Creature : virtual public Thing {
std::vector<Condition*> getConditionsByType(ConditionType_t type) const;
void executeConditions(uint32_t interval);
bool hasCondition(ConditionType_t type, uint32_t subId = 0) const;
virtual bool isImmune(ConditionType_t type) const;
virtual bool isImmune(CombatType_t type) const;
virtual bool isSuppress(ConditionType_t type) const;
virtual uint32_t getDamageImmunities() const {
return 0;

virtual bool isImmune(CombatType_t type) const {
return false;
}
virtual const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &getConditionImmunities() const {
const static std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> array = {};
return array;
virtual bool isImmune(ConditionType_t type) const {
return false;
}
virtual bool isSuppress(ConditionType_t type) const {
return false;
};

virtual const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &getConditionSuppressions() const {
const static std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> array = {};
return array;
}
virtual bool isAttackable() const {
return true;
}
Expand Down
119 changes: 60 additions & 59 deletions src/creatures/creatures_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,47 +67,47 @@ enum ConditionAttr_t {
CONDITIONATTR_END = 254,
};

enum ConditionType_t : int8_t {
CONDITION_NONE = -1,

CONDITION_POISON = 0,
CONDITION_FIRE = 1,
CONDITION_ENERGY = 2,
CONDITION_BLEEDING = 3,
CONDITION_HASTE = 4,
CONDITION_PARALYZE = 5,
CONDITION_OUTFIT = 6,
CONDITION_INVISIBLE = 7,
CONDITION_LIGHT = 8,
CONDITION_MANASHIELD = 9,
CONDITION_INFIGHT = 10,
CONDITION_DRUNK = 11,
CONDITION_EXHAUST = 12, // unused
CONDITION_REGENERATION = 13,
CONDITION_SOUL = 14,
CONDITION_DROWN = 15,
CONDITION_MUTED = 16,
CONDITION_CHANNELMUTEDTICKS = 17,
CONDITION_YELLTICKS = 18,
CONDITION_ATTRIBUTES = 19,
CONDITION_FREEZING = 20,
CONDITION_DAZZLED = 21,
CONDITION_CURSED = 22,
CONDITION_EXHAUST_COMBAT = 23, // unused
CONDITION_EXHAUST_HEAL = 24, // unused
CONDITION_PACIFIED = 25,
CONDITION_SPELLCOOLDOWN = 26,
CONDITION_SPELLGROUPCOOLDOWN = 27,
CONDITION_ROOTED = 28,
CONDITION_FEARED = 29,
CONDITION_LESSERHEX = 30,
CONDITION_INTENSEHEX = 31,
CONDITION_GREATERHEX = 32,
CONDITION_GOSHNAR1 = 33,
CONDITION_GOSHNAR2 = 34,
CONDITION_GOSHNAR3 = 35,
CONDITION_GOSHNAR4 = 36,
CONDITION_GOSHNAR5 = 37,
enum ConditionType_t : uint8_t {
CONDITION_NONE = 0,

CONDITION_POISON = 1,
CONDITION_FIRE = 2,
CONDITION_ENERGY = 3,
CONDITION_BLEEDING = 4,
CONDITION_HASTE = 5,
CONDITION_PARALYZE = 6,
CONDITION_OUTFIT = 7,
CONDITION_INVISIBLE = 8,
CONDITION_LIGHT = 9,
CONDITION_MANASHIELD = 10,
CONDITION_INFIGHT = 11,
CONDITION_DRUNK = 12,
CONDITION_EXHAUST = 13, // unused
CONDITION_REGENERATION = 14,
CONDITION_SOUL = 15,
CONDITION_DROWN = 16,
CONDITION_MUTED = 17,
CONDITION_CHANNELMUTEDTICKS = 18,
CONDITION_YELLTICKS = 19,
CONDITION_ATTRIBUTES = 20,
CONDITION_FREEZING = 21,
CONDITION_DAZZLED = 22,
CONDITION_CURSED = 23,
CONDITION_EXHAUST_COMBAT = 24, // unused
CONDITION_EXHAUST_HEAL = 25, // unused
CONDITION_PACIFIED = 26,
CONDITION_SPELLCOOLDOWN = 27,
CONDITION_SPELLGROUPCOOLDOWN = 28,
CONDITION_ROOTED = 29,
CONDITION_FEARED = 30,
CONDITION_LESSERHEX = 31,
CONDITION_INTENSEHEX = 32,
CONDITION_GREATERHEX = 33,
CONDITION_GOSHNAR1 = 34,
CONDITION_GOSHNAR2 = 35,
CONDITION_GOSHNAR3 = 36,
CONDITION_GOSHNAR4 = 37,
CONDITION_GOSHNAR5 = 38,

// Need the last ever
CONDITION_COUNT = 39
Expand Down Expand Up @@ -768,24 +768,25 @@ enum TradeState_t : uint8_t {
TRADE_TRANSFER,
};

enum CombatType_t : uint16_t {
COMBAT_NONE = 0,

COMBAT_PHYSICALDAMAGE = 1 << 0,
COMBAT_ENERGYDAMAGE = 1 << 1,
COMBAT_EARTHDAMAGE = 1 << 2,
COMBAT_FIREDAMAGE = 1 << 3,
COMBAT_UNDEFINEDDAMAGE = 1 << 4,
COMBAT_LIFEDRAIN = 1 << 5,
COMBAT_MANADRAIN = 1 << 6,
COMBAT_HEALING = 1 << 7,
COMBAT_DROWNDAMAGE = 1 << 8,
COMBAT_ICEDAMAGE = 1 << 9,
COMBAT_HOLYDAMAGE = 1 << 10,
COMBAT_DEATHDAMAGE = 1 << 11,
COMBAT_NEUTRALDAMAGE = 1 << 12,

COMBAT_COUNT = 13
enum CombatType_t : uint8_t {
COMBAT_PHYSICALDAMAGE = 0,
COMBAT_ENERGYDAMAGE = 1,
COMBAT_EARTHDAMAGE = 2,
COMBAT_FIREDAMAGE = 3,
COMBAT_UNDEFINEDDAMAGE = 4,
COMBAT_LIFEDRAIN = 5,
COMBAT_MANADRAIN = 6,
COMBAT_HEALING = 7,
COMBAT_DROWNDAMAGE = 8,
COMBAT_ICEDAMAGE = 9,
COMBAT_HOLYDAMAGE = 10,
COMBAT_DEATHDAMAGE = 11,
COMBAT_NEUTRALDAMAGE = 12,

COMBAT_COUNT = 13,

// Server read only
COMBAT_NONE = 255
};

enum PlayerAsyncOngoingTaskFlags : uint64_t {
Expand Down
8 changes: 8 additions & 0 deletions src/creatures/monsters/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2076,6 +2076,14 @@ bool Monster::changeTargetDistance(int32_t distance, uint32_t duration /* = 1200
return true;
}

bool Monster::isImmune(ConditionType_t conditionType) const {
return mType->info.m_conditionImmunities[static_cast<size_t>(conditionType)];
}

bool Monster::isImmune(CombatType_t combatType) const {
return mType->info.m_damageImmunities[combatTypeToIndex(combatType)];
}

void Monster::getPathSearchParams(const Creature* creature, FindPathParams &fpp) const {
Creature::getPathSearchParams(creature, fpp);

Expand Down
9 changes: 3 additions & 6 deletions src/creatures/monsters/monster.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ class Monster final : public Creature {
void clearFiendishStatus();
bool canDropLoot() const;

bool isImmune(ConditionType_t conditionType) const override;
bool isImmune(CombatType_t combatType) const override;

private:
CreatureHashSet friendList;
CreatureList targetList;
Expand Down Expand Up @@ -441,12 +444,6 @@ class Monster final : public Creature {
return mType->info.lookcorpse;
}
void dropLoot(Container* corpse, Creature* lastHitCreature) override;
uint32_t getDamageImmunities() const override {
return mType->info.damageImmunities;
}
const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &getConditionImmunities() const override {
return mType->info.conditionImmunities;
}
void getPathSearchParams(const Creature* creature, FindPathParams &fpp) const override;
bool useCacheMap() const override {
return !randomStepping;
Expand Down
5 changes: 3 additions & 2 deletions src/creatures/monsters/monsters.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ class MonsterType {
uint32_t staticAttackChance = 95;
uint32_t maxSummons = 0;
uint32_t changeTargetSpeed = 0;
std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> conditionImmunities = {};
uint32_t damageImmunities = 0;

std::bitset<ConditionType_t::CONDITION_COUNT> m_conditionImmunities;
std::bitset<CombatType_t::COMBAT_COUNT> m_damageImmunities;

// Bestiary
uint8_t bestiaryOccurrence = 0;
Expand Down
13 changes: 10 additions & 3 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,18 @@ Item* Player::getInventoryItem(Slots_t slot) const {
return inventory[slot];
}

bool Player::isSuppress(ConditionType_t conditionType) const {
return m_conditionSuppressions[static_cast<size_t>(conditionType)];
}

void Player::addConditionSuppressions(const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &addConditions) {
conditionSuppressions = addConditions;
for (const auto &conditionType : addConditions) {
m_conditionSuppressions[static_cast<size_t>(conditionType)] = true;
}
}

void Player::removeConditionSuppressions() {
conditionSuppressions = {};
m_conditionSuppressions.reset();
}

Item* Player::getWeapon(Slots_t slot, bool ignoreAmmo) const {
Expand Down Expand Up @@ -4632,7 +4638,8 @@ bool Player::isImmune(ConditionType_t type) const {
if (hasFlag(PlayerFlags_t::CannotBeAttacked)) {
return true;
}
return Creature::isImmune(type);

return m_conditionImmunities[static_cast<size_t>(type)];
}

bool Player::isAttackable() const {
Expand Down
17 changes: 5 additions & 12 deletions src/creatures/players/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -2644,9 +2644,9 @@ class Player final : public Creature, public Cylinder, public Bankable {
uint32_t inventoryWeight = 0;
uint32_t capacity = 40000;
uint32_t bonusCapacity = 0;
uint32_t damageImmunities = 0;
std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> conditionImmunities = {};
std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> conditionSuppressions = {};
std::bitset<CombatType_t::COMBAT_COUNT> m_damageImmunities;
std::bitset<ConditionType_t::CONDITION_COUNT> m_conditionImmunities;
std::bitset<ConditionType_t::CONDITION_COUNT> m_conditionSuppressions;
uint32_t level = 1;
uint32_t magLevel = 0;
uint32_t actionTaskEvent = 0;
Expand Down Expand Up @@ -2816,15 +2816,8 @@ class Player final : public Creature, public Cylinder, public Bankable {
uint64_t getLostExperience() const override {
return skillLoss ? static_cast<uint64_t>(experience * getLostPercent()) : 0;
}
uint32_t getDamageImmunities() const override {
return damageImmunities;
}
const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &getConditionImmunities() const override {
return conditionImmunities;
}
const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &getConditionSuppressions() const override {
return conditionSuppressions;
}
bool isSuppress(ConditionType_t conditionType) const override;
void addConditionSuppression(const std::array<ConditionType_t, ConditionType_t::CONDITION_COUNT> &addConditions);
uint16_t getLookCorpse() const override;
void getPathSearchParams(const Creature* creature, FindPathParams &fpp) const override;

Expand Down
5 changes: 2 additions & 3 deletions src/items/functions/item/item_parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ void ItemParse::parseAbsorbPercent(const std::string &tmpStrValue, pugi::xml_att
void ItemParse::parseSupressDrunk(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType) {
std::string stringValue = tmpStrValue;
if (valueAttribute.as_bool()) {
ConditionType_t conditionType;
ConditionType_t conditionType = CONDITION_NONE;
if (stringValue == "suppressdrunk") {
conditionType = CONDITION_DRUNK;
} else if (stringValue == "suppressenergy") {
Expand All @@ -606,8 +606,7 @@ void ItemParse::parseSupressDrunk(const std::string &tmpStrValue, pugi::xml_attr
conditionType = CONDITION_CURSED;
}

// Initialize condititon with value 0
itemType.getAbilities().conditionSuppressions[conditionType] = CONDITION_NONE;
itemType.getAbilities().conditionSuppressions[conditionType] = conditionType;
}
}

Expand Down
Loading