Merge remote-tracking branch 'scrawl/master'

actorid
Marc Zinnschlag 11 years ago
commit a6e6411686

@ -99,8 +99,6 @@ set(OENGINE_BULLET
${LIBDIR}/openengine/bullet/BtOgreExtras.h
${LIBDIR}/openengine/bullet/BtOgreGP.h
${LIBDIR}/openengine/bullet/BtOgrePG.h
${LIBDIR}/openengine/bullet/CMotionState.cpp
${LIBDIR}/openengine/bullet/CMotionState.h
${LIBDIR}/openengine/bullet/physic.cpp
${LIBDIR}/openengine/bullet/physic.hpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp

@ -130,7 +130,7 @@ namespace MWBase
virtual Ogre::Vector2 getNorthVector (MWWorld::CellStore* cell) = 0;
///< get north vector (OGRE coordinates) for given interior cell
virtual std::vector<DoorMarker> getDoorMarkers (MWWorld::CellStore* cell) = 0;
virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out) = 0;
///< get a list of teleport door markers for a given cell, to be displayed on the local map
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) = 0;
@ -438,6 +438,18 @@ namespace MWBase
/// @note id must be lower case
virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr,
const std::string& id, Ogre::Vector3 worldPos) = 0;
enum DetectionType
{
Detect_Enchantment,
Detect_Key,
Detect_Creature
};
/// List all references (filtered by \a type) detected by \a ptr. The range
/// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type.
/// @note This also works for references in containers.
virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector<MWWorld::Ptr>& out,
DetectionType type) = 0;
};
}

@ -291,6 +291,9 @@ namespace MWClass
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(npc).getInventoryStore(npc);
if (ptr.getCellRef().mCharge == 0)
return std::make_pair(0, "#{sInventoryMessage1}");
// slots that this item can be equipped in
std::pair<std::vector<int>, bool> slots_ = MWWorld::Class::get(ptr).getEquipmentSlots(ptr);

@ -252,4 +252,11 @@ namespace MWClass
return ref->mBase->mData.mWeight;
}
bool Miscellaneous::isKey(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->mBase->mData.mIsKey;
}
}

@ -57,6 +57,8 @@ namespace MWClass
virtual float getWeight (const MWWorld::Ptr& ptr) const;
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
virtual bool isKey (const MWWorld::Ptr &ptr) const;
};
}

