1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-24 12:53:52 +00:00
openmw-tes3mp/apps/openmw-mp/Script/Functions/Stats.cpp
David Cernat 2f98f31af2 [General] Use model variable already included in PlayerBaseInfo packets
The variable has been included since TES3MP's earliest proof of concept, but never used for anything. It is now possible to get and set it, due to semi-popular demand.
2021-09-02 15:44:11 +02:00

661 lines
16 KiB
C++

#include "Stats.hpp"
#include <iostream>
#include <components/esm/attr.hpp>
#include <components/esm/loadskil.hpp>
#include <components/misc/stringops.hpp>
#include <components/openmw-mp/TimedLog.hpp>
#include <components/openmw-mp/NetworkMessages.hpp>
#include <apps/openmw-mp/Networking.hpp>
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
int StatsFunctions::GetAttributeCount() noexcept
{
return ESM::Attribute::Length;
}
int StatsFunctions::GetSkillCount() noexcept
{
return ESM::Skill::Length;
}
int StatsFunctions::GetAttributeId(const char *name) noexcept
{
for (int x = 0; x < ESM::Attribute::Length; x++)
{
if (Misc::StringUtils::ciEqual(name, ESM::Attribute::sAttributeNames[x]))
{
return x;
}
}
return -1;
}
int StatsFunctions::GetSkillId(const char *name) noexcept
{
for (int x = 0; x < ESM::Skill::Length; x++)
{
if (Misc::StringUtils::ciEqual(name, ESM::Skill::sSkillNames[x]))
{
return x;
}
}
return -1;
}
const char *StatsFunctions::GetAttributeName(unsigned short attributeId) noexcept
{
if (attributeId >= ESM::Attribute::Length)
return "invalid";
return ESM::Attribute::sAttributeNames[attributeId].c_str();
}
const char *StatsFunctions::GetSkillName(unsigned short skillId) noexcept
{
if (skillId >= ESM::Skill::Length)
return "invalid";
return ESM::Skill::sSkillNames[skillId].c_str();
}
const char *StatsFunctions::GetName(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npc.mName.c_str();
}
const char *StatsFunctions::GetRace(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npc.mRace.c_str();
}
const char *StatsFunctions::GetHead(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npc.mHead.c_str();
}
const char *StatsFunctions::GetHairstyle(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npc.mHair.c_str();
}
int StatsFunctions::GetIsMale(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, false);
return player->npc.isMale();
}
const char* StatsFunctions::GetModel(unsigned short pid) noexcept
{
Player* player;
GET_PLAYER(pid, player, 0);
return player->npc.mModel.c_str();
}
const char *StatsFunctions::GetBirthsign(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->birthsign.c_str();
}
int StatsFunctions::GetLevel(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->creatureStats.mLevel;
}
int StatsFunctions::GetLevelProgress(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npcStats.mLevelProgress;
}
double StatsFunctions::GetHealthBase(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[0].mBase;
}
double StatsFunctions::GetHealthCurrent(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[0].mCurrent;
}
double StatsFunctions::GetMagickaBase(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[1].mBase;
}
double StatsFunctions::GetMagickaCurrent(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[1].mCurrent;
}
double StatsFunctions::GetFatigueBase(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[2].mBase;
}
double StatsFunctions::GetFatigueCurrent(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
return player->creatureStats.mDynamic[2].mCurrent;
}
int StatsFunctions::GetAttributeBase(unsigned short pid, unsigned short attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (attributeId >= ESM::Attribute::Length)
return 0;
return player->creatureStats.mAttributes[attributeId].mBase;
}
int StatsFunctions::GetAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (attributeId >= ESM::Attribute::Length)
return 0;
return player->creatureStats.mAttributes[attributeId].mMod;
}
double StatsFunctions::GetAttributeDamage(unsigned short pid, unsigned short attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (attributeId >= ESM::Attribute::Length)
return 0;
return player->creatureStats.mAttributes[attributeId].mDamage;
}
int StatsFunctions::GetSkillBase(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (skillId >= ESM::Skill::Length)
return 0;
return player->npcStats.mSkills[skillId].mBase;
}
int StatsFunctions::GetSkillModifier(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (skillId >= ESM::Skill::Length)
return 0;
return player->npcStats.mSkills[skillId].mMod;
}
double StatsFunctions::GetSkillDamage(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (skillId >= ESM::Skill::Length)
return 0;
return player->npcStats.mSkills[skillId].mDamage;
}
double StatsFunctions::GetSkillProgress(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0.0f);
if (skillId >= ESM::Skill::Length)
return 0;
return player->npcStats.mSkills[skillId].mProgress;
}
int StatsFunctions::GetSkillIncrease(unsigned short pid, unsigned int attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
if (attributeId > ESM::Attribute::Length)
return 0;
return player->npcStats.mSkillIncrease[attributeId];
}
int StatsFunctions::GetBounty(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, 0);
return player->npcStats.mBounty;
}
void StatsFunctions::SetName(unsigned short pid, const char *name) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (player->npc.mName == name)
return;
player->npc.mName = name;
}
void StatsFunctions::SetRace(unsigned short pid, const char *race) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (player->npc.mRace == race)
return;
LOG_MESSAGE_SIMPLE(TimedLog::LOG_VERBOSE, "Setting race for %s: %s -> %s", player->npc.mName.c_str(),
player->npc.mRace.c_str(), race);
player->npc.mRace = race;
}
void StatsFunctions::SetHead(unsigned short pid, const char *head) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (player->npc.mHead == head)
return;
player->npc.mHead = head;
}
void StatsFunctions::SetHairstyle(unsigned short pid, const char *hairstyle) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (player->npc.mHair == hairstyle)
return;
player->npc.mHair = hairstyle;
}
void StatsFunctions::SetIsMale(unsigned short pid, int state) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->npc.setIsMale(state > 0 ? true : false);
}
void StatsFunctions::SetModel(unsigned short pid, const char *model) noexcept
{
Player* player;
GET_PLAYER(pid, player, );
if (player->npc.mModel == model)
return;
player->npc.mModel = model;
}
void StatsFunctions::SetBirthsign(unsigned short pid, const char *sign) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (player->birthsign == sign)
return;
player->birthsign = sign;
}
void StatsFunctions::SetResetStats(unsigned short pid, bool resetStats) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
player->resetStats = resetStats;
}
void StatsFunctions::SetLevel(unsigned short pid, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
player->creatureStats.mLevel = value;
}
void StatsFunctions::SetLevelProgress(unsigned short pid, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
player->npcStats.mLevelProgress = value;
}
void StatsFunctions::SetHealthBase(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[0].mBase = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 0))
player->statsDynamicIndexChanges.push_back(0);
}
void StatsFunctions::SetHealthCurrent(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[0].mCurrent = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 0))
player->statsDynamicIndexChanges.push_back(0);
}
void StatsFunctions::SetMagickaBase(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[1].mBase = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 1))
player->statsDynamicIndexChanges.push_back(1);
}
void StatsFunctions::SetMagickaCurrent(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[1].mCurrent = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 1))
player->statsDynamicIndexChanges.push_back(1);
}
void StatsFunctions::SetFatigueBase(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[2].mBase = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 2))
player->statsDynamicIndexChanges.push_back(2);
}
void StatsFunctions::SetFatigueCurrent(unsigned short pid, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->creatureStats.mDynamic[2].mCurrent = value;
if (!Utils::vectorContains(player->statsDynamicIndexChanges, 2))
player->statsDynamicIndexChanges.push_back(2);
}
void StatsFunctions::SetAttributeBase(unsigned short pid, unsigned short attributeId, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (attributeId >= ESM::Attribute::Length)
return;
player->creatureStats.mAttributes[attributeId].mBase = value;
if (!Utils::vectorContains(player->attributeIndexChanges, attributeId))
player->attributeIndexChanges.push_back(attributeId);
}
void StatsFunctions::ClearAttributeModifier(unsigned short pid, unsigned short attributeId) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (attributeId >= ESM::Attribute::Length)
return;
player->creatureStats.mAttributes[attributeId].mMod = 0;
if (!Utils::vectorContains(player->attributeIndexChanges, attributeId))
player->attributeIndexChanges.push_back(attributeId);
}
void StatsFunctions::SetAttributeDamage(unsigned short pid, unsigned short attributeId, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (attributeId >= ESM::Attribute::Length)
return;
player->creatureStats.mAttributes[attributeId].mDamage = value;
if (!Utils::vectorContains(player->attributeIndexChanges, attributeId))
player->attributeIndexChanges.push_back(attributeId);
}
void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skillId, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (skillId >= ESM::Skill::Length)
return;
player->npcStats.mSkills[skillId].mBase = value;
if (!Utils::vectorContains(player->skillIndexChanges, skillId))
player->skillIndexChanges.push_back(skillId);
}
void StatsFunctions::ClearSkillModifier(unsigned short pid, unsigned short skillId) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (skillId >= ESM::Skill::Length)
return;
player->npcStats.mSkills[skillId].mMod = 0;
if (!Utils::vectorContains(player->skillIndexChanges, skillId))
player->skillIndexChanges.push_back(skillId);
}
void StatsFunctions::SetSkillDamage(unsigned short pid, unsigned short skillId, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (skillId >= ESM::Skill::Length)
return;
player->npcStats.mSkills[skillId].mDamage = value;
if (!Utils::vectorContains(player->skillIndexChanges, skillId))
player->skillIndexChanges.push_back(skillId);
}
void StatsFunctions::SetSkillProgress(unsigned short pid, unsigned short skillId, double value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
if (skillId >= ESM::Skill::Length)
return;
player->npcStats.mSkills[skillId].mProgress = value;
if (!Utils::vectorContains(player->skillIndexChanges, skillId))
player->skillIndexChanges.push_back(skillId);
}
void StatsFunctions::SetSkillIncrease(unsigned short pid, unsigned int attributeId, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
if (attributeId > ESM::Attribute::Length)
return;
player->npcStats.mSkillIncrease[attributeId] = value;
if (!Utils::vectorContains(player->attributeIndexChanges, attributeId))
player->attributeIndexChanges.push_back(attributeId);
}
void StatsFunctions::SetBounty(unsigned short pid, int value) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
player->npcStats.mBounty = value;
}
void StatsFunctions::SetCharGenStage(unsigned short pid, int currentStage, int endStage) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
player->charGenState.currentStage = currentStage;
player->charGenState.endStage = endStage;
player->charGenState.isFinished = false;
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARGEN);
packet->setPlayer(player);
packet->Send(false);
}
void StatsFunctions::SendBaseInfo(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BASEINFO);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
}
void StatsFunctions::SendStatsDynamic(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_STATS_DYNAMIC);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
player->statsDynamicIndexChanges.clear();
}
void StatsFunctions::SendAttributes(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
player->attributeIndexChanges.clear();
}
void StatsFunctions::SendSkills(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player,);
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SKILL);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
player->skillIndexChanges.clear();
}
void StatsFunctions::SendLevel(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_LEVEL);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
}
void StatsFunctions::SendBounty(unsigned short pid) noexcept
{
Player *player;
GET_PLAYER(pid, player, );
mwmp::PlayerPacket *packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOUNTY);
packet->setPlayer(player);
packet->Send(false);
packet->Send(true);
}