Merge remote-tracking branch 'scrawl/master'

deque
Marc Zinnschlag 11 years ago
commit 7991dfb907

@ -319,6 +319,8 @@ int main(int argc, char**argv)
boost::filesystem::ofstream logfile;
std::auto_ptr<OMW::Engine> engine;
int ret = 0;
try
{
@ -360,11 +362,11 @@ int main(int argc, char**argv)
boost::filesystem::current_path(bundlePath);
#endif
OMW::Engine engine(cfgMgr);
engine.reset(new OMW::Engine(cfgMgr));
if (parseOptions(argc, argv, engine, cfgMgr))
if (parseOptions(argc, argv, *engine, cfgMgr))
{
engine.go();
engine->go();
}
}
catch (std::exception &e)

@ -366,10 +366,17 @@ namespace MWClass
getCreatureStats(ptr).setAttacked(true);
// Self defense
if (!attacker.isEmpty() && !MWBase::Environment::get().getMechanicsManager()->isAggressive(ptr, attacker)
&& (canWalk(ptr) || canFly(ptr) || canSwim(ptr))) // No retaliation for totally static creatures
// (they have no movement or attacks anyway)
if ( ((!attacker.isEmpty() && attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr))
|| attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
&& (canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
// (they have no movement or attacks anyway)
)
{
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored.
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
}
if(!successful)
{

@ -396,6 +396,31 @@ namespace MWGui
mLinks.clear();
updateOptions();
restock();
}
void DialogueWindow::restock()
{
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getFloat();
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay)
{
sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr));
mPtr.getClass().restock(mPtr);
// Also restock any containers owned by this merchant, which are also available to buy in the trade window
std::vector<MWWorld::Ptr> itemSources;
MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources);
for (std::vector<MWWorld::Ptr>::iterator it = itemSources.begin(); it != itemSources.end(); ++it)
{
it->getClass().restock(*it);
}
sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp());
}
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)

@ -152,6 +152,7 @@ namespace MWGui
private:
void updateOptions();
void restock();
int mServices;

@ -144,9 +144,14 @@ namespace MWGui
mEnchanting.setSelfEnchanting(false);
mEnchanting.setEnchanter(actor);
mBuyButton->setCaptionWithReplacing("#{sBuy}");
mPtr = actor;
startEditing ();
mPrice->setVisible(true);
mPriceText->setVisible(true);
updateLabels();
}
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
@ -156,9 +161,10 @@ namespace MWGui
mEnchanting.setSelfEnchanting(true);
mEnchanting.setEnchanter(player);
mBuyButton->setCaptionWithReplacing("#{sCreate}");
mPtr = player;
startEditing();
mEnchanting.setSoulGem(soulgem);
setSoulGem(soulgem);
@ -299,7 +305,7 @@ namespace MWGui
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
if (mEnchanting.getEnchantPrice() > playerGold)
if (mPtr != player && mEnchanting.getEnchantPrice() > playerGold)
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}");
return;

@ -115,7 +115,13 @@ void ItemView::update()
}
x += 42;
MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mScrollView->setVisibleVScroll(false);
mScrollView->setVisibleHScroll(false);
mScrollView->setCanvasSize(size);
mScrollView->setVisibleVScroll(true);
mScrollView->setVisibleHScroll(true);
dragArea->setSize(size);
}

@ -400,7 +400,10 @@ namespace
getPage (pageId)->showPage (book, 0);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
getWidget <MyGUI::ScrollView> (listId)->setVisibleVScroll(false);
getWidget <MyGUI::ScrollView> (listId)->setCanvasSize (size.first, size.second);
getWidget <MyGUI::ScrollView> (listId)->setVisibleVScroll(true);
}
void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId character)

@ -93,7 +93,11 @@ namespace MWGui
}
++i;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mScrollView->setVisibleVScroll(false);
mScrollView->setCanvasSize(mClient->getSize().width, std::max(mItemHeight, mClient->getSize().height));
mScrollView->setVisibleVScroll(true);
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
redraw(true);

@ -10,6 +10,8 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
@ -91,7 +93,10 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick);
}
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mList->setVisibleVScroll(false);
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
mList->setVisibleVScroll(true);
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
+ boost::lexical_cast<std::string>(playerGold));
@ -131,6 +136,10 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
// add gold to NPC trading gold pool
MWMechanics::CreatureStats& actorStats = mActor.getClass().getCreatureStats(mActor);
actorStats.setGoldPool(actorStats.getGoldPool() + price);
startRepair(mActor);
}

@ -654,9 +654,10 @@ namespace MWGui
mHeight += spellHeight;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mMagicList->setVisibleVScroll(false);
mMagicList->setCanvasSize (mWidth, std::max(mMagicList->getHeight(), mHeight));
mMagicList->setVisibleVScroll(true);
}
void MagicSelectionDialog::addGroup(const std::string &label, const std::string& label2)