@ -493,6 +493,11 @@ namespace MWClass
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
// Weapon broken? unequip it
if (weapon.getCellRef().mCharge == 0)
weapon = *inv.unequipItem(weapon, ptr);
}
healthdmg = true;
}
@ -644,6 +649,11 @@ namespace MWClass
armorref.mCharge = armor.get<ESM::Armor>()->mBase->mData.mHealth;
armorref.mCharge -= std::min(std::max(1, (int)damagediff),
armorref.mCharge);
// Armor broken? unequip it
if (armorref.mCharge == 0)
inv.unequipItem(armor, ptr);
switch(get(armor).getEquipmentSkill(armor))
{
case ESM::Skill::LightArmor:

@ -388,6 +388,9 @@ namespace MWClass
std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
{
if (ptr.getCellRef().mCharge == 0)
return std::make_pair(0, "#{sInventoryMessage1}");
std::pair<std::vector<int>, bool> slots_ = MWWorld::Class::get(ptr).getEquipmentSlots(ptr);
if (slots_.first.empty())

@ -163,6 +163,14 @@ namespace MWGui
MWWorld::Ptr object = item.mBase;
int count = item.mCount;
// Bound items may not be moved
if (item.mBase.getCellRef().mRefID.size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_")
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}");
return;
}
if (item.mType == ItemStack::Type_Equipped)
{
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);

@ -103,27 +103,80 @@ namespace MWGui
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
// Workaround to not make the marker visible if it's under fog of war
applyFogOfWar ();
}
void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
{
// Workaround to not make the marker visible if it's under fog of war
applyFogOfWar ();
}
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerPosition& markerPos)
{
MyGUI::IntPoint widgetPos;
// normalized cell coordinates
float nX,nY;
markerPos.interior = mInterior;
if (!mInterior)
{
int cellX, cellY;
MWBase::Environment::get().getWorld()->positionToIndex(worldX, worldY, cellX, cellY);
const int cellSize = 8192;
nX = (worldX - cellSize * cellX) / cellSize;
// Image space is -Y up, cells are Y up
nY = 1 - (worldY - cellSize * cellY) / cellSize;
float cellDx = cellX - mCurX;
float cellDy = cellY - mCurY;
markerPos.cellX = cellX;
markerPos.cellY = cellY;
widgetPos = MyGUI::IntPoint(nX * 512 + (1+cellDx) * 512,
nY * 512 - (cellDy-1) * 512);
}
else
{
int cellX, cellY;
Ogre::Vector2 worldPos (worldX, worldY);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (worldPos, nX, nY, cellX, cellY);
markerPos.cellX = cellX;
markerPos.cellY = cellY;
widgetPos = MyGUI::IntPoint(nX * 512 + (1+cellX-mCurX) * 512,
nY * 512 + (1+cellY-mCurY) * 512);
}
markerPos.nX = nX;
markerPos.nY = nY;
return widgetPos;
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged)
return; // don't do anything if we're still in the same cell
mCurX = x;
mCurY = y;
mInterior = interior;
mChanged = false;
// clear all previous markers
for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i)
{
if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker")
if (mLocalMap->getChildAt(i)->getName ().substr (0, 4) == "Door")
{
MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i));
}
}
// Update the map textures
for (int mx=0; mx<3; ++mx)
{
for (int my=0; my<3; ++my)
@ -138,78 +191,57 @@ namespace MWGui
box->setImageTexture(image);
else
box->setImageTexture("black.png");
}
}
MWBase::World* world = MWBase::Environment::get().getWorld();
// door markers
// interior map only consists of one cell, so handle the markers only once
if (interior && (mx != 2 || my != 2))
continue;
MWWorld::CellStore* cell;
if (interior)
cell = MWBase::Environment::get().getWorld ()->getInterior (mPrefix);
else
cell = MWBase::Environment::get().getWorld ()->getExterior (x+mx-1, y-(my-1));
std::vector<MWBase::World::DoorMarker> doors = MWBase::Environment::get().getWorld ()->getDoorMarkers (cell);
for (std::vector<MWBase::World::DoorMarker>::iterator it = doors.begin(); it != doors.end(); ++it)
// Retrieve the door markers we want to show
std::vector<MWBase::World::DoorMarker> doors;
if (interior)
{
MWWorld::CellStore* cell = world->getInterior (mPrefix);
world->getDoorMarkers(cell, doors);
}
else
{
for (int dX=-1; dX<2; ++dX)
{
for (int dY=-1; dY<2; ++dY)
{
MWBase::World::DoorMarker marker = *it;
// convert world coordinates to normalized cell coordinates
MyGUI::IntCoord widgetCoord;
float nX,nY;
int cellDx, cellDy;
if (!interior)
{
const int cellSize = 8192;
nX = (marker.x - cellSize * (x+mx-1)) / cellSize;
nY = 1 - (marker.y - cellSize * (y-(my-1))) / cellSize;
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + mx * 512, nY * 512 - 4 + my * 512, 8, 8);
}
else
{
Ogre::Vector2 position (marker.x, marker.y);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
}
static int counter = 0;
++counter;
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage",
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", marker.name);
markerWidget->setUserString("IsMarker", "true");
markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused);
markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused);
MarkerPosition markerPos;
markerPos.interior = interior;
markerPos.cellX = interior ? cellDx : x + mx - 1;
markerPos.cellY = interior ? cellDy : y + ((my - 1)*-1);
markerPos.nX = nX;
markerPos.nY = nY;
markerWidget->setUserData(markerPos);
MWWorld::CellStore* cell = world->getExterior (mCurX+dX, mCurY+dY);
world->getDoorMarkers(cell, doors);
}
}
}
mInterior = interior;
mCurX = x;
mCurY = y;
mChanged = false;
// fog of war
// Create a widget for each marker
int counter = 0;
for (std::vector<MWBase::World::DoorMarker>::iterator it = doors.begin(); it != doors.end(); ++it)
{
MWBase::World::DoorMarker marker = *it;
MarkerPosition markerPos;
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.x, marker.y, markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
widgetPos.top - 4,
8, 8);
++counter;
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage",
widgetCoord, MyGUI::Align::Default, "Door" + boost::lexical_cast<std::string>(counter));
markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", marker.name);
markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused);
markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused);
// Used by tooltips to not show the tooltip if marker is hidden by fog of war
markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos);
}
updateMarkers();
applyFogOfWar();
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
@ -222,6 +254,8 @@ namespace MWGui
void LocalMapBase::setPlayerPos(const float x, const float y)
{
updateMarkers();
if (x == mLastPositionX && y == mLastPositionY)
return;
@ -255,6 +289,88 @@ namespace MWGui
mLastDirectionY = y;
}
void LocalMapBase::addDetectionMarkers(int type)
{
std::vector<MWWorld::Ptr> markers;
MWBase::World* world = MWBase::Environment::get().getWorld();
world->listDetectedReferences(
world->getPlayer().getPlayer(),
markers, MWBase::World::DetectionType(type));
if (markers.empty())
return;
std::string markerTexture;
MyGUI::Colour markerColour;
if (type == MWBase::World::Detect_Creature)
{
markerTexture = "textures\\menu_map_dcreature.dds";
markerColour = MyGUI::Colour(1,0,0,1);
}
if (type == MWBase::World::Detect_Key)
{
markerTexture = "textures\\menu_map_dkey.dds";
markerColour = MyGUI::Colour(0,1,0,1);
}
if (type == MWBase::World::Detect_Enchantment)
{
markerTexture = "textures\\menu_map_dmagic.dds";
markerColour = MyGUI::Colour(0,0,1,1);
}
int counter = 0;
for (std::vector<MWWorld::Ptr>::iterator it = markers.begin(); it != markers.end(); ++it)
{
const ESM::Position& worldPos = it->getRefData().getPosition();
MarkerPosition markerPos;
MyGUI::IntPoint widgetPos = getMarkerPosition(worldPos.pos[0], worldPos.pos[1], markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
widgetPos.top - 4,
8, 8);
++counter;
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
markerWidget->setImageTexture(markerTexture);
markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos);
markerWidget->setColour(markerColour);
}
}
void LocalMapBase::updateMarkers()
{
// clear all previous markers
for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i)
{
if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker")
{
MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i));
}
}
addDetectionMarkers(MWBase::World::Detect_Creature);
addDetectionMarkers(MWBase::World::Detect_Key);
addDetectionMarkers(MWBase::World::Detect_Enchantment);
// Add marker for the spot marked with Mark magic effect
MWWorld::CellStore* markedCell = NULL;
ESM::Position markedPosition;
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
if (markedCell && markedCell->isExterior() == !mInterior
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->mCell->mName, mPrefix)))
{
MarkerPosition markerPos;
MyGUI::IntPoint widgetPos = getMarkerPosition(markedPosition.pos[0], markedPosition.pos[1], markerPos);
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
widgetPos.top - 4,
8, 8);
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
widgetCoord, MyGUI::Align::Default, "MarkerMarked");
markerWidget->setImageTexture("textures\\menu_map_smark.dds");
markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos);
}
}
// ------------------------------------------------------------------------------------------
MapWindow::MapWindow(const std::string& cacheDir)
@ -319,7 +435,7 @@ namespace MWGui
static int _counter=0;
MyGUI::Button* markerWidget = mGlobalMapImage->createWidget<MyGUI::Button>("ButtonImage",
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter));
widgetCoord, MyGUI::Align::Default, "Door" + boost::lexical_cast<std::string>(_counter));
markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
@ -385,7 +501,7 @@ namespace MWGui
for (unsigned int i=0; i<mGlobalMapImage->getChildCount (); ++i)
{
if (mGlobalMapImage->getChildAt (i)->getName().substr(0,6) == "Marker")
if (mGlobalMapImage->getChildAt (i)->getName().substr(0,4) == "Door")
mGlobalMapImage->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
}

