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

[Feature] Item tiers and new skills (Onslaught, Ruse and Momentum) from 12.80 #366

Merged
merged 77 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
844f374
first commit
omeranha Apr 30, 2022
b10641d
Merge branch 'main' into item-tiers
omeranha May 1, 2022
6bddbdf
code rework
omeranha May 1, 2022
8265b7c
should fix linux builds
omeranha May 1, 2022
515daa4
sonar
omeranha May 1, 2022
fa5f25d
math and sonar
omeranha May 2, 2022
9251323
Merge branch 'main' into item-tiers
omeranha May 4, 2022
3c8b75c
fixes + forge system first commit (not completed yet)
omeranha May 4, 2022
45a0aa8
Merge branch 'main' into item-tiers
omeranha May 4, 2022
e94aac3
progress saving
omeranha May 8, 2022
9642874
Merge branch 'main' into item-tiers
omeranha May 17, 2022
feb8de4
sync + start fusion function
omeranha May 17, 2022
aecdaeb
Merge branch 'main' into item-tiers
omeranha May 26, 2022
a85ba28
sync changes
omeranha May 26, 2022
a0efb1a
commit set item tier talkaction
omeranha May 26, 2022
4ab2c40
Merge branch 'main' into item-tiers
omeranha May 26, 2022
fddc735
Merge branch 'main' into item-tiers
omeranha Jun 10, 2022
3f340a5
Merge branch 'main' into item-tiers
omeranha Jun 16, 2022
beb1ea9
someday will be completed in another pull request
omeranha Jun 16, 2022
906fafc
finished I think
omeranha Jun 16, 2022
fe627a0
ok
omeranha Jun 16, 2022
534dfb2
little fixes
omeranha Jun 17, 2022
02b81e0
Merge branch 'main' into item-tiers
omeranha Jul 16, 2022
acb6077
hotkey equip working but debug when having 1 tiered item and 1 normal…
omeranha Jul 16, 2022
2e330d7
fix debug, all working
omeranha Jul 16, 2022
782e695
sync
omeranha Jul 17, 2022
b375af6
Merge branch 'main' into item-tiers
omeranha Jul 17, 2022
73888df
sonar, removed unecessary function and hotkey equip 100% working
omeranha Jul 17, 2022
2f73ce5
Merge branch 'main' into item-tiers
omeranha Jul 18, 2022
b2b5f0c
Merge branch 'main' into item-tiers
omeranha Jul 19, 2022
dc14c66
Merge branch 'main' into item-tiers
omeranha Jul 22, 2022
cfe790a
sync
omeranha Jul 22, 2022
9c93982
Merge branch 'main' into item-tiers
omeranha Aug 3, 2022
052edda
fixes
omeranha Aug 3, 2022
316e6cd
Merge branch 'main' into item-tiers
omeranha Aug 11, 2022
a7cd0c1
item:getClassification function to lua
omeranha Aug 11, 2022
5819bb1
missing statistics
omeranha Aug 20, 2022
1417fc4
Merge branch 'main' into item-tiers
omeranha Sep 10, 2022
83a0fec
fixing crash with characters without mainBp and clean
omeranha Sep 10, 2022
ec32a80
sonar
omeranha Sep 10, 2022
00db00f
Merge branch 'main' into item-tiers
dudantas Sep 15, 2022
0af037d
fix market attr
omeranha Sep 16, 2022
21c6b42
Merge branch 'main' into item-tiers
dudantas Oct 6, 2022
ae11a92
Fix conflicts
dudantas Oct 6, 2022
cf21619
Fix error
dudantas Oct 6, 2022
1e26106
Some tier fixes
dudantas Oct 6, 2022
fe49b59
Fix tier order
dudantas Oct 6, 2022
f8a48b7
Fix migrations
dudantas Oct 6, 2022
6884ba5
Some fix
dudantas Oct 6, 2022
389882f
Fix uint size
dudantas Oct 6, 2022
fc69b4d
Fix tier convert to string
dudantas Oct 6, 2022
d6b1ec7
Merge branch 'main' into item-tiers
dudantas Oct 6, 2022
43cf14a
Some indent
dudantas Oct 7, 2022
d793a34
Some indent
dudantas Oct 7, 2022
837b051
Fix
dudantas Oct 8, 2022
57dd49f
Fix
dudantas Oct 13, 2022
476f5ea
Some item tier fixes
dudantas Oct 14, 2022
5b3a5c8
Small fix to tier and upgrade detail
dudantas Oct 15, 2022
ad2a7fe
Add market purchase and sale statistics for item tiers
dudantas Oct 15, 2022
e63788a
Fix statistics values and some tier changes
dudantas Oct 16, 2022
86b5b9d
Some tier fixes
dudantas Oct 16, 2022
b0368fa
Some tier fixes and sonar adjustments
dudantas Oct 16, 2022
3c529dd
fix buid linux, sonar
beats-dh Oct 17, 2022
2296eb4
Fix for not show item with imbuement and tier on npc shop
dudantas Oct 20, 2022
28d671a
Merge branch 'item-tiers' of https://github.com/opentibiabr/canary in…
dudantas Oct 20, 2022
66791e4
Fix sell offer remove item
dudantas Oct 20, 2022
f9e4662
Some sonar check fixes and others things
dudantas Oct 20, 2022
ae66772
Fix create item tier
dudantas Oct 20, 2022
f9f2234
Fix to remove only the selected items count
dudantas Oct 20, 2022
cfc49e5
Add auto instead of types
dudantas Oct 20, 2022
0159aa7
Fix possibility of clone money
dudantas Oct 20, 2022
0f94221
Simplify functions body and rename function for better explanation
dudantas Oct 20, 2022
b91d803
Fix sell items
dudantas Oct 21, 2022
d0d3482
Fix item tier ignore from requestLockerItems
dudantas Oct 22, 2022
cadb78e
Some sonar fixes
dudantas Oct 22, 2022
ec64bb5
Fix tier error on distro
dudantas Oct 26, 2022
1a9d95c
Remove comment
dudantas Oct 26, 2022
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
1 change: 1 addition & 0 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ CREATE TABLE IF NOT EXISTS `players` (
`bonus_rerolls` bigint(21) NOT NULL DEFAULT '0',
`prey_wildcard` bigint(21) NOT NULL DEFAULT '0',
`task_points` bigint(21) NOT NULL DEFAULT '0',
`forge_dusts` bigint(21) NOT NULL DEFAULT '0',
`quickloot_fallback` tinyint(1) DEFAULT '0',
`lookmountbody` tinyint(3) unsigned NOT NULL DEFAULT '0',
`lookmountfeet` tinyint(3) unsigned NOT NULL DEFAULT '0',
Expand Down
42 changes: 32 additions & 10 deletions src/creatures/combat/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,14 +838,16 @@ void Combat::CombatFunc(Creature* caster, const Position& pos, const AreaCombat*
}
//
CombatDamage tmpDamage;
if(data) {
tmpDamage.origin = data->origin;
tmpDamage.primary.type = data->primary.type;
tmpDamage.primary.value = data->primary.value;
tmpDamage.secondary.type = data->secondary.type;
tmpDamage.secondary.value = data->secondary.value;
tmpDamage.critical = data->critical;
}
if (data) {
tmpDamage.origin = data->origin;
tmpDamage.primary.type = data->primary.type;
tmpDamage.primary.value = data->primary.value;
tmpDamage.secondary.type = data->secondary.type;
tmpDamage.secondary.value = data->secondary.value;
tmpDamage.critical = data->critical;
tmpDamage.fatal = data->fatal;
}

tmpDamage.affected = affected;
for (Tile* tile : tileList) {
if (canDoCombat(caster, tile, params.aggressive) != RETURNVALUE_NOERROR) {
Expand Down Expand Up @@ -919,6 +921,16 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage& da
damage.primary.value += (damage.primary.value * caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE ))/100;
damage.secondary.value += (damage.secondary.value * caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE ))/100;
}