@ -119,7 +119,11 @@ void Recharge::updateView()
currentY += 32 + 4;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mView->setVisibleVScroll(false);
mView->setCanvasSize (MyGUI::IntSize(mView->getWidth(), std::max(mView->getHeight(), currentY)));
mView->setVisibleVScroll(true);
}
void Recharge::onCancel(MyGUI::Widget *sender)

@ -126,7 +126,10 @@ void Repair::updateRepairView()
currentY += 32 + 4;
}
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mRepairView->setVisibleVScroll(false);
mRepairView->setCanvasSize (MyGUI::IntSize(mRepairView->getWidth(), std::max(mRepairView->getHeight(), currentY)));
mRepairView->setVisibleVScroll(true);
}
void Repair::onCancel(MyGUI::Widget *sender)

@ -320,7 +320,10 @@ namespace MWGui
if (!mMiscSkills.empty())
addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSkillView->setVisibleVScroll(false);
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top));
mSkillView->setVisibleVScroll(true);
}
// widget controls

@ -57,10 +57,13 @@ namespace MWGui
BookTextParser parser;
MyGUI::IntSize size = parser.parseScroll(ref->mBase->mText, mTextView, 390);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mTextView->setVisibleVScroll(false);
if (size.height > mTextView->getSize().height)
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
else
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setVisibleVScroll(true);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));

@ -473,7 +473,10 @@ namespace MWGui
curH += h;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mControlsBox->setVisibleVScroll(false);
mControlsBox->setCanvasSize (mControlsBox->getWidth(), std::max(curH, mControlsBox->getHeight()));
mControlsBox->setVisibleVScroll(true);
}
void SettingsWindow::onRebindAction(MyGUI::Widget* _sender)

@ -50,6 +50,8 @@ namespace MWGui
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);
// TODO: refactor to use MyGUI::ListBox
MyGUI::Button* toAdd =
mSpellsView->createWidget<MyGUI::Button>(
"SandTextButton",
@ -106,7 +108,10 @@ namespace MWGui
updateLabels();
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSpellsView->setVisibleVScroll(false);
mSpellsView->setCanvasSize (MyGUI::IntSize(mSpellsView->getWidth(), std::max(mSpellsView->getHeight(), mCurrentY)));
mSpellsView->setVisibleVScroll(true);
}
bool SpellBuyingWindow::playerHasSpell(const std::string &id)
@ -130,6 +135,11 @@ namespace MWGui
MWMechanics::Spells& spells = stats.getSpells();
spells.add (mSpellsWidgetMap.find(_sender)->second);
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
// add gold to NPC trading gold pool
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
npcStats.setGoldPool(npcStats.getGoldPool() + price);
startSpellBuying(mPtr);
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);

@ -352,7 +352,13 @@ namespace MWGui
mSpell.mName = mNameEdit->getCaption();
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, boost::lexical_cast<int>(mPriceLabel->getCaption()), player);
int price = boost::lexical_cast<int>(mPriceLabel->getCaption());
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
// add gold to NPC trading gold pool
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
npcStats.setGoldPool(npcStats.getGoldPool() + price);
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
@ -637,7 +643,10 @@ namespace MWGui
++i;
}
// Canvas size must be expressed with HScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mUsedEffectsView->setVisibleHScroll(false);
mUsedEffectsView->setCanvasSize(size);
mUsedEffectsView->setVisibleHScroll(true);
notifyEffectsChanged();
}

@ -261,7 +261,10 @@ namespace MWGui
mHeight += spellHeight;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSpellView->setVisibleVScroll(false);
mSpellView->setCanvasSize(mSpellView->getWidth(), std::max(mSpellView->getHeight(), mHeight));
mSpellView->setVisibleVScroll(true);
}
void SpellWindow::addGroup(const std::string &label, const std::string& label2)

@ -82,7 +82,10 @@ namespace MWGui
{
mLeftPane->setCoord( MyGUI::IntCoord(0, 0, 0.44*window->getSize().width, window->getSize().height) );
mRightPane->setCoord( MyGUI::IntCoord(0.44*window->getSize().width, 0, 0.56*window->getSize().width, window->getSize().height) );
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSkillView->setVisibleVScroll(false);
mSkillView->setCanvasSize (mSkillView->getWidth(), mSkillView->getCanvasSize().height);
mSkillView->setVisibleVScroll(true);
}
void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max)
@ -578,7 +581,10 @@ namespace MWGui
mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}");
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mSkillView->setVisibleVScroll(false);
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top));
mSkillView->setVisibleVScroll(true);
}
void StatsWindow::onPinToggled()