@ -55,9 +55,16 @@ namespace MWGui
void onMarkerFocused(MyGUI::Widget* w1, MyGUI::Widget* w2);
void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2);
MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerPosition& markerPos);
virtual void notifyPlayerUpdate() {}
virtual void notifyMapChanged() {}
// Update markers (Detect X effects, Mark/Recall effects)
// Note, door markers handled in setActiveCell
void updateMarkers();
void addDetectionMarkers(int type);
OEngine::GUI::Layout* mLayout;
bool mMapDragAndDrop;

@ -40,6 +40,14 @@ namespace MWGui
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
{
const ItemStack& item = mSourceModel->getItem(i);
// Bound items may not be stolen
if (item.mBase.getCellRef().mRefID.size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_")
{
continue;
}
if (std::find(mHiddenItems.begin(), mHiddenItems.end(), item) == mHiddenItems.end()
&& item.mType != ItemStack::Type_Equipped)
mItems.push_back(item);

@ -154,6 +154,13 @@ namespace MWGui
if(!MWWorld::Class::get(base).canSell(base, services))
continue;
// Bound items may not be bought
if (item.mBase.getCellRef().mRefID.size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_")
{
continue;
}
// don't show equipped items
if(mMerchant.getTypeName() == typeid(ESM::NPC).name())
{

@ -831,9 +831,11 @@ namespace MWInput
void InputManager::updateIdleTime(float dt)
{
static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fVanityDelay")->getFloat();
if (mTimeIdle >= 0.f)
mTimeIdle += dt;
if (mTimeIdle > 30.f) {
if (mTimeIdle > vanityDelay) {
MWBase::Environment::get().getWorld()->toggleVanityMode(true);
mTimeIdle = -1.f;
}

@ -46,6 +46,44 @@ void adjustBoundItem (const std::string& item, bool bound, const MWWorld::Ptr& a
}
}
bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
{
// TODO: remove this check once creatures support inventory store
if (ptr.getTypeName() == typeid(ESM::NPC).name())
{
MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
MWWorld::ContainerStoreIterator item =
inv.getSlot(slot);
if (item != inv.end())
{
if (!item->getClass().hasItemHealth(*item))
return false;
if (item->getCellRef().mCharge == -1)
item->getCellRef().mCharge = item->getClass().getItemMaxHealth(*item);
if (item->getCellRef().mCharge == 0)
return false;
item->getCellRef().mCharge -=
std::min(disintegrate,
static_cast<float>(item->getCellRef().mCharge));
if (item->getCellRef().mCharge == 0)
{
// Will unequip the broken item and try to find a replacement
if (ptr.getRefData().getHandle() != "player")
inv.autoEquip(ptr);
else
inv.unequipItem(*item, ptr);
}
return true;
}
}
return true;
}
}
namespace MWMechanics
@ -241,6 +279,33 @@ namespace MWMechanics
creatureStats.setDynamic(i, stat);
}
// Apply disintegration (reduces item health)
float disintegrateWeapon = effects.get(EffectKey(ESM::MagicEffect::DisintegrateWeapon)).mMagnitude;
if (disintegrateWeapon > 0)
disintegrateSlot(ptr, MWWorld::InventoryStore::Slot_CarriedRight, disintegrateWeapon*duration);
float disintegrateArmor = effects.get(EffectKey(ESM::MagicEffect::DisintegrateArmor)).mMagnitude;
if (disintegrateArmor > 0)
{
// According to UESP
int priorities[] = {
MWWorld::InventoryStore::Slot_CarriedLeft,
MWWorld::InventoryStore::Slot_Cuirass,
MWWorld::InventoryStore::Slot_LeftPauldron,
MWWorld::InventoryStore::Slot_RightPauldron,
MWWorld::InventoryStore::Slot_LeftGauntlet,
MWWorld::InventoryStore::Slot_RightGauntlet,
MWWorld::InventoryStore::Slot_Helmet,
MWWorld::InventoryStore::Slot_Greaves,
MWWorld::InventoryStore::Slot_Boots
};
for (unsigned int i=0; i<sizeof(priorities)/sizeof(int); ++i)
{
if (disintegrateSlot(ptr, priorities[i], disintegrateArmor*duration))
break;
}
}
// Apply damage ticks
int damageEffects[] = {
ESM::MagicEffect::FireDamage, ESM::MagicEffect::ShockDamage, ESM::MagicEffect::FrostDamage, ESM::MagicEffect::Poison,
@ -640,6 +705,11 @@ namespace MWMechanics
iter->second->kill();
// Reset magic effects and recalculate derived effects
// One case where we need this is to make sure bound items are removed upon death
stats.setMagicEffects(MWMechanics::MagicEffects());
calculateCreatureStatModifiers(iter->first, 0);
++mDeathCount[cls.getId(iter->first)];
if(cls.isEssential(iter->first))

@ -12,6 +12,8 @@
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "spellcasting.hpp"
namespace MWMechanics
{
void MechanicsManager::buildPlayer()
@ -123,6 +125,19 @@ namespace MWMechanics
npcStats.getSkill (index).setBase (
npcStats.getSkill (index).getBase() + bonus);
}
if (i==1)
{
// Major skill - add starting spells for this skill if existing
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
MWWorld::Store<ESM::Spell>::iterator it = store.get<ESM::Spell>().begin();
for (; it != store.get<ESM::Spell>().end(); ++it)
{
if (it->mData.mFlags & ESM::Spell::F_PCStart
&& spellSchoolToSkill(getSpellSchool(&*it, ptr)) == index)
creatureStats.getSpells().add(it->mId);
}
}
}
}

@ -8,6 +8,7 @@
#include "../mwworld/containerstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/actionteleport.hpp"
#include "../mwrender/animation.hpp"
@ -250,26 +251,30 @@ namespace MWMechanics
if (effectId == ESM::MagicEffect::DivineIntervention)
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker", worldPos);
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker", worldPos);
}
else if (effectId == ESM::MagicEffect::AlmsiviIntervention)
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "templemarker", worldPos);
}
else if (effectId == ESM::MagicEffect::Mark)
{
// TODO
MWBase::Environment::get().getWorld()->getPlayer().markPosition(
target.getCell(), target.getRefData().getPosition());
}
else if (effectId == ESM::MagicEffect::Recall)
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
MWWorld::CellStore* markedCell = NULL;
ESM::Position markedPosition;
// TODO
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
if (markedCell)
{
MWWorld::ActionTeleport action(markedCell->isExterior() ? "" : markedCell->mCell->mName,
markedPosition);
action.execute(target);
}
}
}
}