// fatal hit (onslaught)
if (caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT) != nullptr) {
double_t fatalChance = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT)->getFatalChance();
if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && uniform_random(1, 100) <= fatalChance) {
damage.fatal = true;
damage.primary.value += static_cast<int32_t>(std::round(damage.primary.value * 1.6));
damage.secondary.value += static_cast<int32_t>(std::round(damage.secondary.value * 1.6));
}
}
}
if (canCombat) {
if (target && caster && params.distanceEffect != CONST_ANI_NONE) {
Expand All @@ -936,12 +948,22 @@ void Combat::doCombatHealth(Creature* caster, const Position& position, const Ar
{
if(caster && caster->getPlayer()){
// Critical damage
uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE);
if (damage.primary.type != COMBAT_HEALING && chance != 0 && uniform_random(1, 100) <= chance) {
if (uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE);
damage.primary.type != COMBAT_HEALING && chance != 0 && uniform_random(1, 100) <= chance) {
damage.critical = true;
damage.primary.value += (damage.primary.value * caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE ))/100;
damage.secondary.value += (damage.secondary.value * caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE ))/100;
}

// fatal hit (onslaught)
if (caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT) != nullptr) {
double_t fatalChance = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT)->getFatalChance();
if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && uniform_random(1, 100) <= fatalChance) {
damage.fatal = true;
damage.primary.value += static_cast<int32_t>(std::round(damage.primary.value * 1.6));
damage.secondary.value += static_cast<int32_t>(std::round(damage.secondary.value * 1.6));
}
}
}
CombatFunc(caster, position, area, params, CombatHealthFunc, &damage);
}
Expand Down
5 changes: 4 additions & 1 deletion src/creatures/creatures_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ enum BlockType_t : uint8_t {
BLOCK_NONE,
BLOCK_DEFENSE,
BLOCK_ARMOR,
BLOCK_IMMUNITY
BLOCK_IMMUNITY,
BLOCK_DODGE
};