@ -99,8 +99,6 @@ namespace MWGui
mCurrentBalance = 0;
mCurrentMerchantOffer = 0;
restock();
std::vector<MWWorld::Ptr> itemSources;
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
@ -509,29 +507,6 @@ namespace MWGui
return merchantGold;
}
void TradeWindow::restock()
{
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getFloat();
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay)
{
sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr));
mPtr.getClass().restock(mPtr);
// Also restock any containers owned by this merchant, which are also available to buy in the trade window
std::vector<MWWorld::Ptr> itemSources;
MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources);
for (std::vector<MWWorld::Ptr>::iterator it = itemSources.begin(); it != itemSources.end(); ++it)
{
it->getClass().restock(*it);
}
sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp());
}
}
void TradeWindow::resetReference()
{
ReferenceInterface::resetReference();

@ -104,8 +104,6 @@ namespace MWGui
virtual void onReferenceUnavailable();
int getMerchantGold();
void restock();
};
}

@ -159,6 +159,9 @@ namespace MWGui
// remove gold
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
// add gold to NPC trading gold pool
npcStats.setGoldPool(npcStats.getGoldPool() + price);
// go back to game mode
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Dialogue);

@ -12,6 +12,8 @@
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/actionteleport.hpp"
@ -126,7 +128,10 @@ namespace MWGui
}
updateLabels();
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mDestinationsView->setVisibleVScroll(false);
mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY)));
mDestinationsView->setVisibleVScroll(true);
}
void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender)
@ -147,6 +152,10 @@ namespace MWGui
player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player);
// add gold to NPC trading gold pool
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
npcStats.setGoldPool(npcStats.getGoldPool() + price);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
ESM::Position pos = *_sender->getUserData<ESM::Position>();
std::string cellname = _sender->getUserString("Destination");