@ -280,6 +280,11 @@ namespace MWRender
}
}
float Camera::getCameraDistance() const
{
return mCamera->getPosition().z;
}
void Camera::setCameraDistance(float dist, bool adjust, bool override)
{
if(mFirstPersonView && !mPreviewMode && !mVanity.enabled)

@ -105,6 +105,8 @@ namespace MWRender
/// Restore default camera distance for current mode.
void setCameraDistance();
float getCameraDistance() const;
void setAnimation(NpcAnimation *anim);
/// Stores focal and camera world positions in passed arguments

@ -225,64 +225,54 @@ void LocalMap::render(const float x, const float y,
tex = TextureManager::getSingleton().getByName(texture);
if (tex.isNull())
{
// try loading from disk
//if (boost::filesystem::exists(texture+".jpg"))
//{
/// \todo
//}
//else
// render
tex = TextureManager::getSingleton().createManual(
texture,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sMapResolution/sSize, yw*sMapResolution/sSize,
0,
PF_R8G8B8,
TU_RENDERTARGET);
RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(mCellCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0, 0, 0));
vp->setVisibilityMask(RV_Map);
vp->setMaterialScheme("local_map");
rtt->update();
// create "fog of war" texture
TexturePtr tex2 = TextureManager::getSingleton().createManual(
texture + "_fog",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize,
0,
PF_A8R8G8B8,
TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
// create a buffer to use for dynamic operations
std::vector<uint32> buffer;
buffer.resize(sFogOfWarResolution*sFogOfWarResolution);
// initialize to (0, 0, 0, 1)
for (int p=0; p<sFogOfWarResolution*sFogOfWarResolution; ++p)
{
// render
tex = TextureManager::getSingleton().createManual(
texture,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sMapResolution/sSize, yw*sMapResolution/sSize,
0,
PF_R8G8B8,
TU_RENDERTARGET);
RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(mCellCamera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0, 0, 0));
vp->setVisibilityMask(RV_Map);
vp->setMaterialScheme("local_map");
rtt->update();
// create "fog of war" texture
TexturePtr tex2 = TextureManager::getSingleton().createManual(
texture + "_fog",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
xw*sFogOfWarResolution/sSize, yw*sFogOfWarResolution/sSize,
0,
PF_A8R8G8B8,
TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
// create a buffer to use for dynamic operations
std::vector<uint32> buffer;
buffer.resize(sFogOfWarResolution*sFogOfWarResolution);
// initialize to (0, 0, 0, 1)
for (int p=0; p<sFogOfWarResolution*sFogOfWarResolution; ++p)
{
buffer[p] = (255 << 24);
}
memcpy(tex2->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4);
tex2->getBuffer()->unlock();
buffer[p] = (255 << 24);
}
mBuffers[texture] = buffer;
memcpy(tex2->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &buffer[0], sFogOfWarResolution*sFogOfWarResolution*4);
tex2->getBuffer()->unlock();
// save to cache for next time
//rtt->writeContentsToFile("./" + texture + ".jpg");
}
mBuffers[texture] = buffer;
}
mRenderingManager->enableLights(true);
mLight->setVisible(false);
@ -339,8 +329,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).yAxis();
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
if (!mInterior)
{
x = std::ceil(pos.x / sSize)-1;

@ -1026,4 +1026,9 @@ void RenderingManager::enableTerrain(bool enable)
mTerrain->setVisible(false);
}
float RenderingManager::getCameraDistance() const
{
return mCamera->getCameraDistance();
}
} // namespace