enum BestiaryType_t : uint8_t {
Expand Down Expand Up @@ -756,6 +757,7 @@ struct CombatDamage {
int affected;
bool extension;
std::string exString;
bool fatal;

CombatDamage() {
origin = ORIGIN_NONE;
Expand All @@ -765,6 +767,7 @@ struct CombatDamage {
affected = 1;
extension = false;
exString = "";
fatal = false;
}
};

Expand Down
25 changes: 25 additions & 0 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,31 @@ void Player::onThink(uint32_t interval)
addMessageBuffer();
}

// momentum(cooldown resets), checks and eligibility (chance to trigger every 2 seconds)
if (getInventoryItem(CONST_SLOT_HEAD) != nullptr) {
double_t chance = getInventoryItem(CONST_SLOT_HEAD)->getMomentumChance();
if (getZone() != ZONE_PROTECTION && hasCondition(CONDITION_INFIGHT) && ((OTSYS_TIME()/1000) % 2) == 0 && chance > 0 && uniform_random(1, 100) <= chance) {
bool triggered = false;
auto it = conditions.begin(); auto end = conditions.end();
while (it != end) {
ConditionType_t type = (*it)->getType();
uint32_t spellId = (*it)->getSubId();
int32_t ticks = (*it)->getTicks();
int32_t newTicks = (ticks <= 2000) ? 0 : ticks - 2000;
triggered = true;
if (type == CONDITION_SPELLCOOLDOWN || (type == CONDITION_SPELLGROUPCOOLDOWN && spellId > SPELLGROUP_SUPPORT)) {
(*it)->setTicks(newTicks);
type == CONDITION_SPELLGROUPCOOLDOWN ? sendSpellGroupCooldown(static_cast<SpellGroup_t>(spellId), newTicks) : sendSpellCooldown(static_cast<uint8_t>(spellId), newTicks);
}
++it;
}
if (triggered) {
g_game().addMagicEffect(getPosition(), CONST_ME_HOURGLASS);
sendTextMessage(MESSAGE_ATTENTION, "Momentum was triggered.");
}
}
}

if (!getTile()->hasFlag(TILESTATE_NOLOGOUT) && !isAccessPlayer() && !isExerciseTraining()) {
idleTime += interval;
const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES);
Expand Down
35 changes: 34 additions & 1 deletion src/creatures/players/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -1504,7 +1504,7 @@ class Player final : public Creature, public Cylinder

void sendOpenStash(bool isNpc = false) {
if (client && ((getLastDepotId() != -1) || isNpc)) {
client->sendOpenStash();
client->sendOpenStash();
}
}
bool isStashExhausted() const;
Expand Down Expand Up @@ -2033,6 +2033,36 @@ class Player final : public Creature, public Cylinder
return nullptr;
}

void sendOpenForge() const {
if (client) {
client->sendOpenForge();
}
}

void setForgeSlivers(uint64_t amount) {
forgeSlivers = amount;
}

void setForgeCores(uint64_t amount) {
forgeCores = amount;
}

void setForgeDusts(uint64_t amount) {
forgeDusts = amount;
if (client) {
client->sendResourcesBalance(getMoney(), getBankBalance(), getPreyCards(), getTaskHuntingPoints(), getForgeDusts());
}
}

uint64_t getForgeDusts() const {
return forgeDusts;
}
uint64_t getForgeSlivers() const {
return forgeSlivers;
}
uint64_t getForgeCores() const {
return forgeCores;
}