@ -192,6 +192,15 @@ namespace MWMechanics
CreatureStats& creatureStats = actor1.getClass().getCreatureStats(actor1);
if (againstPlayer && creatureStats.isHostile()) return; // already fighting against player
if (actor2.getClass().getCreatureStats(actor2).isDead()
|| actor1.getClass().getCreatureStats(actor1).isDead())
return;
const ESM::Position& actor1Pos = actor2.getRefData().getPosition();
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
float sqrDist = Ogre::Vector3(actor1Pos.pos).squaredDistance(Ogre::Vector3(actor2Pos.pos));
if (sqrDist > 7168*7168)
return;
// pure water creatures won't try to fight with the target on the ground
// except that creature is already hostile
@ -208,9 +217,9 @@ namespace MWMechanics
else
{
aggressive = false;
// if one of actors is creature then we should make a decision to start combat or not
// NOTE: function doesn't take into account combat between 2 creatures
if (!actor1.getClass().isNpc())
// Make guards fight aggressive creatures
if (!actor1.getClass().isNpc() && actor2.getClass().isClass(actor2, "Guard"))
{
// if creature is hostile then it is necessarily to start combat
if (creatureStats.isHostile()) aggressive = true;
@ -218,24 +227,34 @@ namespace MWMechanics
}
}
// start combat if we are in combat with any followers of this actor
const std::list<MWWorld::Ptr>& followers = getActorsFollowing(actor2);
for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it)
{
if (creatureStats.getAiSequence().isInCombat(*it))
aggressive = true;
}
// start combat if we are in combat with someone this actor is following
const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats2.getAiSequence().begin(); it != creatureStats2.getAiSequence().end(); ++it)
{
if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdFollow &&
creatureStats.getAiSequence().isInCombat(dynamic_cast<MWMechanics::AiFollow*>(*it)->getTarget()))
aggressive = true;
}
if(aggressive)
{
const ESM::Position& actor1Pos = actor2.getRefData().getPosition();
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
float d = Ogre::Vector3(actor1Pos.pos).distance(Ogre::Vector3(actor2Pos.pos));
if (againstPlayer || actor2.getClass().getCreatureStats(actor2).getAiSequence().canAddTarget(actor2Pos, d))
{
bool LOS = MWBase::Environment::get().getWorld()->getLOS(actor1, actor2);
bool LOS = MWBase::Environment::get().getWorld()->getLOS(actor1, actor2);
if (againstPlayer) LOS &= MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor2, actor1);
if (againstPlayer) LOS &= MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor2, actor1);
if (LOS)
if (LOS)
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
if (!againstPlayer) // start combat between each other
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
if (!againstPlayer) // start combat between each other
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor2, actor1);
}
MWBase::Environment::get().getMechanicsManager()->startCombat(actor2, actor1);
}
}
}
@ -905,12 +924,7 @@ namespace MWMechanics
Actors::~Actors()
{
PtrControllerMap::iterator it(mActors.begin());
for (; it != mActors.end(); ++it)
{
delete it->second;
it->second = NULL;
}
clear();
}
void Actors::addActor (const MWWorld::Ptr& ptr, bool updateImmediately)
@ -964,19 +978,10 @@ namespace MWMechanics
}
}
static Ogre::Vector3 sBasePoint;
bool comparePtrDist (const MWWorld::Ptr& ptr1, const MWWorld::Ptr& ptr2)
{
return (sBasePoint.squaredDistance(Ogre::Vector3(ptr1.getRefData().getPosition().pos))
< sBasePoint.squaredDistance(Ogre::Vector3(ptr2.getRefData().getPosition().pos)));
}
void Actors::update (float duration, bool paused)
{
if(!paused)
{
std::list<MWWorld::Ptr> listGuards; // at the moment only guards certainly will fight with creatures
{
static float timerUpdateAITargets = 0;
// target lists get updated once every 1.0 sec
@ -989,16 +994,10 @@ namespace MWMechanics
// Note, the new hit object for this frame may be set by CharacterController::update -> Animation::runAnimation
// (below)
iter->first.getClass().getCreatureStats(iter->first).setLastHitObject(std::string());
// add guards to list to later make them fight with creatures
if (timerUpdateAITargets == 0 && iter->first.getClass().isClass(iter->first, "Guard"))
listGuards.push_back(iter->first);
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
listGuards.push_back(player);
// AI and magic effects update
for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{
@ -1008,20 +1007,16 @@ namespace MWMechanics
if (MWBase::Environment::get().getMechanicsManager()->isAIActive())
{
// make guards and creatures fight each other
if (timerUpdateAITargets == 0 && iter->first.getTypeName() == typeid(ESM::Creature).name() && !listGuards.empty())
{
sBasePoint = Ogre::Vector3(iter->first.getRefData().getPosition().pos);
listGuards.sort(comparePtrDist); // try to engage combat starting from the nearest guard
for (std::list<MWWorld::Ptr>::iterator it = listGuards.begin(); it != listGuards.end(); ++it)
if (timerUpdateAITargets == 0)
{
for(PtrControllerMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
{
engageCombat(iter->first, *it, *it == player);
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
continue;
engageCombat(iter->first, it->first, it->first == player);
}
}
if (iter->first != player) engageCombat(iter->first, player, true);
if (iter->first.getClass().isNpc() && iter->first != player)
updateCrimePersuit(iter->first, duration);
@ -1359,6 +1354,13 @@ namespace MWMechanics
void Actors::clear()
{
PtrControllerMap::iterator it(mActors.begin());
for (; it != mActors.end(); ++it)
{
delete it->second;
it->second = NULL;
}
mActors.clear();
mDeathCount.clear();
}
}

@ -174,6 +174,8 @@ namespace MWMechanics
return true;
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId);
if (target.isEmpty())
return false;
if(target.getClass().getCreatureStats(target).isDead())
return true;

@ -121,3 +121,8 @@ MWMechanics::AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow)
{
}
MWWorld::Ptr MWMechanics::AiFollow::getTarget() const
{
return MWBase::Environment::get().getWorld()->searchPtr(mActorId, false);
}

@ -31,6 +31,8 @@ namespace MWMechanics
AiFollow(const ESM::AiSequence::AiFollow* follow);
MWWorld::Ptr getTarget() const;
virtual AiFollow *clone() const;
virtual bool execute (const MWWorld::Ptr& actor,float duration);

@ -72,6 +72,16 @@ bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const
return true;
}
std::list<AiPackage*>::const_iterator AiSequence::begin() const
{
return mPackages.begin();
}
std::list<AiPackage*>::const_iterator AiSequence::end() const
{
return mPackages.end();
}
bool AiSequence::isInCombat() const
{
for(std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it)

@ -50,6 +50,10 @@ namespace MWMechanics
virtual ~AiSequence();
/// Iterator may be invalidated by any function calls other than begin() or end().
std::list<AiPackage*>::const_iterator begin() const;
std::list<AiPackage*>::const_iterator end() const;
/// Returns currently executing AiPackage type
/** \see enum AiPackage::TypeId **/
int getTypeId() const;

@ -181,7 +181,13 @@ void MWMechanics::Alchemy::updateEffects()
ESM::ENAMstruct effect;
effect.mEffectID = iter->mId;
effect.mSkill = effect.mAttribute = iter->mArg; // somewhat hack-ish, but should work
effect.mAttribute = -1;
effect.mSkill = -1;
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
effect.mSkill = iter->mArg;
else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
effect.mAttribute = iter->mArg;
effect.mRange = 0;
effect.mArea = 0;

@ -62,7 +62,7 @@ namespace MWMechanics
if(mSelfEnchanting)
{
if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
if(std::rand()/static_cast<double> (RAND_MAX)*100 < getEnchantChance())
return false;
mEnchanter.getClass().skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 2);
@ -292,5 +292,9 @@ namespace MWMechanics
MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
store.remove(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), player);
// add gold to NPC trading gold pool
CreatureStats& enchanterStats = mEnchanter.getClass().getCreatureStats(mEnchanter);
enchanterStats.setGoldPool(enchanterStats.getGoldPool() + getEnchantPrice());
}
}

@ -1171,6 +1171,8 @@ namespace MWMechanics
void MechanicsManager::startCombat(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target)
{
if (ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(target))
return;
ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(MWMechanics::AiCombat(target), ptr);
if (target == MWBase::Environment::get().getWorld()->getPlayerPtr())
{

@ -287,6 +287,27 @@ namespace MWMechanics
bool castByPlayer = (!caster.isEmpty() && caster.getRefData().getHandle() == "player");
// Try absorbing if it's a spell
// NOTE: Vanilla does this once per effect source instead of adding the % from all sources together, not sure
// if that is worth replicating.
bool absorbed = false;
if (spell && caster != target && target.getClass().isActor())
{
int absorb = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::SpellAbsorption).mMagnitude;
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
absorbed = (roll < absorb);
if (absorbed)
{
const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Absorb");
MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect(
"meshes\\" + absorbStatic->mModel, ESM::MagicEffect::SpellAbsorption, false, "");
// Magicka is increased by cost of spell
DynamicStat<float> magicka = target.getClass().getCreatureStats(target).getMagicka();
magicka.setCurrent(magicka.getCurrent() + spell->mData.mCost);
target.getClass().getCreatureStats(target).setMagicka(magicka);
}
}
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (effects.mList.begin());
effectIt!=effects.mList.end(); ++effectIt)
{
@ -326,31 +347,13 @@ namespace MWMechanics
{
anyHarmfulEffect = true;
if (absorbed) // Absorbed, and we know there was a harmful effect (figuring that out is the only reason we are in this loop)
break;
// If player is attempting to cast a harmful spell, show the target's HP bar
if (castByPlayer && target != caster)
MWBase::Environment::get().getWindowManager()->setEnemy(target);
// Try absorbing if it's a spell
// NOTE: Vanilla does this once per effect source instead of adding the % from all sources together, not sure
// if that is worth replicating.
if (spell && caster != target)
{
int absorb = target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::SpellAbsorption).mMagnitude;
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
bool isAbsorbed = (roll < absorb);
if (isAbsorbed)
{
const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Absorb");
MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect(
"meshes\\" + absorbStatic->mModel, ESM::MagicEffect::Reflect, false, "");
// Magicka is increased by cost of spell
DynamicStat<float> magicka = target.getClass().getCreatureStats(target).getMagicka();
magicka.setCurrent(magicka.getCurrent() + spell->mData.mCost);
target.getClass().getCreatureStats(target).setMagicka(magicka);
magnitudeMult = 0;
}
}
// Try reflecting
if (!reflected && magnitudeMult > 0 && !caster.isEmpty() && caster != target && !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable))
{
@ -382,8 +385,7 @@ namespace MWMechanics
}
}
if (magnitudeMult > 0)
if (magnitudeMult > 0 && !absorbed)
{
float random = std::rand() / static_cast<float>(RAND_MAX);
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;

@ -72,12 +72,6 @@ namespace MWWorld
public:
/// NPC-stances.
enum Stance
{
Run, Sneak
};
virtual ~Class();
const std::string& getTypeName() const {

@ -148,7 +148,7 @@ namespace MWWorld
mSky (true), mCells (mStore, mEsm),
mActivationDistanceOverride (activationDistanceOverride),
mFallback(fallbackMap), mTeleportEnabled(true), mLevitationEnabled(true),
mFacedDistance(FLT_MAX), mGodMode(false), mContentFiles (contentFiles),
mGodMode(false), mContentFiles (contentFiles),
mGoToJail(false),
mStartCell (startCell), mStartupScript(startupScript)
{
@ -290,7 +290,6 @@ namespace MWWorld
mGodMode = false;
mSky = true;
mTeleportEnabled = true;
mFacedDistance = FLT_MAX;
mGlobalVariables.fill (mStore);
}
@ -320,8 +319,9 @@ namespace MWWorld
MWMechanics::CreatureStats::writeActorIdCounter(writer);
progress.increaseProgress();
mStore.write (writer, progress); // dynamic Store must be written (and read) before Cells, so that
// references to custom made records will be recognized
mCells.write (writer, progress);
mStore.write (writer, progress);
mGlobalVariables.write (writer, progress);
mPlayer->write (writer, progress);
mWeatherManager->write (writer, progress);
@ -1462,30 +1462,22 @@ namespace MWWorld
updateFacedHandle ();
}
void World::updateFacedHandle ()
void World::getFacedHandle(std::string& facedHandle, float maxDistance)
{
float telekinesisRangeBonus =
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects()
.get(ESM::MagicEffect::Telekinesis).mMagnitude;
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);
maxDistance += mRendering->getCameraDistance();
float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus;
activationDistance += mRendering->getCameraDistance();
// send new query
// figure out which object we want to test against
std::vector < std::pair < float, std::string > > results;
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{
float x, y;
MWBase::Environment::get().getWindowManager()->getMousePosition(x, y);
results = mPhysics->getFacedHandles(x, y, activationDistance);
results = mPhysics->getFacedHandles(x, y, maxDistance);
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
results = mPhysics->getFacedHandles(x, y, getMaxActivationDistance ()*50);
}
else
{
results = mPhysics->getFacedHandles(activationDistance);
results = mPhysics->getFacedHandles(maxDistance);
}
// ignore the player and other things we're not interested in
@ -1508,15 +1500,21 @@ namespace MWWorld
if (results.empty()
|| results.front().second.find("HeightField") != std::string::npos) // Blocked by terrain
{
mFacedHandle = "";
mFacedDistance = FLT_MAX;
}
facedHandle = "";
else
{
mFacedHandle = results.front().second;
mFacedDistance = results.front().first;
}
facedHandle = results.front().second;
}
void World::updateFacedHandle ()
{
float telekinesisRangeBonus =
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects()
.get(ESM::MagicEffect::Telekinesis).mMagnitude;
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);
float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus;
getFacedHandle(mFacedHandle, activationDistance);
}
bool World::isCellExterior() const
@ -2114,8 +2112,8 @@ namespace MWWorld
void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable)
{
OEngine::Physic::PhysicActor *physicActor = mPhysEngine->getCharacter(actor.getRefData().getHandle());
physicActor->enableCollisionBody(enable);
if (physicActor)
physicActor->enableCollisionBody(enable);
}
bool World::findInteriorPosition(const std::string &name, ESM::Position &pos)
@ -2344,8 +2342,49 @@ namespace MWWorld
{
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
// TODO: this only works for the player
MWWorld::Ptr target = getFacedObject();
// Get the target to use for "on touch" effects
MWWorld::Ptr target;
float distance = 192.f; // ??
if (actor == getPlayerPtr())
{
// For the player, use camera to aim
std::string facedHandle;
getFacedHandle(facedHandle, distance);
if (!facedHandle.empty())
target = getPtrViaHandle(facedHandle);
}
else
{
// For NPCs use facing direction from Head node
Ogre::Vector3 origin(actor.getRefData().getPosition().pos);
MWRender::Animation *anim = mRendering->getAnimation(actor);
if(anim != NULL)
{
Ogre::Node *node = anim->getNode("Head");
if (node == NULL)
node = anim->getNode("Bip01 Head");
if(node != NULL)
origin += node->_getDerivedPosition();
}
Ogre::Quaternion orient;
orient = Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
Ogre::Vector3 direction = orient.yAxis();
Ogre::Vector3 dest = origin + direction * distance;
std::vector<std::pair<float, std::string> > collisions = mPhysEngine->rayTest2(btVector3(origin.x, origin.y, origin.z), btVector3(dest.x, dest.y, dest.z));
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end(); ++cIt)
{
MWWorld::Ptr collided = getPtrViaHandle(cIt->second);
if (collided != actor)
{
target = collided;
break;
}
}
}
std::string selectedSpell = stats.getSpells().getSelectedSpell();