@ -90,6 +90,7 @@ public:
bool vanityRotateCamera(const float *rot);
void setCameraDistance(float dist, bool adjust = false, bool override = true);
float getCameraDistance() const;
void setupPlayer(const MWWorld::Ptr &ptr);
void renderPlayer(const MWWorld::Ptr &ptr);

@ -207,6 +207,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
if (!ptr.isInCell())
return;
if (ptr.getRefData().getHandle() == "player")
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
@ -275,6 +279,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
if (!ptr.isInCell())
return;
if (ptr.getRefData().getHandle() == "player")
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
@ -336,6 +344,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
if (!ptr.isInCell())
return;
if (ptr.getRefData().getHandle() == "player")
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
@ -605,6 +617,10 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
if (!ptr.isInCell())
return;
ptr.getRefData().getLocalRotation().rot[0] = 0;
ptr.getRefData().getLocalRotation().rot[1] = 0;
ptr.getRefData().getLocalRotation().rot[2] = 0;
@ -624,6 +640,9 @@ namespace MWScript
{
const MWWorld::Ptr& ptr = R()(runtime);
if (!ptr.isInCell())
return;
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
@ -659,6 +678,9 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
if (!ptr.isInCell())
return;
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());

@ -252,7 +252,7 @@ namespace MWSound
float basevol = volumeFromType(Play_TypeVoice);
std::string filePath = "Sound/"+filename;
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
const Ogre::Vector3 objpos(pos.pos);
MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f,
20.0f, 12750.0f, Play_Normal|Play_TypeVoice, 0);
@ -354,7 +354,7 @@ namespace MWSound
float min, max;
std::string file = lookup(soundId, volume, min, max);
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
const Ogre::Vector3 objpos(pos.pos);
sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode|type, offset);
if((mode&Play_NoTrack))
@ -584,7 +584,7 @@ namespace MWSound
if(!ptr.isEmpty())
{
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
const Ogre::Vector3 objpos(pos.pos);
snditer->first->setPosition(objpos);
}
//update fade out

@ -4,7 +4,7 @@
#include <vector>
#include <string>
#include "refdata.hpp"
#include "ptr.hpp"
namespace ESM
{
@ -18,13 +18,13 @@ namespace MWWorld
{
std::vector<Ogre::SceneNode*> mHandles;
bool operator() (ESM::CellRef& ref, RefData& data)
bool operator() (MWWorld::Ptr ptr)
{
Ogre::SceneNode* handle = data.getBaseNode();
Ogre::SceneNode* handle = ptr.getRefData().getBaseNode();
if (handle)
mHandles.push_back (handle);
data.setBaseNode(0);
ptr.getRefData().setBaseNode(0);
return true;
}
};

@ -143,7 +143,7 @@ namespace MWWorld
{
if (!iter->mData.getCount())
continue;
if (!functor (iter->mRef, iter->mData))
if (!functor (MWWorld::Ptr(&*iter, this)))
return false;
}
return true;

@ -290,6 +290,8 @@ namespace MWWorld
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
virtual bool isKey (const MWWorld::Ptr& ptr) const { return false; }
virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell) const;

@ -577,10 +577,28 @@ namespace MWWorld
float oldHeight = iter->first.getRefData().getPosition().pos[2];
bool waterCollision = false;
if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects()
.get(ESM::MagicEffect::WaterWalking).mMagnitude
&& cell->hasWater()
&& !world->isUnderwater(iter->first.getCell(),
Ogre::Vector3(iter->first.getRefData().getPosition().pos)))
waterCollision = true;
btStaticPlaneShape planeShape(btVector3(0,0,1), waterlevel);
btCollisionObject object;
object.setCollisionShape(&planeShape);
if (waterCollision)
mEngine->dynamicsWorld->addCollisionObject(&object);
Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum,
world->isFlying(iter->first),
waterlevel, mEngine);
if (waterCollision)
mEngine->dynamicsWorld->removeCollisionObject(&object);
float heightDiff = newpos.z - oldHeight;
if (heightDiff < 0)

