forked from mirror/openmw-tes3mp
Move werewolf functions from World to MechanicsManager
This commit is contained in:
parent
53334d08a2
commit
f052c05018
7 changed files with 117 additions and 118 deletions
|
@ -221,6 +221,13 @@ namespace MWBase
|
|||
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
||||
|
||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim) = 0;
|
||||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||
|
||||
/// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST.
|
||||
/// It only applies to the current form the NPC is in.
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -456,13 +456,6 @@ namespace MWBase
|
|||
/// Returns true if levitation spell effect is allowed.
|
||||
virtual bool isLevitationEnabled() const = 0;
|
||||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||
|
||||
/// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST.
|
||||
/// It only applies to the current form the NPC is in.
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||
|
||||
virtual bool getGodModeState() = 0;
|
||||
|
||||
virtual bool toggleGodMode() = 0;
|
||||
|
|
|
@ -1585,4 +1585,109 @@ namespace MWMechanics
|
|||
{
|
||||
return mActors.isReadyToBlock(ptr);
|
||||
}
|
||||
|
||||
void MechanicsManager::setWerewolf(const MWWorld::Ptr& actor, bool werewolf)
|
||||
{
|
||||
MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor);
|
||||
|
||||
// The actor does not have to change state
|
||||
if (npcStats.isWerewolf() == werewolf)
|
||||
return;
|
||||
|
||||
MWWorld::Player* player = &MWBase::Environment::get().getWorld()->getPlayer();
|
||||
|
||||
if (actor == player->getPlayer())
|
||||
{
|
||||
if (werewolf)
|
||||
{
|
||||
player->saveSkillsAttributes();
|
||||
player->setWerewolfSkillsAttributes();
|
||||
}
|
||||
else
|
||||
player->restoreSkillsAttributes();
|
||||
}
|
||||
|
||||
npcStats.setWerewolf(werewolf);
|
||||
|
||||
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
|
||||
// bones that do not even exist with the werewolf object root.
|
||||
// Therefore, make sure to unequip everything at once, and only fire the change event
|
||||
// (which will rebuild the animation parts) afterwards. unequipAll will do this for us.
|
||||
MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor);
|
||||
invStore.unequipAll(actor);
|
||||
|
||||
if(werewolf)
|
||||
{
|
||||
MWWorld::InventoryStore &inv = actor.getClass().getInventoryStore(actor);
|
||||
|
||||
inv.equip(MWWorld::InventoryStore::Slot_Robe, inv.ContainerStore::add("werewolfrobe", 1, actor), actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor);
|
||||
}
|
||||
|
||||
if(actor == player->getPlayer())
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->reattachPlayerCamera();
|
||||
|
||||
// Update the GUI only when called on the player
|
||||
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
||||
|
||||
if (werewolf)
|
||||
{
|
||||
windowManager->forceHide(MWGui::GW_Inventory);
|
||||
windowManager->forceHide(MWGui::GW_Magic);
|
||||
}
|
||||
else
|
||||
{
|
||||
windowManager->unsetForceHide(MWGui::GW_Inventory);
|
||||
windowManager->unsetForceHide(MWGui::GW_Magic);
|
||||
}
|
||||
|
||||
windowManager->setWerewolfOverlay(werewolf);
|
||||
|
||||
// Witnesses of the player's transformation will make them a globally known werewolf
|
||||
std::vector<MWWorld::Ptr> closeActors;
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->getFloat(), closeActors);
|
||||
|
||||
bool detected = false, reported = false;
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it)
|
||||
{
|
||||
if (*it == actor)
|
||||
continue;
|
||||
|
||||
if (!it->getClass().isNpc())
|
||||
continue;
|
||||
|
||||
if (MWBase::Environment::get().getWorld()->getLOS(*it, actor) && awarenessCheck(actor, *it))
|
||||
detected = true;
|
||||
if (it->getClass().getCreatureStats(*it).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0)
|
||||
reported = true;
|
||||
}
|
||||
|
||||
if (detected)
|
||||
{
|
||||
windowManager->messageBox("#{sWerewolfAlarmMessage}");
|
||||
MWBase::Environment::get().getWorld()->setGlobalInt("pcknownwerewolf", 1);
|
||||
|
||||
if (reported)
|
||||
{
|
||||
npcStats.setBounty(npcStats.getBounty()+
|
||||
gmst.find("iWereWolfBounty")->getInt());
|
||||
windowManager->messageBox("#{sCrimeMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MechanicsManager::applyWerewolfAcrobatics(const MWWorld::Ptr &actor)
|
||||
{
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor);
|
||||
|
||||
stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -187,6 +187,9 @@ namespace MWMechanics
|
|||
/// @return is \a ptr allowed to take/use \a cellref or is it a crime?
|
||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::CellRef& cellref, MWWorld::Ptr& victim);
|
||||
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||
|
||||
private:
|
||||
void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
|
||||
OffenseType type, int arg=0);
|
||||
|
|
|
@ -1096,7 +1096,7 @@ namespace MWScript
|
|||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWBase::Environment::get().getWorld()->setWerewolf(ptr, set);
|
||||
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1108,7 +1108,7 @@ namespace MWScript
|
|||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWBase::Environment::get().getWorld()->applyWerewolfAcrobatics(ptr);
|
||||
MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2453,111 +2453,6 @@ namespace MWWorld
|
|||
mRendering->rebuildPtr(getPlayerPtr());
|
||||
}
|
||||
|
||||
void World::setWerewolf(const MWWorld::Ptr& actor, bool werewolf)
|
||||
{
|
||||
MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor);
|
||||
|
||||
// The actor does not have to change state
|
||||
if (npcStats.isWerewolf() == werewolf)
|
||||
return;
|
||||
|
||||
if (actor == getPlayerPtr())
|
||||
{
|
||||
if (werewolf)
|
||||
{
|
||||
mPlayer->saveSkillsAttributes();
|
||||
mPlayer->setWerewolfSkillsAttributes();
|
||||
}
|
||||
else
|
||||
mPlayer->restoreSkillsAttributes();
|
||||
}
|
||||
|
||||
npcStats.setWerewolf(werewolf);
|
||||
|
||||
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
|
||||
// bones that do not even exist with the werewolf object root.
|
||||
// Therefore, make sure to unequip everything at once, and only fire the change event
|
||||
// (which will rebuild the animation parts) afterwards. unequipAll will do this for us.
|
||||
MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor);
|
||||
invStore.unequipAll(actor);
|
||||
|
||||
if(werewolf)
|
||||
{
|
||||
InventoryStore &inv = actor.getClass().getInventoryStore(actor);
|
||||
|
||||
inv.equip(InventoryStore::Slot_Robe, inv.ContainerStore::add("werewolfrobe", 1, actor), actor);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor.getClass().getContainerStore(actor).remove("werewolfrobe", 1, actor);
|
||||
}
|
||||
|
||||
// NpcAnimation::updateParts will already rebuild the animation when it detects change of Npc type.
|
||||
// the following is just for reattaching the camera properly.
|
||||
mRendering->rebuildPtr(actor);
|
||||
|
||||
if(actor == getPlayerPtr())
|
||||
{
|
||||
// Update the GUI only when called on the player
|
||||
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
||||
|
||||
if (werewolf)
|
||||
{
|
||||
windowManager->forceHide(MWGui::GW_Inventory);
|
||||
windowManager->forceHide(MWGui::GW_Magic);
|
||||
}
|
||||
else
|
||||
{
|
||||
windowManager->unsetForceHide(MWGui::GW_Inventory);
|
||||
windowManager->unsetForceHide(MWGui::GW_Magic);
|
||||
}
|
||||
|
||||
windowManager->setWerewolfOverlay(werewolf);
|
||||
|
||||
// Witnesses of the player's transformation will make them a globally known werewolf
|
||||
std::vector<MWWorld::Ptr> closeActors;
|
||||
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(actor.getRefData().getPosition().asVec3(),
|
||||
getStore().get<ESM::GameSetting>().search("fAlarmRadius")->getFloat(),
|
||||
closeActors);
|
||||
|
||||
bool detected = false, reported = false;
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it = closeActors.begin(); it != closeActors.end(); ++it)
|
||||
{
|
||||
if (*it == actor)
|
||||
continue;
|
||||
|
||||
if (!it->getClass().isNpc())
|
||||
continue;
|
||||
|
||||
if (getLOS(*it, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, *it))
|
||||
detected = true;
|
||||
if (it->getClass().getCreatureStats(*it).getAiSetting(MWMechanics::CreatureStats::AI_Alarm).getModified() > 0)
|
||||
reported = true;
|
||||
}
|
||||
|
||||
if (detected)
|
||||
{
|
||||
windowManager->messageBox("#{sWerewolfAlarmMessage}");
|
||||
setGlobalInt("pcknownwerewolf", 1);
|
||||
|
||||
if (reported)
|
||||
{
|
||||
npcStats.setBounty(npcStats.getBounty()+
|
||||
mStore.get<ESM::GameSetting>().find("iWereWolfBounty")->getInt());
|
||||
windowManager->messageBox("#{sCrimeMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::applyWerewolfAcrobatics(const Ptr &actor)
|
||||
{
|
||||
const Store<ESM::GameSetting> &gmst = getStore().get<ESM::GameSetting>();
|
||||
MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor);
|
||||
|
||||
stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt());
|
||||
}
|
||||
|
||||
bool World::getGodModeState()
|
||||
{
|
||||
return mGodMode;
|
||||
|
|
|
@ -560,10 +560,6 @@ namespace MWWorld
|
|||
/// Returns true if levitation spell effect is allowed.
|
||||
virtual bool isLevitationEnabled() const;
|
||||
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
||||
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||
|
||||
virtual bool getGodModeState();
|
||||
|
||||
virtual bool toggleGodMode();
|
||||
|
|
Loading…
Reference in a new issue