@ -92,7 +92,6 @@ namespace MWWorld
int mActivationDistanceOverride;
std::string mFacedHandle;
float mFacedDistance;
std::string mStartupScript;
@ -114,6 +113,7 @@ namespace MWWorld
void updateWindowManager ();
void performUpdateSceneQueries ();
void updateFacedHandle ();
void getFacedHandle(std::string& facedHandle, float maxDistance);
float getMaxActivationDistance ();
float getNpcActivationDistance ();

@ -4,7 +4,7 @@
#include "esmreader.hpp"
#include "esmwriter.hpp"
ESM::NpcStats::Faction::Faction() : mExpelled (false), mRank (0), mReputation (0) {}
ESM::NpcStats::Faction::Faction() : mExpelled (false), mRank (-1), mReputation (0) {}
void ESM::NpcStats::load (ESMReader &esm)
{
@ -98,7 +98,7 @@ void ESM::NpcStats::save (ESMWriter &esm) const
esm.writeHNT ("FAEX", expelled);
}
if (iter->second.mRank)
if (iter->second.mRank >= 0)
esm.writeHNT ("FARA", iter->second.mRank);
if (iter->second.mReputation)

@ -51,24 +51,32 @@ namespace sh
{
assert(mCurrentLanguage != Language_None);
if (boost::filesystem::exists (mPlatform->getCacheFolder () + "/lastModified.txt"))
try
{
std::ifstream file;
file.open(std::string(mPlatform->getCacheFolder () + "/lastModified.txt").c_str());
std::string line;
while (getline(file, line))
if (boost::filesystem::exists (mPlatform->getCacheFolder () + "/lastModified.txt"))
{
std::string sourceFile = line;
std::ifstream file;
file.open(std::string(mPlatform->getCacheFolder () + "/lastModified.txt").c_str());
std::string line;
while (getline(file, line))
{
std::string sourceFile = line;
if (!getline(file, line))
assert(0);
if (!getline(file, line))
assert(0);
int modified = boost::lexical_cast<int>(line);
int modified = boost::lexical_cast<int>(line);
mShadersLastModified[sourceFile] = modified;
mShadersLastModified[sourceFile] = modified;
}
}
}
catch (std::exception& e)
{
std::cerr << "Failed to load shader modification index: " << e.what() << std::endl;
mShadersLastModified.clear();
}
// load configurations
{

@ -33,7 +33,7 @@
SH_START_PROGRAM
{
shOutputColour(0) = alphaFade * atmosphereColour + (1.f - alphaFade) * horizonColour;
shOutputColour(0) = alphaFade * atmosphereColour + (1.0 - alphaFade) * horizonColour;
}
#endif

@ -25,7 +25,7 @@
shOutputPosition = shMatrixMult(proj, shMatrixMult(worldviewFixed, shInputPosition));
UV = uv0;
alphaFade = (shInputPosition.z <= 200.f) ? ((shInputPosition.z <= 100.f) ? 0.0 : 0.25) : 1.0;
alphaFade = (shInputPosition.z <= 200.0) ? ((shInputPosition.z <= 100.0) ? 0.0 : 0.25) : 1.0;
}
#else

@ -14,7 +14,7 @@
SH_START_PROGRAM
{
shOutputPosition = float4(shInputPosition.xyz, 1.f);
shOutputPosition = float4(shInputPosition.xyz, 1.0);
#if TEXTURE
UV.xy = uv0;
#endif

@ -210,11 +210,11 @@
#if VERTEXCOLOR_MODE == 2
lightResult.xyz += colour.xyz * lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(viewNormal.xyz, lightDir), 0);
* max(dot(viewNormal.xyz, lightDir), 0.0);
#else
lightResult.xyz += materialDiffuse.xyz * lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(viewNormal.xyz, lightDir), 0);
* max(dot(viewNormal.xyz, lightDir), 0.0);
#endif
#if @shIterator == 0
@ -432,11 +432,11 @@
#if VERTEXCOLOR_MODE == 2
lightResult.xyz += colourPassthrough.xyz * lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(viewNormal.xyz, lightDir), 0);
* max(dot(viewNormal.xyz, lightDir), 0.0);
#else
lightResult.xyz += materialDiffuse.xyz * lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(viewNormal.xyz, lightDir), 0);
* max(dot(viewNormal.xyz, lightDir), 0.0);
#endif
#if @shIterator == 0
@ -504,8 +504,8 @@
#if ENV_MAP
// Everything looks better with fresnel
float facing = 1.0 - max(abs(dot(-eyeDir, normal)), 0);
float envFactor = shSaturate(0.25 + 0.75 * pow(facing, 1));
float facing = 1.0 - max(abs(dot(-eyeDir, normal)), 0.0);
float envFactor = shSaturate(0.25 + 0.75 * pow(facing, 1.0));
shOutputColour(0).xyz += shSample(envMap, UV.zw).xyz * envFactor * env_map_color;
#endif
@ -513,7 +513,7 @@
#if SPECULAR
float3 light0Dir = normalize(lightPosObjSpace0.xyz);
float NdotL = max(dot(normal, light0Dir), 0);
float NdotL = max(dot(normal, light0Dir), 0.0);
float3 halfVec = normalize (light0Dir + eyeDir);
float shininess = matShininess;
@ -522,7 +522,7 @@
shininess *= (specTex.a);
#endif
float3 specular = pow(max(dot(normal, halfVec), 0), shininess) * lightSpec0 * matSpec;
float3 specular = pow(max(dot(normal, halfVec), 0.0), shininess) * lightSpec0 * matSpec;
#if SPEC_MAP
specular *= specTex.xyz;
#else