@ -21,7 +21,8 @@ namespace MWWorld
mLastKnownExteriorPosition(0,0,0),
mAutoMove(false),
mForwardBackward (0),
mTeleported(false)
mTeleported(false),
mMarkedCell(NULL)
{
mPlayer.mBase = player;
mPlayer.mRef.mRefID = "player";
@ -157,4 +158,17 @@ namespace MWWorld
{
mTeleported = teleported;
}
void Player::markPosition(CellStore *markedCell, ESM::Position markedPosition)
{
mMarkedCell = markedCell;
mMarkedPosition = markedPosition;
}
void Player::getMarkedPosition(CellStore*& markedCell, ESM::Position &markedPosition) const
{
markedCell = mMarkedCell;
if (mMarkedCell)
markedPosition = mMarkedPosition;
}
}

@ -32,6 +32,10 @@ namespace MWWorld
Ogre::Vector3 mLastKnownExteriorPosition;
ESM::Position mMarkedPosition;
// If no position was marked, this is NULL
CellStore* mMarkedCell;
bool mAutoMove;
int mForwardBackward;
bool mTeleported;
@ -39,6 +43,10 @@ namespace MWWorld
Player(const ESM::NPC *player, const MWBase::World& world);
// For mark/recall magic effects
void markPosition (CellStore* markedCell, ESM::Position markedPosition);
void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const;
/// Interiors can not always be mapped to a world position. However
/// world position is still required for divine / almsivi magic effects
/// and the player arrow on the global map.

