Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,10 @@ std::shared_ptr<KV> Player::kv() const {
return g_kv().scoped("player")->scoped(fmt::format("{}", getGUID()));
}

int32_t Player::getMarriageSpouseId() const {
return marriageSpouse;
}

bool Player::canSee(const Position &pos) {
if (!client) {
return false;
Expand Down
8 changes: 4 additions & 4 deletions src/creatures/players/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,8 @@ class Player final : public Creature, public Cylinder, public Bankable {
bool isFirstOnStack() const;
void resetOldCharms();

int32_t getMarriageSpouseId() const;

const auto &getOutfits() const {
return outfits;
}
Expand All @@ -1373,6 +1375,8 @@ class Player final : public Creature, public Cylinder, public Bankable {
return familiars;
}

uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override;

private:
friend class PlayerLock;
std::mutex mutex;
Expand Down Expand Up @@ -1427,7 +1431,6 @@ class Player final : public Creature, public Cylinder, public Bankable {
int32_t getThingIndex(const std::shared_ptr<Thing> &thing) const override;
size_t getFirstIndex() const override;
size_t getLastIndex() const override;
uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override;
void stashContainer(const StashContainerList &itemDict);
ItemsTierCountList getInventoryItemsId(bool ignoreStoreInbox = false) const;

Expand Down Expand Up @@ -1751,7 +1754,4 @@ class Player final : public Creature, public Cylinder, public Bankable {
void setMarriageSpouse(const int32_t spouseId) {
marriageSpouse = spouseId;
}
int32_t getMarriageSpouse() const {
return marriageSpouse;
}
};
7 changes: 7 additions & 0 deletions src/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ target_sources(
network/message/networkmessage.cpp
network/message/outputmessage.cpp
network/protocol/protocol.cpp
network/protocol/builders/bosstiary_message_builder.cpp
network/protocol/builders/cyclopedia_character_message_builder.cpp
network/protocol/builders/cyclopedia_house_message_builder.cpp
network/protocol/builders/imbuement_damage_encoder.cpp
network/protocol/builders/imbuement_message_builder.cpp
network/protocol/builders/outfit_message_builder.cpp
network/protocol/builders/prey_message_builder.cpp
network/protocol/protocolgame.cpp
network/protocol/protocollogin.cpp
network/protocol/protocolstatus.cpp
Expand Down
104 changes: 104 additions & 0 deletions src/server/network/protocol/builders/bosstiary_message_builder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "server/network/protocol/builders/bosstiary_message_builder.hpp"

#include "creatures/monsters/monsters.hpp"
#include "creatures/players/player.hpp"
#include "io/io_bosstiary.hpp"
#include "lib/logging/log_with_spd_log.hpp"
#include "server/network/message/outputmessage.hpp"

void BosstiaryMessageBuilder::writeMilestoneData(NetworkMessage &msg) {
msg.add<uint16_t>(25);
msg.add<uint16_t>(100);
msg.add<uint16_t>(300);

msg.add<uint16_t>(5);
msg.add<uint16_t>(20);
msg.add<uint16_t>(60);

msg.add<uint16_t>(1);
msg.add<uint16_t>(3);
msg.add<uint16_t>(5);

msg.add<uint16_t>(5);
msg.add<uint16_t>(15);
msg.add<uint16_t>(30);

msg.add<uint16_t>(10);
msg.add<uint16_t>(30);
msg.add<uint16_t>(60);

msg.add<uint16_t>(10);
msg.add<uint16_t>(30);
msg.add<uint16_t>(60);
}

void BosstiaryMessageBuilder::writeBossEntry(NetworkMessage &msg, uint32_t bossId, BosstiaryRarity_t bossRace, uint32_t killCount, bool isTracked) {
msg.add<uint32_t>(bossId);
msg.addByte(static_cast<uint8_t>(bossRace));
msg.add<uint32_t>(killCount);
msg.addByte(0);
msg.addByte(isTracked ? 0x01 : 0x00);
}

void BosstiaryMessageBuilder::writeSlot(NetworkMessage &msg, uint8_t bossRace, uint32_t bossKillCount, uint16_t lootBonus, uint8_t killBonus, uint8_t inactiveFlag, uint32_t removePrice) {
msg.addByte(bossRace);
msg.add<uint32_t>(bossKillCount);
msg.add<uint16_t>(lootBonus);
msg.addByte(killBonus);
msg.addByte(bossRace);
msg.add<uint32_t>(inactiveFlag == 1 ? 0 : removePrice);
msg.addByte(inactiveFlag);
}

void BosstiaryMessageBuilder::writeTrackedSlot(NetworkMessage &msg, const std::shared_ptr<Player> &player, uint32_t bossId, BosstiaryRarity_t bossRace, uint16_t currentBonus, uint32_t removePrice, uint32_t boostedBossId) {
if (!player) {
return;
}

const auto bossKillCount = player->getBestiaryKillCount(static_cast<uint16_t>(bossId));
const auto bossLevel = g_ioBosstiary().getBossCurrentLevel(player, static_cast<uint16_t>(bossId));
const uint16_t lootBonus = currentBonus + (bossLevel == 3 ? 25 : 0);
const uint8_t inactiveFlag = bossId == boostedBossId ? 1 : 0;
writeSlot(msg, static_cast<uint8_t>(bossRace), bossKillCount, lootBonus, 0, inactiveFlag, removePrice);
}

void BosstiaryMessageBuilder::writeBoostedSlot(NetworkMessage &msg, const std::shared_ptr<Player> &player, uint32_t bossId, BosstiaryRarity_t bossRace, uint16_t lootBonus, uint8_t bosstiaryMultiplier, uint8_t boostedKillBonus) {
if (!player) {
return;
}

const auto bossKillCount = player->getBestiaryKillCount(static_cast<uint16_t>(bossId));
const uint8_t killBonus = static_cast<uint8_t>(bosstiaryMultiplier + boostedKillBonus);
writeSlot(msg, static_cast<uint8_t>(bossRace), bossKillCount, lootBonus, killBonus, 0, 0);
}

void BosstiaryMessageBuilder::writeUnlockedList(NetworkMessage &msg, const std::vector<uint16_t> &bosses, uint32_t slotOneBossId, uint32_t slotTwoBossId) {
const auto unlockCountBuffer = msg.getBufferPosition();
uint16_t bossesCount = 0;
msg.skipBytes(2);

for (const auto bossId : bosses) {
if (bossId == slotOneBossId || bossId == slotTwoBossId) {
continue;
}

const auto mType = g_ioBosstiary().getMonsterTypeByBossRaceId(bossId);
if (!mType) {
g_logger().error("[{}] monster {} not found", __FUNCTION__, bossId);
continue;
}

auto bossRace = mType->info.bosstiaryRace;
if (bossRace < BosstiaryRarity_t::RARITY_BANE || bossRace > BosstiaryRarity_t::RARITY_NEMESIS) {
g_logger().error("[{}] monster {} have wrong boss race {}", __FUNCTION__, mType->name, static_cast<uint8_t>(bossRace));
continue;
}

msg.add<uint32_t>(bossId);
msg.addByte(static_cast<uint8_t>(bossRace));
++bossesCount;
}

msg.setBufferPosition(unlockCountBuffer);
msg.add<uint16_t>(bossesCount);
}
16 changes: 16 additions & 0 deletions src/server/network/protocol/builders/bosstiary_message_builder.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

class NetworkMessage;
class Player;

enum class BosstiaryRarity_t : uint8_t;

class BosstiaryMessageBuilder {
public:
static void writeMilestoneData(NetworkMessage &msg);
static void writeBossEntry(NetworkMessage &msg, uint32_t bossId, BosstiaryRarity_t bossRace, uint32_t killCount, bool isTracked);
static void writeSlot(NetworkMessage &msg, uint8_t bossRace, uint32_t bossKillCount, uint16_t lootBonus, uint8_t killBonus, uint8_t inactiveFlag, uint32_t removePrice);
static void writeTrackedSlot(NetworkMessage &msg, const std::shared_ptr<Player> &player, uint32_t bossId, BosstiaryRarity_t bossRace, uint16_t currentBonus, uint32_t removePrice, uint32_t boostedBossId);
static void writeBoostedSlot(NetworkMessage &msg, const std::shared_ptr<Player> &player, uint32_t bossId, BosstiaryRarity_t bossRace, uint16_t lootBonus, uint8_t bosstiaryMultiplier, uint8_t boostedKillBonus);
static void writeUnlockedList(NetworkMessage &msg, const std::vector<uint16_t> &bosses, uint32_t slotOneBossId, uint32_t slotTwoBossId);
};
Loading
Loading