@ -175,7 +175,7 @@
lightResult.xyz += lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(normal.xyz, lightDir), 0);
* max(dot(normal.xyz, lightDir), 0.0);
#if @shIterator == 0
directionalResult = lightResult.xyz;
@ -310,7 +310,7 @@ shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position)
#if !IS_FIRST_PASS
// Opacity the previous passes should have, i.e. 1 - (opacity of this pass)
float previousAlpha = 1.f;
float previousAlpha = 1.0;
#endif
@ -334,7 +334,7 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
float4 albedo = float4(0,0,0,1);
float2 layerUV = float2(UV.x, 1.f-UV.y) * 16; // Reverse Y, required to get proper tangents
float2 layerUV = float2(UV.x, 1.0-UV.y) * 16.0; // Reverse Y, required to get proper tangents
float2 thisLayerUV;
float4 normalTex;
float4 diffuseTex;
@ -349,9 +349,9 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
#if @shPropertyBool(use_normal_map_@shIterator)
normalTex = shSample(normalMap@shIterator, thisLayerUV);
#if @shIterator == 0 && IS_FIRST_PASS
TSnormal = normalize(normalTex.xyz * 2 - 1);
TSnormal = normalize(normalTex.xyz * 2.0 - 1.0);
#else
TSnormal = shLerp(TSnormal, normalTex.xyz * 2 - 1, blendValues@shPropertyString(blendmap_component_@shIterator));
TSnormal = shLerp(TSnormal, normalTex.xyz * 2.0 - 1.0, blendValues@shPropertyString(blendmap_component_@shIterator));
#endif
#endif
@ -361,7 +361,7 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
diffuseTex = shSample(diffuseMap@shIterator, layerUV);
#if !@shPropertyBool(use_specular_@shIterator)
diffuseTex.a = 0;
diffuseTex.a = 0.0;
#endif
#if @shIterator == 0
@ -371,7 +371,7 @@ albedo = shLerp(albedo, diffuseTex, blendValues@shPropertyString(blendmap_compon
#endif
#if !IS_FIRST_PASS
previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator);
previousAlpha *= 1.0-blendValues@shPropertyString(blendmap_component_@shIterator);
#endif
@ -404,7 +404,7 @@ albedo = shLerp(albedo, diffuseTex, blendValues@shPropertyString(blendmap_compon
lightResult.xyz += lightDiffuse[@shIterator].xyz
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
* max(dot(normal.xyz, lightDir), 0);
* max(dot(normal.xyz, lightDir), 0.0);
#if @shIterator == 0
float3 directionalResult = lightResult.xyz;
#endif
@ -444,10 +444,10 @@ albedo = shLerp(albedo, diffuseTex, blendValues@shPropertyString(blendmap_compon
// Specular
float3 light0Dir = normalize(lightPos0.xyz);
float NdotL = max(dot(normal, light0Dir), 0);
float NdotL = max(dot(normal, light0Dir), 0.0);
float3 halfVec = normalize (light0Dir + eyeDir);
float3 specular = pow(max(dot(normal, halfVec), 0), 32) * lightSpec0;
float3 specular = pow(max(dot(normal, halfVec), 0.0), 32.0) * lightSpec0;
shOutputColour(0).xyz += specular * (albedo.a) * shadow;
#endif
@ -465,9 +465,9 @@ albedo = shLerp(albedo, diffuseTex, blendValues@shPropertyString(blendmap_compon
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if IS_FIRST_PASS
shOutputColour(0).a = 1;
shOutputColour(0).a = 1.0;
#else
shOutputColour(0).a = 1.f-previousAlpha;
shOutputColour(0).a = 1.0-previousAlpha;
#endif
}

@ -737,7 +737,7 @@ namespace Physic
{
}
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap, Ogre::Vector3* normal)
std::pair<std::string,float> PhysicEngine::rayTest(const btVector3 &from, const btVector3 &to, bool raycastingObjectOnly, bool ignoreHeightMap, Ogre::Vector3* normal)
{
std::string name = "";
float d = -1;
@ -801,7 +801,7 @@ namespace Physic
return std::make_pair(false, 1);
}
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(btVector3& from, btVector3& to)
std::vector< std::pair<float, std::string> > PhysicEngine::rayTest2(const btVector3& from, const btVector3& to)
{
MyRayResultCallback resultCallback1;
resultCallback1.m_collisionFilterGroup = 0xff;

@ -302,13 +302,13 @@ namespace Physic
* 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,
std::pair<std::string,float> rayTest(const btVector3& from,const btVector3& to,bool raycastingObjectOnly = true,
bool ignoreHeightMap = false, Ogre::Vector3* normal = NULL);
/**
* Return all objects hit by a ray.
*/
std::vector< std::pair<float, std::string> > rayTest2(btVector3& from, btVector3& to);
std::vector< std::pair<float, std::string> > rayTest2(const btVector3 &from, const btVector3 &to);
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
///< @return (hit, relative distance)

Loading…
Cancel
Save