@ -796,32 +796,9 @@ namespace MWWorld
MWWorld::Ptr World::getFacedObject()
{
std::pair<float, std::string> result;
if (!mRendering->occlusionQuerySupported())
result = mPhysics->getFacedHandle (getMaxActivationDistance ());
else
result = std::make_pair (mFacedDistance, mFacedHandle);
if (result.second.empty())
return MWWorld::Ptr ();
MWWorld::Ptr object = searchPtrViaHandle (result.second);
if (object.isEmpty())
return object;
float ActivationDistance;
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
ActivationDistance = getObjectActivationDistance ()*50;
else if (object.getTypeName ().find("NPC") != std::string::npos)
ActivationDistance = getNpcActivationDistance ();
else
ActivationDistance = getObjectActivationDistance ();
if (result.first > ActivationDistance)
return MWWorld::Ptr ();
return object;
if (mFacedHandle.empty())
return MWWorld::Ptr();
return searchPtrViaHandle(mFacedHandle);
}
std::pair<MWWorld::Ptr,Ogre::Vector3> World::getHitContact(const MWWorld::Ptr &ptr, float distance)
@ -934,7 +911,7 @@ namespace MWWorld
ptr.getRefData().setCount(0);
}
}
if (haveToMove)
if (haveToMove && ptr.getRefData().getBaseNode())
{
mRendering->moveObject(ptr, vec);
mPhysics->moveObject (ptr);
@ -1063,7 +1040,7 @@ namespace MWWorld
void World::adjustPosition(const Ptr &ptr)
{
Ogre::Vector3 pos (ptr.getRefData().getPosition().pos[0], ptr.getRefData().getPosition().pos[1], ptr.getRefData().getPosition().pos[2]);
Ogre::Vector3 pos (ptr.getRefData().getPosition().pos);
if(!ptr.getRefData().getBaseNode())
{
@ -1304,7 +1281,7 @@ namespace MWWorld
if (mPlayer->getPlayer().getCell()->isExterior())
{
ESM::Position pos = mPlayer->getPlayer().getRefData().getPosition();
mPlayer->setLastKnownExteriorPosition(Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]));
mPlayer->setLastKnownExteriorPosition(Ogre::Vector3(pos.pos));
}
}
@ -1346,6 +1323,14 @@ namespace MWWorld
void World::updateFacedHandle ()
{
float telekinesisRangeBonus =
mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects()
.get(ESM::MagicEffect::Telekinesis).mMagnitude;
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);
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;
@ -1353,13 +1338,13 @@ namespace MWWorld
{
float x, y;
MWBase::Environment::get().getWindowManager()->getMousePosition(x, y);
results = mPhysics->getFacedHandles(x, y, getMaxActivationDistance ());
results = mPhysics->getFacedHandles(x, y, activationDistance);
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
results = mPhysics->getFacedHandles(x, y, getMaxActivationDistance ()*50);
}
else
{
results = mPhysics->getFacedHandles(getMaxActivationDistance ());
results = mPhysics->getFacedHandles(activationDistance);
}
// ignore the player and other things we're not interested in
@ -1442,10 +1427,8 @@ namespace MWWorld
return d;
}
std::vector<World::DoorMarker> World::getDoorMarkers (CellStore* cell)
void World::getDoorMarkers (CellStore* cell, std::vector<World::DoorMarker>& out)
{
std::vector<World::DoorMarker> result;
MWWorld::CellRefList<ESM::Door>& doors = cell->mDoors;
CellRefList<ESM::Door>::List& refList = doors.mList;
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
@ -1461,11 +1444,9 @@ namespace MWWorld
newMarker.x = pos.pos[0];
newMarker.y = pos.pos[1];
result.push_back(newMarker);
out.push_back(newMarker);
}
}
return result;
}
void World::getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y)
@ -1588,7 +1569,7 @@ namespace MWWorld
pos.rot[1] = 0;
Ogre::Vector3 orig =
Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]);
Ogre::Vector3(pos.pos);
Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1);
float len = (pos.pos[2] >= 0) ? pos.pos[2] : -pos.pos[2];
@ -1829,9 +1810,9 @@ namespace MWWorld
{
std::vector<std::string> mHandles;
bool operator() (ESM::CellRef& ref, RefData& data)
bool operator() (Ptr ptr)
{
Ogre::SceneNode* handle = data.getBaseNode();
Ogre::SceneNode* handle = ptr.getRefData().getBaseNode();
if (handle)
mHandles.push_back(handle->getName());
return true;
@ -1940,17 +1921,8 @@ namespace MWWorld
int y = ext->getGridY();
indexToPosition(x, y, pos.pos[0], pos.pos[1], true);
ESM::Land* land = getStore().get<ESM::Land>().search(x, y);
if (land) {
if (!land->isDataLoaded(ESM::Land::DATA_VHGT)) {
land->loadData(ESM::Land::DATA_VHGT);
}
pos.pos[2] = land->mLandData->mHeights[ESM::Land::LAND_NUM_VERTS / 2 + 1];
}
else {
std::cerr << "Land data for cell at (" << x << ", " << y << ") not found\n";
pos.pos[2] = 0;
}
// Note: Z pos will be adjusted by adjustPosition later
pos.pos[2] = 0;
return true;
}
@ -2312,7 +2284,7 @@ namespace MWWorld
if (ref.mRef.mTeleport && ref.mRef.mDestCell.empty())
{
ESM::Position pos = ref.mRef.mDoorDest;
result = Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]);
result = Ogre::Vector3(pos.pos);
return true;
}
}
@ -2333,7 +2305,7 @@ namespace MWWorld
for (std::vector<MWWorld::Ptr>::iterator it = markers.begin(); it != markers.end(); ++it)
{
ESM::Position pos = it->getRefData().getPosition();
Ogre::Vector3 markerPos = Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]);
Ogre::Vector3 markerPos = Ogre::Vector3(pos.pos);
float distance = worldPos.squaredDistance(markerPos);
if (distance < closestDistance)
{
@ -2357,4 +2329,91 @@ namespace MWWorld
mWeatherManager->update(duration);
}
struct AddDetectedReference
{
AddDetectedReference(std::vector<Ptr>& out, Ptr detector, World::DetectionType type, float squaredDist)
: mOut(out), mDetector(detector), mType(type), mSquaredDist(squaredDist)
{
}
std::vector<Ptr>& mOut;
Ptr mDetector;
float mSquaredDist;
World::DetectionType mType;
bool operator() (MWWorld::Ptr ptr)
{
if (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(
Ogre::Vector3(mDetector.getRefData().getPosition().pos)) >= mSquaredDist)
return true;
if (!ptr.getRefData().isEnabled())
return true;
// Consider references inside containers as well
if (ptr.getClass().isActor() || ptr.getClass().getTypeName() == typeid(ESM::Container).name())
{
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr);
{
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{
if (needToAdd(*it))
{
mOut.push_back(ptr);
return true;
}
}
}
}
if (needToAdd(ptr))
mOut.push_back(ptr);
return true;
}
bool needToAdd (MWWorld::Ptr ptr)
{
if (mType == World::Detect_Creature && ptr.getClass().getTypeName() != typeid(ESM::Creature).name())
return false;
if (mType == World::Detect_Key && !ptr.getClass().isKey(ptr))
return false;
if (mType == World::Detect_Enchantment && ptr.getClass().getEnchantment(ptr).empty())
return false;
return true;
}
};
void World::listDetectedReferences(const Ptr &ptr, std::vector<Ptr> &out, DetectionType type)
{
const MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects();
float dist=0;
if (type == World::Detect_Creature)
dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectAnimal)).mMagnitude;
else if (type == World::Detect_Key)
dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectKey)).mMagnitude;
else if (type == World::Detect_Enchantment)
dist = effects.get(MWMechanics::EffectKey(ESM::MagicEffect::DetectEnchantment)).mMagnitude;
if (!dist)
return;
dist = feetToGameUnits(dist);
AddDetectedReference functor (out, ptr, type, dist*dist);
const Scene::CellStoreCollection& active = mWorldScene->getActiveCells();
for (Scene::CellStoreCollection::const_iterator it = active.begin(); it != active.end(); ++it)
{
MWWorld::CellStore* cellStore = *it;
cellStore->forEach(functor);
}
}
float World::feetToGameUnits(float feet)
{
// Looks like there is no GMST for this. This factor was determined in experiments
// with the Telekinesis effect.
return feet * 22;
}
}

@ -155,6 +155,8 @@ namespace MWWorld
/// Called when \a object is moved to an inactive cell
void objectLeftActiveCell (MWWorld::Ptr object, MWWorld::Ptr movedPtr);
float feetToGameUnits(float feet);
public:
World (OEngine::Render::OgreRenderer& renderer,
@ -202,7 +204,7 @@ namespace MWWorld
virtual Ogre::Vector2 getNorthVector (CellStore* cell);
///< get north vector (OGRE coordinates) for given interior cell
virtual std::vector<DoorMarker> getDoorMarkers (MWWorld::CellStore* cell);
virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out);
///< get a list of teleport door markers for a given cell, to be displayed on the local map
virtual void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
@ -526,6 +528,12 @@ namespace MWWorld
/// @note id must be lower case
virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr,
const std::string& id, Ogre::Vector3 worldPos);
/// List all references (filtered by \a type) detected by \a ptr. The range
/// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type.
/// @note This also works for references in containers.
virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector<MWWorld::Ptr>& out,
DetectionType type);
};
}