private:
std::forward_list<Condition*> getMuteConditions() const;
Expand Down Expand Up @@ -2155,6 +2185,9 @@ class Player final : public Creature, public Cylinder
uint64_t lastQuestlogUpdate = 0;
uint64_t preyCards = 0;
uint64_t taskHuntingPoints = 0;
uint64_t forgeDusts = 0;
uint64_t forgeSlivers = 0;
uint64_t forgeCores = 0;
int64_t lastFailedFollow = 0;
int64_t skullTicks = 0;
int64_t lastWalkthroughAttempt = 0;
Expand Down
21 changes: 20 additions & 1 deletion src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5540,6 +5540,8 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
addMagicEffect(targetPos, CONST_ME_POFF);
} else if (blockType == BLOCK_ARMOR) {
addMagicEffect(targetPos, CONST_ME_BLOCKHIT);
} else if (blockType == BLOCK_DODGE) {
addMagicEffect(targetPos, CONST_ME_DODGE);
} else if (blockType == BLOCK_IMMUNITY) {
uint8_t hitEffect = 0;
switch (combatType) {
Expand Down Expand Up @@ -5571,6 +5573,18 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
}
};

// dodge (ruse)
if (const Player* targetPlayer = target->getPlayer()) {
if (targetPlayer->getInventoryItem(CONST_SLOT_ARMOR) != nullptr) {
double_t chance = targetPlayer->getInventoryItem(CONST_SLOT_ARMOR)->getDodgeChance();
if (chance > 0 && uniform_random(1, 100) <= chance) {
sendBlockEffect(BLOCK_DODGE, damage.primary.type, target->getPosition());
targetPlayer->sendTextMessage(MESSAGE_ATTENTION, "You dodged an attack. (Ruse)");
return true;
}
}
}

bool canHeal = false;
CombatDamage damageHeal;
damageHeal.primary.type = COMBAT_HEALING;
Expand Down Expand Up @@ -5931,7 +5945,9 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage
SpectatorHashSet spectators;
map.getSpectators(spectators, targetPos, true, true);

if (damage.critical) {
if (damage.fatal) {
addMagicEffect(spectators, targetPos, CONST_ME_FATAL);
} else if (damage.critical) {
addMagicEffect(spectators, targetPos, CONST_ME_CRITICAL_DAMAGE);
}

Expand Down Expand Up @@ -6236,6 +6252,9 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage
if (damage.extension) {
ss << " " << damage.exString;
}
if (damage.fatal) {
ss << " (Onslaught)";
}
message.type = MESSAGE_DAMAGE_DEALT;
message.text = ss.str();
} else if (tmpPlayer == targetPlayer) {
Expand Down
2 changes: 2 additions & 0 deletions src/io/iologindata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result)

player->addPreyCards(result->getNumber<uint64_t>("prey_wildcard"));
player->addTaskHuntingPoints(result->getNumber<uint16_t>("task_points"));
player->setForgeDusts(result->getNumber<uint64_t>("forge_dusts"));

player->lastLoginSaved = result->getNumber<time_t>("lastlogin");
player->lastLogout = result->getNumber<time_t>("lastlogout");
Expand Down Expand Up @@ -878,6 +879,7 @@ bool IOLoginData::savePlayer(Player* player)

query << "`prey_wildcard` = " << player->getPreyCards() << ',';
query << "`task_points` = " << player->getTaskHuntingPoints() << ',';
query << "`forge_dusts` = " << player->getForgeDusts() << ',';

query << "`cap` = " << (player->capacity / 100) << ',';
query << "`sex` = " << static_cast<uint16_t>(player->sex) << ',';
Expand Down
29 changes: 29 additions & 0 deletions src/items/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,16 @@ Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream)
break;
}

case ATTR_TIER: {
uint8_t tier;
if (!propStream.read<uint8_t>(tier)) {
return ATTR_READ_ERROR;
}

setIntAttr(ITEM_ATTRIBUTE_TIER, tier);
break;
}

default:
return ATTR_READ_ERROR;
}
Expand Down Expand Up @@ -943,6 +953,11 @@ void Item::serializeAttr(PropWriteStream& propWriteStream) const
propWriteStream.write<uint8_t>(ATTR_IMBUEMENT_TYPE);
propWriteStream.writeString(getStrAttr(ITEM_ATTRIBUTE_IMBUEMENT_TYPE));
}

