mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-07 13:20:25 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw
This commit is contained in:
commit
251df73407
@ -387,7 +387,7 @@ std::string magicEffectLabel(int idx)
|
|||||||
"sEffectSummonCreature04",
|
"sEffectSummonCreature04",
|
||||||
"sEffectSummonCreature05"
|
"sEffectSummonCreature05"
|
||||||
};
|
};
|
||||||
if (idx >= 0 && idx <= 143)
|
if (idx >= 0 && idx <= 142)
|
||||||
return magicEffectLabels[idx];
|
return magicEffectLabels[idx];
|
||||||
else
|
else
|
||||||
return "Invalid";
|
return "Invalid";
|
||||||
@ -471,7 +471,7 @@ std::string skillLabel(int idx)
|
|||||||
"Speechcraft",
|
"Speechcraft",
|
||||||
"Hand-to-hand"
|
"Hand-to-hand"
|
||||||
};
|
};
|
||||||
if (idx >= 0 && idx <= 27)
|
if (idx >= 0 && idx <= 26)
|
||||||
return skillLabels[idx];
|
return skillLabels[idx];
|
||||||
else
|
else
|
||||||
return "Invalid";
|
return "Invalid";
|
||||||
@ -498,7 +498,7 @@ std::string rangeTypeLabel(int idx)
|
|||||||
"Touch",
|
"Touch",
|
||||||
"Target"
|
"Target"
|
||||||
};
|
};
|
||||||
if (idx >= 0 && idx <= 3)
|
if (idx >= 0 && idx <= 2)
|
||||||
return rangeTypeLabels[idx];
|
return rangeTypeLabels[idx];
|
||||||
else
|
else
|
||||||
return "Invalid";
|
return "Invalid";
|
||||||
|
@ -707,9 +707,9 @@ void Record<ESM::Faction>::print()
|
|||||||
std::cout << " Faction Reaction: "
|
std::cout << " Faction Reaction: "
|
||||||
<< mData.mData.mRankData[i].mFactReaction << std::endl;
|
<< mData.mData.mRankData[i].mFactReaction << std::endl;
|
||||||
}
|
}
|
||||||
std::vector<ESM::Faction::Reaction>::iterator rit;
|
std::map<std::string, int>::iterator rit;
|
||||||
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++)
|
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++)
|
||||||
std::cout << " Reaction: " << rit->mReaction << " = " << rit->mFaction << std::endl;
|
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -68,6 +68,12 @@ namespace MWBase
|
|||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
||||||
|
|
||||||
|
/// Changes faction1's opinion of faction2 by \a diff.
|
||||||
|
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff) = 0;
|
||||||
|
|
||||||
|
/// @return faction1's opinion of faction2
|
||||||
|
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +642,8 @@ namespace MWDialogue
|
|||||||
if (iter->second)
|
if (iter->second)
|
||||||
state.mKnownTopics.push_back (iter->first);
|
state.mKnownTopics.push_back (iter->first);
|
||||||
|
|
||||||
|
state.mModFactionReaction = mModFactionReaction;
|
||||||
|
|
||||||
writer.startRecord (ESM::REC_DIAS);
|
writer.startRecord (ESM::REC_DIAS);
|
||||||
state.save (writer);
|
state.save (writer);
|
||||||
writer.endRecord (ESM::REC_DIAS);
|
writer.endRecord (ESM::REC_DIAS);
|
||||||
@ -661,9 +663,46 @@ namespace MWDialogue
|
|||||||
iter!=state.mKnownTopics.end(); ++iter)
|
iter!=state.mKnownTopics.end(); ++iter)
|
||||||
if (store.get<ESM::Dialogue>().search (*iter))
|
if (store.get<ESM::Dialogue>().search (*iter))
|
||||||
mKnownTopics.insert (std::make_pair (*iter, true));
|
mKnownTopics.insert (std::make_pair (*iter, true));
|
||||||
|
|
||||||
|
mModFactionReaction = state.mModFactionReaction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueManager::modFactionReaction(const std::string &faction1, const std::string &faction2, int diff)
|
||||||
|
{
|
||||||
|
std::string fact1 = Misc::StringUtils::lowerCase(faction1);
|
||||||
|
std::string fact2 = Misc::StringUtils::lowerCase(faction2);
|
||||||
|
|
||||||
|
// Make sure the factions exist
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact1);
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact2);
|
||||||
|
|
||||||
|
std::map<std::string, int>& map = mModFactionReaction[fact1];
|
||||||
|
if (map.find(fact2) == map.end())
|
||||||
|
map[fact2] = 0;
|
||||||
|
map[fact2] += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DialogueManager::getFactionReaction(const std::string &faction1, const std::string &faction2) const
|
||||||
|
{
|
||||||
|
std::string fact1 = Misc::StringUtils::lowerCase(faction1);
|
||||||
|
std::string fact2 = Misc::StringUtils::lowerCase(faction2);
|
||||||
|
|
||||||
|
ModFactionReactionMap::const_iterator map = mModFactionReaction.find(fact1);
|
||||||
|
int diff = 0;
|
||||||
|
if (map != mModFactionReaction.end() && map->second.find(fact2) != map->second.end())
|
||||||
|
diff = map->second.at(fact2);
|
||||||
|
|
||||||
|
const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(fact1);
|
||||||
|
|
||||||
|
std::map<std::string, int>::const_iterator it = faction->mReactions.begin();
|
||||||
|
for (; it != faction->mReactions.end(); ++it)
|
||||||
|
{
|
||||||
|
if (Misc::StringUtils::ciEqual(it->first, fact2))
|
||||||
|
return it->second + diff;
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
|
std::vector<HyperTextToken> ParseHyperText(const std::string& text)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,11 @@ namespace MWDialogue
|
|||||||
{
|
{
|
||||||
std::map<std::string, ESM::Dialogue> mDialogueMap;
|
std::map<std::string, ESM::Dialogue> mDialogueMap;
|
||||||
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
|
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
|
||||||
|
|
||||||
|
// Modified faction reactions. <Faction1, <Faction2, Difference> >
|
||||||
|
typedef std::map<std::string, std::map<std::string, int> > ModFactionReactionMap;
|
||||||
|
ModFactionReactionMap mModFactionReaction;
|
||||||
|
|
||||||
std::list<std::string> mActorKnownTopics;
|
std::list<std::string> mActorKnownTopics;
|
||||||
|
|
||||||
Translation::Storage& mTranslationDataStorage;
|
Translation::Storage& mTranslationDataStorage;
|
||||||
@ -86,6 +91,12 @@ namespace MWDialogue
|
|||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
||||||
|
|
||||||
|
/// Changes faction1's opinion of faction2 by \a diff.
|
||||||
|
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff);
|
||||||
|
|
||||||
|
/// @return faction1's opinion of faction2
|
||||||
|
virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -396,16 +396,15 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
|
|||||||
|
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
const ESM::Faction& faction =
|
|
||||||
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
|
|
||||||
|
|
||||||
MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player);
|
MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player);
|
||||||
|
|
||||||
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin());
|
std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin();
|
||||||
iter!=faction.mReactions.end(); ++iter)
|
for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt)
|
||||||
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end())
|
{
|
||||||
if (low ? iter->mReaction<value : iter->mReaction>value)
|
int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first);
|
||||||
value = iter->mReaction;
|
if (low ? reaction < value : reaction > value)
|
||||||
|
value = reaction;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -492,7 +492,8 @@ namespace MWInput
|
|||||||
}
|
}
|
||||||
if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
if (arg.keysym.sym == SDLK_x && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
||||||
{
|
{
|
||||||
std::string text = edit->getTextSelection();
|
// Discard color codes and other escape characters
|
||||||
|
std::string text = MyGUI::TextIterator::getOnlyText(edit->getTextSelection());
|
||||||
if (text.length())
|
if (text.length())
|
||||||
{
|
{
|
||||||
SDL_SetClipboardText(text.c_str());
|
SDL_SetClipboardText(text.c_str());
|
||||||
@ -504,7 +505,8 @@ namespace MWInput
|
|||||||
{
|
{
|
||||||
if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
if (arg.keysym.sym == SDLK_c && (arg.keysym.mod & SDL_Keymod(KMOD_CTRL)))
|
||||||
{
|
{
|
||||||
std::string text = edit->getTextSelection();
|
// Discard color codes and other escape characters
|
||||||
|
std::string text = MyGUI::TextIterator::getOnlyText(edit->getTextSelection());
|
||||||
if (text.length())
|
if (text.length())
|
||||||
SDL_SetClipboardText(text.c_str());
|
SDL_SetClipboardText(text.c_str());
|
||||||
}
|
}
|
||||||
|
@ -407,29 +407,25 @@ MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::I
|
|||||||
return inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
return inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::playRandomDeath(float startpoint)
|
void CharacterController::playDeath(float startpoint, CharacterState death)
|
||||||
{
|
{
|
||||||
if(MWBase::Environment::get().getWorld()->isSwimming(mPtr) && mAnimation->hasAnimation("swimdeath"))
|
switch (death)
|
||||||
{
|
{
|
||||||
mDeathState = CharState_SwimDeath;
|
case CharState_SwimDeath:
|
||||||
mCurrentDeath = "swimdeath";
|
mCurrentDeath = "swimdeath";
|
||||||
}
|
break;
|
||||||
else if (mHitState == CharState_KnockDown)
|
case CharState_DeathKnockDown:
|
||||||
{
|
|
||||||
mDeathState = CharState_DeathKnockDown;
|
|
||||||
mCurrentDeath = "deathknockdown";
|
mCurrentDeath = "deathknockdown";
|
||||||
}
|
break;
|
||||||
else if (mHitState == CharState_KnockOut)
|
case CharState_DeathKnockOut:
|
||||||
{
|
|
||||||
mDeathState = CharState_DeathKnockOut;
|
|
||||||
mCurrentDeath = "deathknockout";
|
mCurrentDeath = "deathknockout";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mCurrentDeath = "death" + Ogre::StringConverter::toString(death - CharState_Death1 + 1);
|
||||||
}
|
}
|
||||||
else
|
mDeathState = death;
|
||||||
{
|
|
||||||
int selected=0;
|
mPtr.getClass().getCreatureStats(mPtr).setDeathAnimation(mDeathState - CharState_Death1);
|
||||||
mCurrentDeath = chooseRandomGroup("death", &selected);
|
|
||||||
mDeathState = static_cast<CharacterState>(CharState_Death1 + (selected-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// For dead actors, refreshCurrentAnims is no longer called, so we need to disable the movement state manually.
|
// For dead actors, refreshCurrentAnims is no longer called, so we need to disable the movement state manually.
|
||||||
mMovementState = CharState_None;
|
mMovementState = CharState_None;
|
||||||
@ -440,6 +436,29 @@ void CharacterController::playRandomDeath(float startpoint)
|
|||||||
false, 1.0f, "start", "stop", startpoint, 0);
|
false, 1.0f, "start", "stop", startpoint, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CharacterController::playRandomDeath(float startpoint)
|
||||||
|
{
|
||||||
|
if(MWBase::Environment::get().getWorld()->isSwimming(mPtr) && mAnimation->hasAnimation("swimdeath"))
|
||||||
|
{
|
||||||
|
mDeathState = CharState_SwimDeath;
|
||||||
|
}
|
||||||
|
else if (mHitState == CharState_KnockDown)
|
||||||
|
{
|
||||||
|
mDeathState = CharState_DeathKnockDown;
|
||||||
|
}
|
||||||
|
else if (mHitState == CharState_KnockOut)
|
||||||
|
{
|
||||||
|
mDeathState = CharState_DeathKnockOut;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int selected=0;
|
||||||
|
chooseRandomGroup("death", &selected);
|
||||||
|
mDeathState = static_cast<CharacterState>(CharState_Death1 + (selected-1));
|
||||||
|
}
|
||||||
|
playDeath(startpoint, mDeathState);
|
||||||
|
}
|
||||||
|
|
||||||
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim)
|
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim)
|
||||||
: mPtr(ptr)
|
: mPtr(ptr)
|
||||||
, mAnimation(anim)
|
, mAnimation(anim)
|
||||||
@ -497,7 +516,8 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
|
|||||||
|
|
||||||
if(mDeathState != CharState_None)
|
if(mDeathState != CharState_None)
|
||||||
{
|
{
|
||||||
playRandomDeath(1.0f);
|
int deathindex = mPtr.getClass().getCreatureStats(mPtr).getDeathAnimation();
|
||||||
|
playDeath(1.0f, CharacterState(CharState_Death1 + deathindex));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
refreshCurrentAnims(mIdleState, mMovementState, true);
|
refreshCurrentAnims(mIdleState, mMovementState, true);
|
||||||
|
@ -181,6 +181,7 @@ class CharacterController
|
|||||||
|
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
|
|
||||||
|
void playDeath(float startpoint, CharacterState death);
|
||||||
void playRandomDeath(float startpoint = 0.0f);
|
void playRandomDeath(float startpoint = 0.0f);
|
||||||
|
|
||||||
/// choose a random animation group with \a prefix and numeric suffix
|
/// choose a random animation group with \a prefix and numeric suffix
|
||||||
|
@ -22,7 +22,8 @@ namespace MWMechanics
|
|||||||
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mKnockdownOneFrame(false),
|
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mKnockdownOneFrame(false),
|
||||||
mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false),
|
mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false),
|
||||||
mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f),
|
mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f),
|
||||||
mLastRestock(0,0), mGoldPool(0), mActorId(-1)
|
mLastRestock(0,0), mGoldPool(0), mActorId(-1),
|
||||||
|
mDeathAnimation(0)
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
mAiSettings[i] = 0;
|
mAiSettings[i] = 0;
|
||||||
@ -498,6 +499,7 @@ namespace MWMechanics
|
|||||||
state.mDrawState = mDrawState;
|
state.mDrawState = mDrawState;
|
||||||
state.mLevel = mLevel;
|
state.mLevel = mLevel;
|
||||||
state.mActorId = mActorId;
|
state.mActorId = mActorId;
|
||||||
|
state.mDeathAnimation = mDeathAnimation;
|
||||||
|
|
||||||
mSpells.writeState(state.mSpells);
|
mSpells.writeState(state.mSpells);
|
||||||
mActiveSpells.writeState(state.mActiveSpells);
|
mActiveSpells.writeState(state.mActiveSpells);
|
||||||
@ -537,6 +539,7 @@ namespace MWMechanics
|
|||||||
mDrawState = DrawState_(state.mDrawState);
|
mDrawState = DrawState_(state.mDrawState);
|
||||||
mLevel = state.mLevel;
|
mLevel = state.mLevel;
|
||||||
mActorId = state.mActorId;
|
mActorId = state.mActorId;
|
||||||
|
mDeathAnimation = state.mDeathAnimation;
|
||||||
|
|
||||||
mSpells.readState(state.mSpells);
|
mSpells.readState(state.mSpells);
|
||||||
mActiveSpells.readState(state.mActiveSpells);
|
mActiveSpells.readState(state.mActiveSpells);
|
||||||
@ -590,4 +593,14 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
esm.getHNT(sActorId, "COUN");
|
esm.getHNT(sActorId, "COUN");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CreatureStats::getDeathAnimation() const
|
||||||
|
{
|
||||||
|
return mDeathAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setDeathAnimation(unsigned char index)
|
||||||
|
{
|
||||||
|
mDeathAnimation = index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,9 @@ namespace MWMechanics
|
|||||||
|
|
||||||
int mActorId;
|
int mActorId;
|
||||||
|
|
||||||
|
// The index of the death animation that was played
|
||||||
|
unsigned char mDeathAnimation;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// These two are only set by NpcStats, but they are declared in CreatureStats to prevent using virtual methods.
|
// These two are only set by NpcStats, but they are declared in CreatureStats to prevent using virtual methods.
|
||||||
bool mIsWerewolf;
|
bool mIsWerewolf;
|
||||||
@ -250,6 +253,9 @@ namespace MWMechanics
|
|||||||
void setGoldPool(int pool);
|
void setGoldPool(int pool);
|
||||||
int getGoldPool() const;
|
int getGoldPool() const;
|
||||||
|
|
||||||
|
unsigned char getDeathAnimation() const;
|
||||||
|
void setDeathAnimation(unsigned char index);
|
||||||
|
|
||||||
int getActorId();
|
int getActorId();
|
||||||
///< Will generate an actor ID, if the actor does not have one yet.
|
///< Will generate an actor ID, if the actor does not have one yet.
|
||||||
|
|
||||||
|
@ -498,27 +498,24 @@ namespace MWMechanics
|
|||||||
|
|
||||||
if (playerStats.getFactionRanks().find(npcFaction) != playerStats.getFactionRanks().end())
|
if (playerStats.getFactionRanks().find(npcFaction) != playerStats.getFactionRanks().end())
|
||||||
{
|
{
|
||||||
for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npcFaction)->mReactions.begin();
|
if (!playerStats.getExpelled(npcFaction))
|
||||||
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npcFaction)->mReactions.end(); ++it)
|
|
||||||
{
|
{
|
||||||
if(Misc::StringUtils::ciEqual(it->mFaction, npcFaction)
|
reaction = playerStats.getFactionReputation(npcFaction);
|
||||||
&& !playerStats.getExpelled(it->mFaction))
|
|
||||||
reaction = it->mReaction;
|
rank = playerStats.getFactionRanks().find(npcFaction)->second;
|
||||||
}
|
}
|
||||||
rank = playerStats.getFactionRanks().find(npcFaction)->second;
|
|
||||||
}
|
}
|
||||||
else if (npcFaction != "")
|
else if (!npcFaction.empty())
|
||||||
{
|
{
|
||||||
for(std::vector<ESM::Faction::Reaction>::const_iterator it = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npcFaction)->mReactions.begin();
|
std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin();
|
||||||
it != MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npcFaction)->mReactions.end();++it)
|
for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt)
|
||||||
{
|
{
|
||||||
if(playerStats.getFactionRanks().find(Misc::StringUtils::lowerCase(it->mFaction)) != playerStats.getFactionRanks().end() )
|
std::string itFaction = playerFactionIt->first;
|
||||||
{
|
|
||||||
if(it->mReaction < reaction)
|
int itReaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, itFaction);
|
||||||
reaction = it->mReaction;
|
if (playerFactionIt == playerStats.getFactionRanks().begin() || itReaction < reaction)
|
||||||
}
|
reaction = itReaction;
|
||||||
}
|
}
|
||||||
rank = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -54,17 +54,12 @@ void Actors::insertBegin(const MWWorld::Ptr &ptr)
|
|||||||
// Convert MW rotation to a quaternion:
|
// Convert MW rotation to a quaternion:
|
||||||
f = ptr.getCellRef().getPosition().rot;
|
f = ptr.getCellRef().getPosition().rot;
|
||||||
|
|
||||||
// Rotate around X axis
|
// For rendering purposes, actors should only rotate around the Z axis.
|
||||||
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);
|
// X rotation is used for camera rotation (for the player) and for
|
||||||
|
// ranged magic / ranged weapon aiming.
|
||||||
// Rotate around Y axis
|
|
||||||
Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y);
|
|
||||||
|
|
||||||
// Rotate around Z axis
|
|
||||||
Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z);
|
Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
// Rotates first around z, then y, then x
|
insert->setOrientation(zr);
|
||||||
insert->setOrientation(xr*yr*zr);
|
|
||||||
ptr.getRefData().setBaseNode(insert);
|
ptr.getRefData().setBaseNode(insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,11 +775,11 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look in reverse; last-inserted source has priority. */
|
/* Look in reverse; last-inserted source has priority. */
|
||||||
|
AnimState state;
|
||||||
AnimSourceList::reverse_iterator iter(mAnimSources.rbegin());
|
AnimSourceList::reverse_iterator iter(mAnimSources.rbegin());
|
||||||
for(;iter != mAnimSources.rend();++iter)
|
for(;iter != mAnimSources.rend();++iter)
|
||||||
{
|
{
|
||||||
const NifOgre::TextKeyMap &textkeys = (*iter)->mTextKeys;
|
const NifOgre::TextKeyMap &textkeys = (*iter)->mTextKeys;
|
||||||
AnimState state;
|
|
||||||
if(reset(state, textkeys, groupname, start, stop, startpoint))
|
if(reset(state, textkeys, groupname, start, stop, startpoint))
|
||||||
{
|
{
|
||||||
state.mSource = *iter;
|
state.mSource = *iter;
|
||||||
@ -821,6 +821,13 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
|
|||||||
std::cerr<< "Failed to find animation "<<groupname<<" for "<<mPtr.getCellRef().getRefId() <<std::endl;
|
std::cerr<< "Failed to find animation "<<groupname<<" for "<<mPtr.getCellRef().getRefId() <<std::endl;
|
||||||
|
|
||||||
resetActiveGroups();
|
resetActiveGroups();
|
||||||
|
|
||||||
|
if (!state.mPlaying && mNonAccumCtrl)
|
||||||
|
{
|
||||||
|
// If the animation state is not playing, we need to manually apply the accumulation
|
||||||
|
// (see updatePosition, which would be called if the animation was playing)
|
||||||
|
mAccumRoot->setPosition(-mNonAccumCtrl->getTranslation(state.mTime)*mAccumulate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::isPlaying(const std::string &groupname) const
|
bool Animation::isPlaying(const std::string &groupname) const
|
||||||
|
@ -196,6 +196,45 @@ namespace MWScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpModFactionReaction : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string faction1 = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
std::string faction2 = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
int modReaction = runtime[0].mInteger;
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
MWBase::Environment::get().getDialogueManager()->modFactionReaction(faction1, faction2, modReaction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpGetFactionReaction : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string faction1 = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
std::string faction2 = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
// ignore extra garbage argument
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
runtime.push(MWBase::Environment::get().getDialogueManager()
|
||||||
|
->getFactionReaction(faction1, faction2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
@ -215,6 +254,8 @@ namespace MWScript
|
|||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetReputationExplicit, new OpGetReputation<ExplicitRef>);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetReputationExplicit, new OpGetReputation<ExplicitRef>);
|
||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFaction, new OpSameFaction<ImplicitRef>);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFaction, new OpSameFaction<ImplicitRef>);
|
||||||
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
|
||||||
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeModFactionReaction, new OpModFactionReaction);
|
||||||
|
interpreter.installSegment5 (Compiler::Dialogue::opcodeGetFactionReaction, new OpGetFactionReaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,5 +390,7 @@ op 0x200023e: GetPcInJail
|
|||||||
op 0x200023f: GetPcTraveling
|
op 0x200023f: GetPcTraveling
|
||||||
op 0x2000240: onKnockout
|
op 0x2000240: onKnockout
|
||||||
op 0x2000241: onKnockoutExplicit
|
op 0x2000241: onKnockoutExplicit
|
||||||
|
op 0x2000242: ModFactionReaction
|
||||||
|
op 0x2000243: GetFactionReaction
|
||||||
|
|
||||||
opcodes 0x2000242-0x3ffffff unused
|
opcodes 0x2000244-0x3ffffff unused
|
||||||
|
@ -541,6 +541,9 @@ namespace MWScript
|
|||||||
runtime.pop();
|
runtime.pop();
|
||||||
}
|
}
|
||||||
::Misc::StringUtils::toLower(factionID);
|
::Misc::StringUtils::toLower(factionID);
|
||||||
|
// Make sure this faction exists
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
|
||||||
|
|
||||||
if(factionID != "")
|
if(factionID != "")
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
@ -572,6 +575,9 @@ namespace MWScript
|
|||||||
runtime.pop();
|
runtime.pop();
|
||||||
}
|
}
|
||||||
::Misc::StringUtils::toLower(factionID);
|
::Misc::StringUtils::toLower(factionID);
|
||||||
|
// Make sure this faction exists
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
|
||||||
|
|
||||||
if(factionID != "")
|
if(factionID != "")
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
@ -607,6 +613,9 @@ namespace MWScript
|
|||||||
runtime.pop();
|
runtime.pop();
|
||||||
}
|
}
|
||||||
::Misc::StringUtils::toLower(factionID);
|
::Misc::StringUtils::toLower(factionID);
|
||||||
|
// Make sure this faction exists
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
|
||||||
|
|
||||||
if(factionID != "")
|
if(factionID != "")
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
@ -645,6 +654,9 @@ namespace MWScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
::Misc::StringUtils::toLower(factionID);
|
::Misc::StringUtils::toLower(factionID);
|
||||||
|
// Make sure this faction exists
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(factionID);
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
if(factionID!="")
|
if(factionID!="")
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ObjectState;
|
struct ObjectState;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
|
@ -33,12 +33,12 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
|
|||||||
// Cache parent esX files by tracking their indices in the global list of
|
// Cache parent esX files by tracking their indices in the global list of
|
||||||
// all files/readers used by the engine. This will greaty accelerate
|
// all files/readers used by the engine. This will greaty accelerate
|
||||||
// refnumber mangling, as required for handling moved references.
|
// refnumber mangling, as required for handling moved references.
|
||||||
int index = ~0;
|
|
||||||
const std::vector<ESM::Header::MasterData> &masters = esm.getGameFiles();
|
const std::vector<ESM::Header::MasterData> &masters = esm.getGameFiles();
|
||||||
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
|
std::vector<ESM::ESMReader> *allPlugins = esm.getGlobalReaderList();
|
||||||
for (size_t j = 0; j < masters.size(); j++) {
|
for (size_t j = 0; j < masters.size(); j++) {
|
||||||
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
|
ESM::Header::MasterData &mast = const_cast<ESM::Header::MasterData&>(masters[j]);
|
||||||
std::string fname = mast.name;
|
std::string fname = mast.name;
|
||||||
|
int index = ~0;
|
||||||
for (int i = 0; i < esm.getIndex(); i++) {
|
for (int i = 0; i < esm.getIndex(); i++) {
|
||||||
const std::string &candidate = allPlugins->at(i).getContext().filename;
|
const std::string &candidate = allPlugins->at(i).getContext().filename;
|
||||||
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
|
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
|
||||||
|
@ -492,7 +492,7 @@ namespace MWWorld
|
|||||||
return std::make_pair(true, ray.getPoint(len * test.second));
|
return std::make_pair(true, ray.getPoint(len * test.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY)
|
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal)
|
||||||
{
|
{
|
||||||
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
||||||
mouseX,
|
mouseX,
|
||||||
@ -504,7 +504,7 @@ namespace MWWorld
|
|||||||
_from = btVector3(from.x, from.y, from.z);
|
_from = btVector3(from.x, from.y, from.z);
|
||||||
_to = btVector3(to.x, to.y, to.z);
|
_to = btVector3(to.x, to.y, to.z);
|
||||||
|
|
||||||
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
|
std::pair<std::string, float> result = mEngine->rayTest(_from, _to, true, false, normal);
|
||||||
|
|
||||||
if (result.first == "")
|
if (result.first == "")
|
||||||
return std::make_pair(false, Ogre::Vector3());
|
return std::make_pair(false, Ogre::Vector3());
|
||||||
|
@ -70,8 +70,9 @@ namespace MWWorld
|
|||||||
std::pair<bool, Ogre::Vector3>
|
std::pair<bool, Ogre::Vector3>
|
||||||
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY);
|
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL);
|
||||||
///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates)
|
///< cast ray from the mouse, return true if it hit something and the first result
|
||||||
|
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
@ -1116,13 +1116,15 @@ namespace MWWorld
|
|||||||
while(ptr.getRefData().getLocalRotation().rot[2]<=-fullRotateRad)
|
while(ptr.getRefData().getLocalRotation().rot[2]<=-fullRotateRad)
|
||||||
ptr.getRefData().getLocalRotation().rot[2]+=fullRotateRad;
|
ptr.getRefData().getLocalRotation().rot[2]+=fullRotateRad;
|
||||||
|
|
||||||
Ogre::Quaternion worldRotQuat(Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X)*
|
Ogre::Quaternion worldRotQuat(Ogre::Radian(ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z);
|
||||||
Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::NEGATIVE_UNIT_Y)*
|
if (!ptr.getClass().isActor())
|
||||||
Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z));
|
worldRotQuat = Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X)*
|
||||||
|
Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::NEGATIVE_UNIT_Y)* worldRotQuat;
|
||||||
|
|
||||||
Ogre::Quaternion rot(Ogre::Quaternion(Ogre::Degree(x), Ogre::Vector3::NEGATIVE_UNIT_X)*
|
Ogre::Quaternion rot(Ogre::Degree(z), Ogre::Vector3::NEGATIVE_UNIT_Z);
|
||||||
Ogre::Quaternion(Ogre::Degree(y), Ogre::Vector3::NEGATIVE_UNIT_Y)*
|
if (!ptr.getClass().isActor())
|
||||||
Ogre::Quaternion(Ogre::Degree(z), Ogre::Vector3::NEGATIVE_UNIT_Z));
|
rot = Ogre::Quaternion(Ogre::Degree(x), Ogre::Vector3::NEGATIVE_UNIT_X)*
|
||||||
|
Ogre::Quaternion(Ogre::Degree(y), Ogre::Vector3::NEGATIVE_UNIT_Y)*rot;
|
||||||
|
|
||||||
ptr.getRefData().getBaseNode()->setOrientation(worldRotQuat*rot);
|
ptr.getRefData().getBaseNode()->setOrientation(worldRotQuat*rot);
|
||||||
mPhysics->rotateObject(ptr);
|
mPhysics->rotateObject(ptr);
|
||||||
@ -1618,25 +1620,39 @@ namespace MWWorld
|
|||||||
|
|
||||||
bool World::canPlaceObject(float cursorX, float cursorY)
|
bool World::canPlaceObject(float cursorX, float cursorY)
|
||||||
{
|
{
|
||||||
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
|
Ogre::Vector3 normal(0,0,0);
|
||||||
|
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal);
|
||||||
|
|
||||||
/// \todo also check if the wanted position is on a flat surface, and not e.g. against a vertical wall!
|
if (result.first)
|
||||||
|
{
|
||||||
if (!result.first)
|
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
||||||
|
return (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() < 30);
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ptr World::copyObjectToCell(const Ptr &object, CellStore* cell, ESM::Position pos, bool adjustPos)
|
Ptr World::copyObjectToCell(const Ptr &object, CellStore* cell, ESM::Position pos, bool adjustPos)
|
||||||
{
|
{
|
||||||
if (object.getClass().isActor() || adjustPos)
|
if (!object.getClass().isActor() && adjustPos)
|
||||||
{
|
{
|
||||||
|
// Adjust position so the location we wanted ends up in the middle of the object bounding box
|
||||||
Ogre::Vector3 min, max;
|
Ogre::Vector3 min, max;
|
||||||
if (mPhysics->getObjectAABB(object, min, max)) {
|
if (mPhysics->getObjectAABB(object, min, max)) {
|
||||||
pos.pos[0] -= (min.x + max.x) / 2;
|
Ogre::Quaternion xr(Ogre::Radian(-pos.rot[0]), Ogre::Vector3::UNIT_X);
|
||||||
pos.pos[1] -= (min.y + max.y) / 2;
|
Ogre::Quaternion yr(Ogre::Radian(-pos.rot[1]), Ogre::Vector3::UNIT_Y);
|
||||||
pos.pos[2] -= min.z;
|
Ogre::Quaternion zr(Ogre::Radian(-pos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
Ogre::Vector3 adjust (
|
||||||
|
(min.x + max.x) / 2,
|
||||||
|
(min.y + max.y) / 2,
|
||||||
|
min.z
|
||||||
|
);
|
||||||
|
adjust = (xr*yr*zr) * adjust;
|
||||||
|
pos.pos[0] -= adjust.x;
|
||||||
|
pos.pos[1] -= adjust.y;
|
||||||
|
pos.pos[2] -= adjust.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2526,7 +2542,7 @@ namespace MWWorld
|
|||||||
store.remove(*it, it->getRefData().getCount(), ptr);
|
store.remove(*it, it->getRefData().getCount(), ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closestChest.getClass().unlock(closestChest);
|
closestChest.getClass().lock(closestChest,50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ namespace Compiler
|
|||||||
else if (t1=='f' || t2=='f')
|
else if (t1=='f' || t2=='f')
|
||||||
mOperands.push_back ('f');
|
mOperands.push_back ('f');
|
||||||
else
|
else
|
||||||
std::logic_error ("failed to determine result operand type");
|
throw std::logic_error ("failed to determine result operand type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprParser::pop()
|
void ExprParser::pop()
|
||||||
@ -730,7 +730,7 @@ namespace Compiler
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner,
|
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner,
|
||||||
std::vector<Interpreter::Type_Code>& code, bool invert)
|
std::vector<Interpreter::Type_Code>& code)
|
||||||
{
|
{
|
||||||
bool optional = false;
|
bool optional = false;
|
||||||
int optionalCount = 0;
|
int optionalCount = 0;
|
||||||
@ -762,15 +762,10 @@ namespace Compiler
|
|||||||
|
|
||||||
if (*iter!='x')
|
if (*iter!='x')
|
||||||
{
|
{
|
||||||
if (invert)
|
std::vector<Interpreter::Type_Code> tmp;
|
||||||
{
|
stringParser.append (tmp);
|
||||||
std::vector<Interpreter::Type_Code> tmp;
|
|
||||||
stringParser.append (tmp);
|
|
||||||
|
|
||||||
stack.push (tmp);
|
stack.push (tmp);
|
||||||
}
|
|
||||||
else
|
|
||||||
stringParser.append (code);
|
|
||||||
|
|
||||||
if (optional)
|
if (optional)
|
||||||
++optionalCount;
|
++optionalCount;
|
||||||
@ -795,10 +790,7 @@ namespace Compiler
|
|||||||
if (type!=*iter)
|
if (type!=*iter)
|
||||||
Generator::convert (tmp, type, *iter);
|
Generator::convert (tmp, type, *iter);
|
||||||
|
|
||||||
if (invert)
|
stack.push (tmp);
|
||||||
stack.push (tmp);
|
|
||||||
else
|
|
||||||
std::copy (tmp.begin(), tmp.end(), std::back_inserter (code));
|
|
||||||
|
|
||||||
if (optional)
|
if (optional)
|
||||||
++optionalCount;
|
++optionalCount;
|
||||||
|
@ -96,7 +96,7 @@ namespace Compiler
|
|||||||
/// \return Type ('l': integer, 'f': float)
|
/// \return Type ('l': integer, 'f': float)
|
||||||
|
|
||||||
int parseArguments (const std::string& arguments, Scanner& scanner,
|
int parseArguments (const std::string& arguments, Scanner& scanner,
|
||||||
std::vector<Interpreter::Type_Code>& code, bool invert = false);
|
std::vector<Interpreter::Type_Code>& code);
|
||||||
///< Parse sequence of arguments specified by \a arguments.
|
///< Parse sequence of arguments specified by \a arguments.
|
||||||
/// \param arguments Uses ScriptArgs typedef
|
/// \param arguments Uses ScriptArgs typedef
|
||||||
/// \see Compiler::ScriptArgs
|
/// \see Compiler::ScriptArgs
|
||||||
|
@ -179,6 +179,8 @@ namespace Compiler
|
|||||||
opcodeGetReputationExplicit);
|
opcodeGetReputationExplicit);
|
||||||
extensions.registerFunction("samefaction", 'l', "", opcodeSameFaction,
|
extensions.registerFunction("samefaction", 'l', "", opcodeSameFaction,
|
||||||
opcodeSameFactionExplicit);
|
opcodeSameFactionExplicit);
|
||||||
|
extensions.registerInstruction("modfactionreaction", "ccl", opcodeModFactionReaction);
|
||||||
|
extensions.registerFunction("getfactionreaction", 'l', "ccl", opcodeGetFactionReaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ namespace Compiler
|
|||||||
if (!arguments.empty())
|
if (!arguments.empty())
|
||||||
{
|
{
|
||||||
mExprParser.reset();
|
mExprParser.reset();
|
||||||
mExprParser.parseArguments (arguments, scanner, mCode, true);
|
mExprParser.parseArguments (arguments, scanner, mCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
mName = name;
|
mName = name;
|
||||||
@ -278,7 +278,7 @@ namespace Compiler
|
|||||||
mExplicit.clear();
|
mExplicit.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int optionals = mExprParser.parseArguments (argumentType, scanner, mCode, true);
|
int optionals = mExprParser.parseArguments (argumentType, scanner, mCode);
|
||||||
|
|
||||||
extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals);
|
extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals);
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
@ -363,14 +363,14 @@ namespace Compiler
|
|||||||
|
|
||||||
case Scanner::K_startscript:
|
case Scanner::K_startscript:
|
||||||
|
|
||||||
mExprParser.parseArguments ("c", scanner, mCode, true);
|
mExprParser.parseArguments ("c", scanner, mCode);
|
||||||
Generator::startScript (mCode);
|
Generator::startScript (mCode);
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Scanner::K_stopscript:
|
case Scanner::K_stopscript:
|
||||||
|
|
||||||
mExprParser.parseArguments ("c", scanner, mCode, true);
|
mExprParser.parseArguments ("c", scanner, mCode);
|
||||||
Generator::stopScript (mCode);
|
Generator::stopScript (mCode);
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
return true;
|
||||||
|
@ -152,6 +152,8 @@ namespace Compiler
|
|||||||
const int opcodeGetReputationExplicit = 0x20001b2;
|
const int opcodeGetReputationExplicit = 0x20001b2;
|
||||||
const int opcodeSameFaction = 0x20001b5;
|
const int opcodeSameFaction = 0x20001b5;
|
||||||
const int opcodeSameFactionExplicit = 0x20001b6;
|
const int opcodeSameFactionExplicit = 0x20001b6;
|
||||||
|
const int opcodeModFactionReaction = 0x2000242;
|
||||||
|
const int opcodeGetFactionReaction = 0x2000243;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Gui
|
namespace Gui
|
||||||
|
@ -74,6 +74,9 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
|||||||
mActorId = -1;
|
mActorId = -1;
|
||||||
esm.getHNOT (mActorId, "ACID");
|
esm.getHNOT (mActorId, "ACID");
|
||||||
|
|
||||||
|
mDeathAnimation = 0;
|
||||||
|
esm.getHNOT (mDeathAnimation, "DANM");
|
||||||
|
|
||||||
mSpells.load(esm);
|
mSpells.load(esm);
|
||||||
mActiveSpells.load(esm);
|
mActiveSpells.load(esm);
|
||||||
}
|
}
|
||||||
@ -152,6 +155,9 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
|||||||
if (mActorId != -1)
|
if (mActorId != -1)
|
||||||
esm.writeHNT ("ACID", mActorId);
|
esm.writeHNT ("ACID", mActorId);
|
||||||
|
|
||||||
|
if (mDeathAnimation)
|
||||||
|
esm.writeHNT ("DANM", mDeathAnimation);
|
||||||
|
|
||||||
mSpells.save(esm);
|
mSpells.save(esm);
|
||||||
mActiveSpells.save(esm);
|
mActiveSpells.save(esm);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ namespace ESM
|
|||||||
std::string mLastHitObject;
|
std::string mLastHitObject;
|
||||||
bool mRecalcDynamicStats;
|
bool mRecalcDynamicStats;
|
||||||
int mDrawState;
|
int mDrawState;
|
||||||
|
unsigned char mDeathAnimation;
|
||||||
|
|
||||||
int mLevel;
|
int mLevel;
|
||||||
|
|
||||||
|
@ -8,6 +8,20 @@ void ESM::DialogueState::load (ESMReader &esm)
|
|||||||
{
|
{
|
||||||
while (esm.isNextSub ("TOPI"))
|
while (esm.isNextSub ("TOPI"))
|
||||||
mKnownTopics.push_back (esm.getHString());
|
mKnownTopics.push_back (esm.getHString());
|
||||||
|
|
||||||
|
while (esm.isNextSub ("FACT"))
|
||||||
|
{
|
||||||
|
std::string faction = esm.getHString();
|
||||||
|
|
||||||
|
while (esm.isNextSub ("REAC"))
|
||||||
|
{
|
||||||
|
std::string faction2 = esm.getHString();
|
||||||
|
int reaction;
|
||||||
|
esm.getHNT(reaction, "INTV");
|
||||||
|
|
||||||
|
mModFactionReaction[faction][faction2] = reaction;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::DialogueState::save (ESMWriter &esm) const
|
void ESM::DialogueState::save (ESMWriter &esm) const
|
||||||
@ -16,6 +30,18 @@ void ESM::DialogueState::save (ESMWriter &esm) const
|
|||||||
iter!=mKnownTopics.end(); ++iter)
|
iter!=mKnownTopics.end(); ++iter)
|
||||||
{
|
{
|
||||||
esm.writeHNString ("TOPI", *iter);
|
esm.writeHNString ("TOPI", *iter);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
for (std::map<std::string, std::map<std::string, int> >::const_iterator iter = mModFactionReaction.begin();
|
||||||
|
iter != mModFactionReaction.end(); ++iter)
|
||||||
|
{
|
||||||
|
esm.writeHNString ("FACT", iter->first);
|
||||||
|
|
||||||
|
for (std::map<std::string, int>::const_iterator reactIter = iter->second.begin();
|
||||||
|
reactIter != iter->second.end(); ++reactIter)
|
||||||
|
{
|
||||||
|
esm.writeHNString ("REAC", reactIter->first);
|
||||||
|
esm.writeHNT ("INTV", reactIter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
@ -15,9 +16,11 @@ namespace ESM
|
|||||||
{
|
{
|
||||||
std::vector<std::string> mKnownTopics;
|
std::vector<std::string> mKnownTopics;
|
||||||
|
|
||||||
|
std::map<std::string, std::map<std::string, int> > mModFactionReaction;
|
||||||
|
|
||||||
void load (ESMReader &esm);
|
void load (ESMReader &esm);
|
||||||
void save (ESMWriter &esm) const;
|
void save (ESMWriter &esm) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,10 +44,10 @@ void Faction::load(ESMReader &esm)
|
|||||||
// Read faction response values
|
// Read faction response values
|
||||||
while (esm.hasMoreSubs())
|
while (esm.hasMoreSubs())
|
||||||
{
|
{
|
||||||
Reaction r;
|
std::string faction = esm.getHNString("ANAM");
|
||||||
r.mFaction = esm.getHNString("ANAM");
|
int reaction;
|
||||||
esm.getHNT(r.mReaction, "INTV");
|
esm.getHNT(reaction, "INTV");
|
||||||
mReactions.push_back(r);
|
mReactions[faction] = reaction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Faction::save(ESMWriter &esm) const
|
void Faction::save(ESMWriter &esm) const
|
||||||
@ -64,10 +64,10 @@ void Faction::save(ESMWriter &esm) const
|
|||||||
|
|
||||||
esm.writeHNT("FADT", mData, 240);
|
esm.writeHNT("FADT", mData, 240);
|
||||||
|
|
||||||
for (std::vector<Reaction>::const_iterator it = mReactions.begin(); it != mReactions.end(); ++it)
|
for (std::map<std::string, int>::const_iterator it = mReactions.begin(); it != mReactions.end(); ++it)
|
||||||
{
|
{
|
||||||
esm.writeHNString("ANAM", it->mFaction);
|
esm.writeHNString("ANAM", it->first);
|
||||||
esm.writeHNT("INTV", it->mReaction);
|
esm.writeHNT("INTV", it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define OPENMW_ESM_FACT_H
|
#define OPENMW_ESM_FACT_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <map>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
@ -53,13 +53,8 @@ struct Faction
|
|||||||
|
|
||||||
FADTstruct mData;
|
FADTstruct mData;
|
||||||
|
|
||||||
struct Reaction
|
// <Faction ID, Reaction>
|
||||||
{
|
std::map<std::string, int> mReactions;
|
||||||
std::string mFaction;
|
|
||||||
int mReaction;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Reaction> mReactions;
|
|
||||||
|
|
||||||
// Name of faction ranks (may be empty for NPC factions)
|
// Name of faction ranks (may be empty for NPC factions)
|
||||||
std::string mRanks[10];
|
std::string mRanks[10];
|
||||||
|
@ -155,6 +155,7 @@ struct KeyListT {
|
|||||||
static const int sLinearInterpolation = 1;
|
static const int sLinearInterpolation = 1;
|
||||||
static const int sQuadraticInterpolation = 2;
|
static const int sQuadraticInterpolation = 2;
|
||||||
static const int sTBCInterpolation = 3;
|
static const int sTBCInterpolation = 3;
|
||||||
|
static const int sXYZInterpolation = 4;
|
||||||
|
|
||||||
int mInterpolationType;
|
int mInterpolationType;
|
||||||
VecType mKeys;
|
VecType mKeys;
|
||||||
@ -199,6 +200,38 @@ struct KeyListT {
|
|||||||
key.mContinuity = nif->getFloat();
|
key.mContinuity = nif->getFloat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//\FIXME This now reads the correct amount of data in the file, but doesn't actually do anything with it.
|
||||||
|
else if(mInterpolationType == sXYZInterpolation)
|
||||||
|
{
|
||||||
|
if (count != 1)
|
||||||
|
{
|
||||||
|
nif->file->fail("count should always be '1' for XYZ_ROTATION_KEY. Retrieved Value: "+Ogre::StringConverter::toString(count));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html)
|
||||||
|
//Chomp unknown and possibly unused float
|
||||||
|
nif->getFloat();
|
||||||
|
for(size_t i=0;i<3;++i)
|
||||||
|
{
|
||||||
|
unsigned int numKeys = nif->getInt();
|
||||||
|
if(numKeys != 0)
|
||||||
|
{
|
||||||
|
int interpolationTypeAgain = nif->getInt();
|
||||||
|
if( interpolationTypeAgain != sLinearInterpolation)
|
||||||
|
{
|
||||||
|
nif->file->fail("XYZ_ROTATION_KEY's KeyGroup keyType must be '1' (Linear Interpolation). Retrieved Value: "+Ogre::StringConverter::toString(interpolationTypeAgain));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(size_t j = 0;j < numKeys;j++)
|
||||||
|
{
|
||||||
|
//For now just chomp these
|
||||||
|
nif->getFloat();
|
||||||
|
nif->getFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nif->file->warn("XYZ_ROTATION_KEY read, but not used!");
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (mInterpolationType == 0)
|
else if (mInterpolationType == 0)
|
||||||
{
|
{
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
|
@ -17,6 +17,7 @@ Alex McKibben (WeirdSexy)
|
|||||||
Alexander Nadeau (wareya)
|
Alexander Nadeau (wareya)
|
||||||
Alexander Olofsson (Ace)
|
Alexander Olofsson (Ace)
|
||||||
Artem Kotsynyak (greye)
|
Artem Kotsynyak (greye)
|
||||||
|
Arthur Moore (EmperorArthur)
|
||||||
athile
|
athile
|
||||||
Britt Mathis (galdor557)
|
Britt Mathis (galdor557)
|
||||||
BrotherBrick
|
BrotherBrick
|
||||||
|
2
extern/shiny/Main/Factory.hpp
vendored
2
extern/shiny/Main/Factory.hpp
vendored
@ -206,7 +206,7 @@ namespace sh
|
|||||||
|
|
||||||
std::string getCacheFolder () { return mPlatform->getCacheFolder (); }
|
std::string getCacheFolder () { return mPlatform->getCacheFolder (); }
|
||||||
bool getReadSourceCache() { return mReadSourceCache; }
|
bool getReadSourceCache() { return mReadSourceCache; }
|
||||||
bool getWriteSourceCache() { return mReadSourceCache; }
|
bool getWriteSourceCache() { return mWriteSourceCache; }
|
||||||
public:
|
public:
|
||||||
bool getWriteMicrocodeCache() { return mWriteMicrocodeCache; } // Fixme
|
bool getWriteMicrocodeCache() { return mWriteMicrocodeCache; } // Fixme
|
||||||
|
|
||||||
|
@ -677,7 +677,7 @@ namespace Physic
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap)
|
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap, Ogre::Vector3* normal)
|
||||||
{
|
{
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
float d = -1;
|
float d = -1;
|
||||||
@ -694,7 +694,11 @@ namespace Physic
|
|||||||
if (resultCallback1.hasHit())
|
if (resultCallback1.hasHit())
|
||||||
{
|
{
|
||||||
name = static_cast<const RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
name = static_cast<const RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
||||||
d = resultCallback1.m_closestHitFraction;;
|
d = resultCallback1.m_closestHitFraction;
|
||||||
|
if (normal)
|
||||||
|
*normal = Ogre::Vector3(resultCallback1.m_hitNormalWorld.x(),
|
||||||
|
resultCallback1.m_hitNormalWorld.y(),
|
||||||
|
resultCallback1.m_hitNormalWorld.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::pair<std::string,float>(name,d);
|
return std::pair<std::string,float>(name,d);
|
||||||
|
@ -308,8 +308,10 @@ namespace Physic
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
|
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
|
||||||
|
* If \a normal is non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
*/
|
*/
|
||||||
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
|
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,
|
||||||
|
bool ignoreHeightMap = false, Ogre::Vector3* normal = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all objects hit by a ray.
|
* Return all objects hit by a ray.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user