@ -20,7 +20,7 @@ namespace ESM
public:
int mRefnum; // Reference number
std::string mRefID; // ID of object being referenced
std::string mRefID; // ID of object being referenced (must be lowercase)
float mScale; // Scale applied to mesh
@ -89,4 +89,4 @@ namespace ESM
};
}
#endif
#endif

@ -1,46 +0,0 @@
#include "CMotionState.h"
#include "physic.hpp"
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include <components/nifbullet/bulletnifloader.hpp>
namespace OEngine {
namespace Physic
{
CMotionState::CMotionState(PhysicEngine* eng,std::string name)
: isPC(false)
, isNPC(true)
{
pEng = eng;
tr.setIdentity();
pName = name;
}
void CMotionState::getWorldTransform(btTransform &worldTrans) const
{
worldTrans = tr;
}
void CMotionState::setWorldTransform(const btTransform &worldTrans)
{
tr = worldTrans;
PhysicEvent evt;
evt.isNPC = isNPC;
evt.isPC = isPC;
evt.newTransform = tr;
evt.RigidBodyName = pName;
if(isPC)
{
pEng->PEventList.push_back(evt);
}
else
{
pEng->NPEventList.push_back(evt);
}
}
}}

@ -1,52 +0,0 @@
#ifndef OENGINE_CMOTIONSTATE_H
#define OENGINE_CMOTIONSTATE_H
#include <BulletDynamics/Dynamics/btRigidBody.h>
#include <string>
namespace OEngine {
namespace Physic
{
class PhysicEngine;
/**
* A CMotionState is associated with a single RigidBody.
* When the RigidBody is moved by bullet, bullet will call the function setWorldTransform.
* for more info, see the bullet Wiki at btMotionState.
*/
class CMotionState:public btMotionState
{
public:
CMotionState(PhysicEngine* eng,std::string name);
/**
* Return the position of the RigidBody.
*/
virtual void getWorldTransform(btTransform &worldTrans) const;
/**
* Function called by bullet when the RigidBody is moved.
* It add an event to the EventList of the PhysicEngine class.
*/
virtual void setWorldTransform(const btTransform &worldTrans);
protected:
PhysicEngine* pEng;
btTransform tr;
bool isNPC;
bool isPC;
std::string pName;
};
struct PhysicEvent
{
bool isNPC;
bool isPC;
btTransform newTransform;
std::string RigidBodyName;
};
}}
#endif

@ -3,7 +3,6 @@
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <components/nifbullet/bulletnifloader.hpp>
#include "CMotionState.h"
#include "OgreRoot.h"
#include "btKinematicCharacterController.h"
#include "BtOgrePG.h"
@ -318,9 +317,7 @@ namespace Physic
btVector3 scl(triSize, triSize, 1);
hfShape->setLocalScaling(scl);
CMotionState* newMotionState = new CMotionState(this,name);
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,hfShape);
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,0,hfShape);
RigidBody* body = new RigidBody(CI,name);
body->getWorldTransform().setOrigin(btVector3( (x+0.5)*triSize*(sqrtVerts-1), (y+0.5)*triSize*(sqrtVerts-1), (maxh+minh)/2.f));
@ -401,12 +398,9 @@ namespace Physic
else
shape->mRaycastingShape->setLocalScaling( btVector3(scale,scale,scale));
//create the motionState
CMotionState* newMotionState = new CMotionState(this,name);
//create the real body
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo
(0,newMotionState, raycasting ? shape->mRaycastingShape : shape->mCollisionShape);
(0,0, raycasting ? shape->mRaycastingShape : shape->mCollisionShape);
RigidBody* body = new RigidBody(CI,name);
body->mPlaceable = placeable;

@ -38,7 +38,6 @@ namespace MWWorld
namespace OEngine {
namespace Physic
{
class CMotionState;
struct PhysicEvent;
class PhysicEngine;
class RigidBody;
@ -157,17 +156,7 @@ namespace Physic
private:
void disableCollisionBody();
void enableCollisionBody();
public:
//HACK: in Visual Studio 2010 and presumably above, this structures alignment
// must be 16, but the built in operator new & delete don't properly
// perform this alignment.
#if _MSC_VER >= 1600
void * operator new (size_t Size) { return _aligned_malloc (Size, 16); }
void operator delete (void * Data) { _aligned_free (Data); }
#endif
private:
OEngine::Physic::RigidBody* mBody;
OEngine::Physic::RigidBody* mRaycastingBody;
@ -329,12 +318,6 @@ public:
const btVector3 &origin,
btCollisionObject *object);
//event list of non player object
std::list<PhysicEvent> NPEventList;
//event list affecting the player
std::list<PhysicEvent> PEventList;
//Bullet Stuff
btOverlappingPairCache* pairCache;
btBroadphaseInterface* broadphase;

@ -25,7 +25,8 @@ void OgreRenderer::cleanup()
delete mFader;
mFader = NULL;
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
if (mWindow)
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
mWindow = NULL;
delete mOgreInit;

Loading…
Cancel
Save