1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 02:49:55 +00:00
openmw-tes3mp/apps/openmw/mwmechanics/mechanicsmanager.cpp

351 lines
12 KiB
C++
Raw Normal View History

#include "mechanicsmanager.hpp"
#include <components/esm_store/store.hpp>
#include "../mwgui/window_manager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
namespace MWMechanics
{
2010-09-15 11:31:26 +00:00
void MechanicsManager::buildPlayer()
{
MWWorld::Ptr ptr = mEnvironment.mWorld->getPlayer().getPlayer();
2010-09-15 11:31:26 +00:00
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
MWMechanics::NpcStats& npcStats = MWWorld::Class::get (ptr).getNpcStats (ptr);
2010-09-15 11:31:26 +00:00
2010-09-15 13:32:35 +00:00
const ESM::NPC *player = ptr.get<ESM::NPC>()->base;
2010-09-15 11:31:26 +00:00
// reset
2010-09-15 13:32:35 +00:00
creatureStats.mLevel = player->npdt52.level;
creatureStats.mSpells.clear();
creatureStats.mMagicEffects = MagicEffects();
2010-09-15 11:31:26 +00:00
for (int i=0; i<27; ++i)
npcStats.mSkill[i].setBase (player->npdt52.skills[i]);
2010-09-15 11:31:26 +00:00
// race
2010-09-26 08:01:30 +00:00
if (mRaceSelected)
{
const ESM::Race *race =
mEnvironment.mWorld->getStore().races.find (
mEnvironment.mWorld->getPlayer().getRace());
bool male = mEnvironment.mWorld->getPlayer().isMale();
2010-09-26 08:01:30 +00:00
for (int i=0; i<8; ++i)
{
2010-09-26 08:01:30 +00:00
const ESM::Race::MaleFemale *attribute = 0;
switch (i)
{
case 0: attribute = &race->data.strength; break;
case 1: attribute = &race->data.intelligence; break;
case 2: attribute = &race->data.willpower; break;
case 3: attribute = &race->data.agility; break;
case 4: attribute = &race->data.speed; break;
case 5: attribute = &race->data.endurance; break;
case 6: attribute = &race->data.personality; break;
case 7: attribute = &race->data.luck; break;
}
2010-09-26 08:01:30 +00:00
creatureStats.mAttributes[i].setBase (
static_cast<int> (male ? attribute->male : attribute->female));
}
2010-09-26 08:01:30 +00:00
for (int i=0; i<7; ++i)
{
2010-09-26 08:01:30 +00:00
int index = race->data.bonus[i].skill;
if (index>=0 && index<27)
{
npcStats.mSkill[index].setBase (
npcStats.mSkill[index].getBase() + race->data.bonus[i].bonus);
}
}
2010-09-26 08:01:30 +00:00
for (std::vector<std::string>::const_iterator iter (race->powers.list.begin());
iter!=race->powers.list.end(); ++iter)
{
creatureStats.mSpells.add (*iter, mEnvironment);
}
}
2010-09-15 11:31:26 +00:00
// birthsign
if (!mEnvironment.mWorld->getPlayer().getBirthsign().empty())
2010-09-26 08:01:30 +00:00
{
const ESM::BirthSign *sign =
mEnvironment.mWorld->getStore().birthSigns.find (
mEnvironment.mWorld->getPlayer().getBirthsign());
for (std::vector<std::string>::const_iterator iter (sign->powers.list.begin());
iter!=sign->powers.list.end(); ++iter)
{
creatureStats.mSpells.add (*iter, mEnvironment);
}
2010-09-26 08:01:30 +00:00
}
2010-09-15 11:31:26 +00:00
// class
2010-09-26 08:01:30 +00:00
if (mClassSelected)
{
const ESM::Class& class_ = mEnvironment.mWorld->getPlayer().getClass();
2010-09-26 08:01:30 +00:00
for (int i=0; i<2; ++i)
{
2010-09-26 08:01:30 +00:00
int attribute = class_.data.attribute[i];
if (attribute>=0 && attribute<8)
{
creatureStats.mAttributes[attribute].setBase (
creatureStats.mAttributes[attribute].getBase() + 10);
}
}
2010-09-26 08:01:30 +00:00
for (int i=0; i<2; ++i)
{
2010-09-26 08:01:30 +00:00
int bonus = i==0 ? 10 : 25;
2010-09-26 08:01:30 +00:00
for (int i2=0; i2<5; ++i2)
{
2010-09-26 08:01:30 +00:00
int index = class_.data.skills[i2][i];
if (index>=0 && index<27)
{
npcStats.mSkill[index].setBase (
npcStats.mSkill[index].getBase() + bonus);
}
}
}
2010-09-15 11:31:26 +00:00
2010-09-26 08:01:30 +00:00
typedef ESMS::IndexListT<ESM::Skill>::MapType ContainerType;
const ContainerType& skills = mEnvironment.mWorld->getStore().skills.list;
2010-09-26 08:01:30 +00:00
for (ContainerType::const_iterator iter (skills.begin()); iter!=skills.end(); ++iter)
{
2010-09-26 08:01:30 +00:00
if (iter->second.data.specialization==class_.data.specialization)
{
2010-09-26 08:01:30 +00:00
int index = iter->first;
if (index>=0 && index<27)
{
npcStats.mSkill[index].setBase (
npcStats.mSkill[index].getBase() + 5);
}
}
}
}
// magic effects
adjustMagicEffects (ptr);
2010-09-15 11:31:26 +00:00
// calculate dynamic stats
int strength = creatureStats.mAttributes[0].getBase();
int intelligence = creatureStats.mAttributes[1].getBase();
int willpower = creatureStats.mAttributes[2].getBase();
int agility = creatureStats.mAttributes[3].getBase();
int endurance = creatureStats.mAttributes[5].getBase();
double magickaFactor = creatureStats.mMagicEffects.get (EffectKey (84)).mMagnitude*0.1 + 0.5;
creatureStats.mDynamic[0].setBase (static_cast<int> (0.5 * (strength + endurance)));
creatureStats.mDynamic[1].setBase (static_cast<int> (intelligence +
magickaFactor * intelligence));
creatureStats.mDynamic[2].setBase (strength+willpower+agility+endurance);
for (int i=0; i<3; ++i)
creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified());
2010-09-15 11:31:26 +00:00
}
void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature)
{
MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now = creatureStats.mSpells.getMagicEffects (mEnvironment);
/// \todo add effects from active spells and equipment
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
creatureStats.mMagicEffects = now;
// TODO apply diff to other stats
}
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
2010-09-26 08:01:30 +00:00
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
mRaceSelected (false)
{
2010-09-15 11:31:26 +00:00
buildPlayer();
}
void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
{
mActors.insert (ptr);
}
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
{
2011-02-10 09:38:45 +00:00
if (ptr==mWatched)
mWatched = MWWorld::Ptr();
mActors.erase (ptr);
}
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
{
2011-02-10 09:38:45 +00:00
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
mWatched = MWWorld::Ptr();
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
while (iter!=mActors.end())
if (iter->getCell()==cellStore)
{
2011-12-09 05:08:30 +00:00
//std::cout << "Erasing an actor";
mActors.erase (iter++);
}
else
++iter;
}
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
{
mWatched = ptr;
}
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
{
if (!mWatched.isEmpty())
{
MWMechanics::CreatureStats& stats =
MWWorld::Class::get (mWatched).getCreatureStats (mWatched);
2010-09-21 15:42:07 +00:00
MWMechanics::NpcStats& npcStats =
MWWorld::Class::get (mWatched).getNpcStats (mWatched);
static const char *attributeNames[8] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8"
};
static const char *dynamicNames[3] =
{
"HBar", "MBar", "FBar"
};
for (int i=0; i<8; ++i)
{
if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i])
{
mWatchedCreature.mAttributes[i] = stats.mAttributes[i];
mEnvironment.mWindowManager->setValue (attributeNames[i], stats.mAttributes[i]);
}
}
for (int i=0; i<3; ++i)
{
if (stats.mDynamic[i]!=mWatchedCreature.mDynamic[i])
{
mWatchedCreature.mDynamic[i] = stats.mDynamic[i];
mEnvironment.mWindowManager->setValue (dynamicNames[i], stats.mDynamic[i]);
}
}
2010-09-15 13:32:35 +00:00
2010-09-21 15:42:07 +00:00
bool update = false;
//Loop over ESM::Skill::SkillEnum
for(int i = 0; i < 27; ++i)
2010-09-21 15:42:07 +00:00
{
if(npcStats.mSkill[i] != mWatchedNpc.mSkill[i])
2010-09-21 15:42:07 +00:00
{
update = true;
mWatchedNpc.mSkill[i] = npcStats.mSkill[i];
mEnvironment.mWindowManager->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]);
2010-09-21 15:42:07 +00:00
}
}
if (update)
mEnvironment.mWindowManager->updateSkillArea();
2010-09-15 13:32:35 +00:00
mEnvironment.mWindowManager->setValue ("level", stats.mLevel);
}
if (mUpdatePlayer)
{
// basic player profile; should not change anymore after the creation phase is finished.
mEnvironment.mWindowManager->setValue ("name", mEnvironment.mWorld->getPlayer().getName());
mEnvironment.mWindowManager->setValue ("race",
mEnvironment.mWorld->getStore().races.find (mEnvironment.mWorld->getPlayer().
getRace())->name);
mEnvironment.mWindowManager->setValue ("class",
mEnvironment.mWorld->getPlayer().getClass().name);
mUpdatePlayer = false;
2010-09-21 15:42:07 +00:00
MWGui::WindowManager::SkillList majorSkills (5);
MWGui::WindowManager::SkillList minorSkills (5);
for (int i=0; i<5; ++i)
{
minorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][0];
majorSkills[i] = mEnvironment.mWorld->getPlayer().getClass().data.skills[i][1];
2010-09-21 15:42:07 +00:00
}
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
}
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
++iter)
{
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
if (vector!=Ogre::Vector3::ZERO)
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
}
}
void MechanicsManager::setPlayerName (const std::string& name)
{
mEnvironment.mWorld->getPlayer().setName (name);
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerRace (const std::string& race, bool male)
{
mEnvironment.mWorld->getPlayer().setGender (male);
mEnvironment.mWorld->getPlayer().setRace (race);
2010-09-26 08:01:30 +00:00
mRaceSelected = true;
2010-09-15 11:31:26 +00:00
buildPlayer();
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerBirthsign (const std::string& id)
{
mEnvironment.mWorld->getPlayer().setBirthsign (id);
2010-09-15 11:31:26 +00:00
buildPlayer();
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerClass (const std::string& id)
{
mEnvironment.mWorld->getPlayer().setClass (*mEnvironment.mWorld->getStore().classes.find (id));
2010-09-26 08:01:30 +00:00
mClassSelected = true;
2010-09-15 11:31:26 +00:00
buildPlayer();
mUpdatePlayer = true;
}
void MechanicsManager::setPlayerClass (const ESM::Class& class_)
{
mEnvironment.mWorld->getPlayer().setClass (class_);
2010-09-26 08:01:30 +00:00
mClassSelected = true;
2010-09-15 11:31:26 +00:00
buildPlayer();
mUpdatePlayer = true;
}
}