if (hasAttribute(ITEM_ATTRIBUTE_TIER)) {
propWriteStream.write<uint8_t>(ATTR_TIER);
propWriteStream.write<uint8_t>(getTier());
}
}

bool Item::hasProperty(ItemProperty prop) const
Expand Down Expand Up @@ -2286,6 +2301,20 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance,

s << parseImbuementDescription(item);

if (uint16_t classification = item->getClassification(); classification > 1) {
omeranha marked this conversation as resolved.
Show resolved Hide resolved
s << std::endl << "Classification: " << classification << " Tier: " << item->getTier();
if (item->getTier() != 0) {
s << " (";
if (it.weaponType != WEAPON_NONE) {
s << item->getFatalChance() << "% Onslaught).";
} else if (g_game().getObjectCategory(item) == OBJECTCATEGORY_HELMETS) {
s << item->getMomentumChance() << "% Momentum).";
} else if (g_game().getObjectCategory(item) == OBJECTCATEGORY_ARMORS) {
s << item->getDodgeChance() << "% Ruse).";
}
}
}

if (lookDistance <= 1) {
if (item) {
const uint32_t weight = item->getWeight();
Expand Down
41 changes: 41 additions & 0 deletions src/items/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ class ItemAttributes
checkTypes |= ITEM_ATTRIBUTE_OPENCONTAINER;
checkTypes |= ITEM_ATTRIBUTE_QUICKLOOTCONTAINER;
checkTypes |= ITEM_ATTRIBUTE_DURATION_TIMESTAMP;
checkTypes |= ITEM_ATTRIBUTE_TIER;
return (type & static_cast<ItemAttrTypes>(checkTypes)) != 0;
}
static bool isStrAttrType(ItemAttrTypes type) {
Expand Down Expand Up @@ -950,6 +951,31 @@ class Item : virtual public Thing
return items[id].isQuiver();
}

double_t calculateTierBonus(uint8_t tier, double_t x, double_t y) const {
return x * tier + y * ((tier - 1) * (tier - 1));
}

double_t getDodgeChance() const {
if (getTier() == 0) {
return 0;
}
return calculateTierBonus(getTier(), 0.5, 0.03);
}

double_t getFatalChance() const {
if (getTier() == 0) {
return 0;
}
return calculateTierBonus(getTier(), 0.5, 0.05);
}

double_t getMomentumChance() const {
if (getTier() == 0) {
return 0;
}
return calculateTierBonus(getTier(), 2, 0.05);
}

const std::string& getName() const {
if (hasAttribute(ITEM_ATTRIBUTE_NAME)) {
return getStrAttr(ITEM_ATTRIBUTE_NAME);
Expand Down Expand Up @@ -1096,6 +1122,21 @@ class Item : virtual public Thing
return false;
}

uint16_t getTier() const {
if (hasAttribute(ITEM_ATTRIBUTE_TIER)) {
return getIntAttr(ITEM_ATTRIBUTE_TIER);
}
return 0;
}
void setTier(uint8_t tier) {
if (items[id].upgradeClassification) {
setIntAttr(ITEM_ATTRIBUTE_TIER, tier);
omeranha marked this conversation as resolved.
Show resolved Hide resolved
}
}
uint16_t getClassification() const {
return items[id].upgradeClassification;
}

protected:
std::string getWeightDescription(uint32_t weight) const;

Expand Down
5 changes: 4 additions & 1 deletion src/items/items_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ enum AttrTypes_t {
ATTR_OPENCONTAINER = 36,
ATTR_CUSTOM_ATTRIBUTES = 37,
ATTR_QUICKLOOTCONTAINER = 38,
ATTR_IMBUEMENT_TYPE = 39
ATTR_IMBUEMENT_TYPE = 39,
ATTR_TIER = 40
omeranha marked this conversation as resolved.
Show resolved Hide resolved
};

enum ImbuementTypes_t : int64_t {
Expand Down Expand Up @@ -316,6 +317,8 @@ enum ItemAttrTypes : uint32_t {
ITEM_ATTRIBUTE_QUICKLOOTCONTAINER = 1 << 26,
ITEM_ATTRIBUTE_DURATION_TIMESTAMP = 1 << 27,
ITEM_ATTRIBUTE_IMBUEMENT_TYPE = 1 << 28,
ITEM_ATTRIBUTE_TIER = 1 << 29,

ITEM_ATTRIBUTE_CUSTOM = 1U << 31
};

Expand Down
Loading