forked from mirror/openmw-tes3mp
Merge branch 'refdata' into next
This commit is contained in:
commit
0d7f39fcb5
41 changed files with 409 additions and 258 deletions
|
@ -14,7 +14,7 @@ set(GAME_HEADER
|
|||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||
|
||||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
@ -44,7 +44,7 @@ add_openmw_dir (mwsound
|
|||
add_openmw_dir (mwworld
|
||||
refdata world physicssystem scene environment globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake containerstore manualref containerutil player cellfunctors
|
||||
cells localscripts
|
||||
cells localscripts customdata
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_APPARATUS_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_ARMOR_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_BOOK_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_CLOTHING_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -6,9 +6,41 @@
|
|||
#include <components/esm_store/cell_store.hpp>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Container::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
|
||||
// \todo add initial container content
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
}
|
||||
|
||||
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData> *ref =
|
||||
|
@ -16,7 +48,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
@ -50,17 +82,9 @@ namespace MWClass
|
|||
MWWorld::ContainerStore<MWWorld::RefData>& Container::getContainerStore (const MWWorld::Ptr& ptr)
|
||||
const
|
||||
{
|
||||
if (!ptr.getRefData().getContainerStore().get())
|
||||
{
|
||||
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
|
||||
new MWWorld::ContainerStore<MWWorld::RefData>);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
// TODO add initial content
|
||||
|
||||
ptr.getRefData().getContainerStore() = store;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getContainerStore();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
}
|
||||
|
||||
std::string Container::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
#define GAME_MWCLASS_CONTAINER_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
class Container : public MWWorld::Class
|
||||
{
|
||||
void ensureCustomData (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||
|
|
|
@ -4,16 +4,62 @@
|
|||
#include <components/esm/loadcrea.hpp>
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontalk.hpp"
|
||||
#include "../mwworld/environment.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWMechanics::CreatureStats mCreatureStats;
|
||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Creature::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.mAttributes[0].set (ref->base->data.strength);
|
||||
data->mCreatureStats.mAttributes[1].set (ref->base->data.intelligence);
|
||||
data->mCreatureStats.mAttributes[2].set (ref->base->data.willpower);
|
||||
data->mCreatureStats.mAttributes[3].set (ref->base->data.agility);
|
||||
data->mCreatureStats.mAttributes[4].set (ref->base->data.speed);
|
||||
data->mCreatureStats.mAttributes[5].set (ref->base->data.endurance);
|
||||
data->mCreatureStats.mAttributes[6].set (ref->base->data.personality);
|
||||
data->mCreatureStats.mAttributes[7].set (ref->base->data.luck);
|
||||
data->mCreatureStats.mDynamic[0].set (ref->base->data.health);
|
||||
data->mCreatureStats.mDynamic[1].set (ref->base->data.mana);
|
||||
data->mCreatureStats.mDynamic[2].set (ref->base->data.fatigue);
|
||||
|
||||
data->mCreatureStats.mLevel = ref->base->data.level;
|
||||
|
||||
// \todo add initial container content
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Creature::getId (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
|
@ -24,18 +70,8 @@ namespace MWClass
|
|||
|
||||
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
|
||||
/*ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
if (!model.empty())
|
||||
{*/
|
||||
MWRender::Actors& actors = renderingInterface.getActors();
|
||||
actors.insertCreature(ptr);
|
||||
|
||||
MWRender::Actors& actors = renderingInterface.getActors();
|
||||
actors.insertCreature(ptr);
|
||||
}
|
||||
|
||||
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
|
||||
|
@ -49,7 +85,6 @@ namespace MWClass
|
|||
if(!model.empty()){
|
||||
physics.insertActorPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Creature::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const
|
||||
|
@ -72,31 +107,9 @@ namespace MWClass
|
|||
|
||||
MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCreatureStats().get())
|
||||
{
|
||||
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
||||
new MWMechanics::CreatureStats);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
stats->mAttributes[0].set (ref->base->data.strength);
|
||||
stats->mAttributes[1].set (ref->base->data.intelligence);
|
||||
stats->mAttributes[2].set (ref->base->data.willpower);
|
||||
stats->mAttributes[3].set (ref->base->data.agility);
|
||||
stats->mAttributes[4].set (ref->base->data.speed);
|
||||
stats->mAttributes[5].set (ref->base->data.endurance);
|
||||
stats->mAttributes[6].set (ref->base->data.personality);
|
||||
stats->mAttributes[7].set (ref->base->data.luck);
|
||||
stats->mDynamic[0].set (ref->base->data.health);
|
||||
stats->mDynamic[1].set (ref->base->data.mana);
|
||||
stats->mDynamic[2].set (ref->base->data.fatigue);
|
||||
|
||||
stats->mLevel = ref->base->data.level;
|
||||
|
||||
ptr.getRefData().getCreatureStats() = stats;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getCreatureStats();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
|
||||
|
@ -108,17 +121,9 @@ namespace MWClass
|
|||
MWWorld::ContainerStore<MWWorld::RefData>& Creature::getContainerStore (const MWWorld::Ptr& ptr)
|
||||
const
|
||||
{
|
||||
if (!ptr.getRefData().getContainerStore().get())
|
||||
{
|
||||
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
|
||||
new MWWorld::ContainerStore<MWWorld::RefData>);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
// TODO add initial content
|
||||
|
||||
ptr.getRefData().getContainerStore() = store;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getContainerStore();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
}
|
||||
|
||||
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace MWClass
|
|||
{
|
||||
class Creature : public MWWorld::Class
|
||||
{
|
||||
void ensureCustomData (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
|
@ -25,7 +23,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
@ -39,13 +37,11 @@ namespace MWClass
|
|||
ESMS::LiveCellRef<ESM::Door, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Door>();
|
||||
|
||||
|
||||
const std::string &model = ref->base->model;
|
||||
assert (ref->base != NULL);
|
||||
if(!model.empty()){
|
||||
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string Door::getName (const MWWorld::Ptr& ptr) const
|
||||
|
@ -86,7 +82,7 @@ namespace MWClass
|
|||
}
|
||||
else
|
||||
{
|
||||
// another NPC or a create is using the door
|
||||
// another NPC or a creature is using the door
|
||||
// TODO return action for teleporting other NPC/creature
|
||||
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_DOOR_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
@ -34,14 +35,11 @@ namespace MWClass
|
|||
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
|
||||
|
||||
|
||||
const std::string &model = ref->base->model;
|
||||
assert (ref->base != NULL);
|
||||
if(!model.empty()){
|
||||
physics.insertObjectPhysics(ptr, "meshes\\" + model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string Ingredient::getName (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_INGREDIENT_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -23,7 +25,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_LIGHT_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -19,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_LOCKPICK_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -19,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_MISC_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -1,27 +1,88 @@
|
|||
|
||||
#include "npc.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontalk.hpp"
|
||||
#include "../mwworld/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||
#include <OgreSceneNode.h>
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/customdata.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
const Ogre::Radian kOgrePi (Ogre::Math::PI);
|
||||
const Ogre::Radian kOgrePiOverTwo (Ogre::Math::PI / Ogre::Real(2.0));
|
||||
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWMechanics::NpcStats mNpcStats;
|
||||
MWMechanics::CreatureStats mCreatureStats;
|
||||
MWMechanics::Movement mMovement;
|
||||
MWWorld::ContainerStore<MWWorld::RefData> mContainerStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
void Npc::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = ptr.get<ESM::NPC>();
|
||||
|
||||
// NPC stats
|
||||
if (!ref->base->faction.empty())
|
||||
{
|
||||
// TODO research how initial rank is stored. The information in loadnpc.hpp are at
|
||||
// best very unclear.
|
||||
data->mNpcStats.mFactionRank[ref->base->faction] = 0;
|
||||
}
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
|
||||
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
|
||||
data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility);
|
||||
data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed);
|
||||
data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance);
|
||||
data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality);
|
||||
data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck);
|
||||
data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health);
|
||||
data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana);
|
||||
data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue);
|
||||
|
||||
data->mCreatureStats.mLevel = ref->base->npdt52.level;
|
||||
|
||||
// \todo add initial container content
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Npc::getId (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
|
@ -77,56 +138,16 @@ namespace MWClass
|
|||
|
||||
MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCreatureStats().get())
|
||||
{
|
||||
boost::shared_ptr<MWMechanics::CreatureStats> stats (
|
||||
new MWMechanics::CreatureStats);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = ptr.get<ESM::NPC>();
|
||||
|
||||
stats->mAttributes[0].set (ref->base->npdt52.strength);
|
||||
stats->mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||
stats->mAttributes[2].set (ref->base->npdt52.willpower);
|
||||
stats->mAttributes[3].set (ref->base->npdt52.agility);
|
||||
stats->mAttributes[4].set (ref->base->npdt52.speed);
|
||||
stats->mAttributes[5].set (ref->base->npdt52.endurance);
|
||||
stats->mAttributes[6].set (ref->base->npdt52.personality);
|
||||
stats->mAttributes[7].set (ref->base->npdt52.luck);
|
||||
stats->mDynamic[0].set (ref->base->npdt52.health);
|
||||
stats->mDynamic[1].set (ref->base->npdt52.mana);
|
||||
stats->mDynamic[2].set (ref->base->npdt52.fatigue);
|
||||
|
||||
stats->mLevel = ref->base->npdt52.level;
|
||||
|
||||
ptr.getRefData().getCreatureStats() = stats;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getCreatureStats();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
}
|
||||
|
||||
MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getNpcStats().get())
|
||||
{
|
||||
boost::shared_ptr<MWMechanics::NpcStats> stats (
|
||||
new MWMechanics::NpcStats);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = ptr.get<ESM::NPC>();
|
||||
|
||||
if (!ref->base->faction.empty())
|
||||
{
|
||||
// TODO research how initial rank is stored. The information in loadnpc.hpp are at
|
||||
// best very unclear.
|
||||
stats->mFactionRank[ref->base->faction] = 0;
|
||||
}
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
stats->mSkill[i].setBase (ref->base->npdt52.skills[i]);
|
||||
|
||||
ptr.getRefData().getNpcStats() = stats;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getNpcStats();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Npc::activate (const MWWorld::Ptr& ptr,
|
||||
|
@ -138,17 +159,9 @@ namespace MWClass
|
|||
MWWorld::ContainerStore<MWWorld::RefData>& Npc::getContainerStore (const MWWorld::Ptr& ptr)
|
||||
const
|
||||
{
|
||||
if (!ptr.getRefData().getContainerStore().get())
|
||||
{
|
||||
boost::shared_ptr<MWWorld::ContainerStore<MWWorld::RefData> > store (
|
||||
new MWWorld::ContainerStore<MWWorld::RefData>);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
// TODO add initial content
|
||||
|
||||
ptr.getRefData().getContainerStore() = store;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getContainerStore();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
}
|
||||
|
||||
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
@ -239,29 +252,20 @@ namespace MWClass
|
|||
|
||||
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getMovement().get())
|
||||
{
|
||||
boost::shared_ptr<MWMechanics::Movement> movement (
|
||||
new MWMechanics::Movement);
|
||||
ensureCustomData (ptr);
|
||||
|
||||
ptr.getRefData().getMovement() = movement;
|
||||
}
|
||||
|
||||
return *ptr.getRefData().getMovement();
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
}
|
||||
|
||||
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
Ogre::Vector3 vector (0, 0, 0);
|
||||
|
||||
if (ptr.getRefData().getMovement().get())
|
||||
{
|
||||
vector.x = - ptr.getRefData().getMovement()->mLeftRight * 200;
|
||||
vector.y = ptr.getRefData().getMovement()->mForwardBackward * 200;
|
||||
vector.x = - getMovementSettings (ptr).mLeftRight * 200;
|
||||
vector.y = getMovementSettings (ptr).mForwardBackward * 200;
|
||||
|
||||
if (getStance (ptr, Run, false))
|
||||
vector *= 2;
|
||||
}
|
||||
if (getStance (ptr, Run, false))
|
||||
vector *= 2;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
class Npc : public MWWorld::Class
|
||||
{
|
||||
void ensureCustomData (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
public:
|
||||
|
||||
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_POTION_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
class Probe : public MWWorld::Class
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
namespace MWClass
|
||||
|
@ -19,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_REPAIR_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
@ -15,7 +16,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_STATIC_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
#include "containerutil.hpp"
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace MWClass
|
|||
|
||||
assert (ref->base != NULL);
|
||||
const std::string &model = ref->base->model;
|
||||
|
||||
|
||||
if (!model.empty())
|
||||
{
|
||||
MWRender::Objects& objects = renderingInterface.getObjects();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GAME_MWCLASS_WEAPON_H
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
|
||||
namespace MWClass
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
#include "ref.hpp"
|
||||
|
|
17
apps/openmw/mwworld/customdata.hpp
Normal file
17
apps/openmw/mwworld/customdata.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef GAME_MWWORLD_CUSTOMDATA_H
|
||||
#define GAME_MWWORLD_CUSTOMDATA_H
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
/// \brief Base class for the MW-class-specific part of RefData
|
||||
class CustomData
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~CustomData() {}
|
||||
|
||||
virtual CustomData *clone() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "../mwrender/player.hpp"
|
||||
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "world.hpp"
|
||||
#include "class.hpp"
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <boost/any.hpp>
|
||||
|
||||
#include <components/esm/loadcell.hpp>
|
||||
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
|
||||
#include "refdata.hpp"
|
||||
|
|
144
apps/openmw/mwworld/refdata.cpp
Normal file
144
apps/openmw/mwworld/refdata.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
|
||||
#include "refdata.hpp"
|
||||
|
||||
#include <components/esm_store/cell_store.hpp>
|
||||
|
||||
#include "customdata.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
void RefData::copy (const RefData& refData)
|
||||
{
|
||||
mBaseNode = refData.mBaseNode;
|
||||
mLocals = refData.mLocals;
|
||||
mHasLocals = refData.mHasLocals;
|
||||
mEnabled = refData.mEnabled;
|
||||
mCount = refData.mCount;
|
||||
mPosition = refData.mPosition;
|
||||
|
||||
mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0;
|
||||
}
|
||||
|
||||
void RefData::cleanup()
|
||||
{
|
||||
mBaseNode = 0;
|
||||
|
||||
delete mCustomData;
|
||||
mCustomData = 0;
|
||||
}
|
||||
|
||||
RefData::RefData (const ESM::CellRef& cellRef)
|
||||
: mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.pos),
|
||||
mCustomData (0)
|
||||
{}
|
||||
|
||||
RefData::RefData (const RefData& refData)
|
||||
: mBaseNode(0), mCustomData (0)
|
||||
{
|
||||
try
|
||||
{
|
||||
copy (refData);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cleanup();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
RefData::RefData& RefData::operator= (const RefData& refData)
|
||||
{
|
||||
try
|
||||
{
|
||||
cleanup();
|
||||
copy (refData);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cleanup();
|
||||
throw;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefData::~RefData()
|
||||
{
|
||||
try
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
}
|
||||
|
||||
std::string RefData::getHandle()
|
||||
{
|
||||
return mBaseNode->getName();
|
||||
}
|
||||
|
||||
Ogre::SceneNode* RefData::getBaseNode()
|
||||
{
|
||||
return mBaseNode;
|
||||
}
|
||||
|
||||
void RefData::setBaseNode(Ogre::SceneNode* base)
|
||||
{
|
||||
mBaseNode = base;
|
||||
}
|
||||
|
||||
int RefData::getCount() const
|
||||
{
|
||||
return mCount;
|
||||
}
|
||||
|
||||
void RefData::setLocals (const ESM::Script& script)
|
||||
{
|
||||
if (!mHasLocals)
|
||||
{
|
||||
mLocals.configure (script);
|
||||
mHasLocals = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RefData::setCount (int count)
|
||||
{
|
||||
mCount = count;
|
||||
}
|
||||
|
||||
MWScript::Locals& RefData::getLocals()
|
||||
{
|
||||
return mLocals;
|
||||
}
|
||||
|
||||
bool RefData::isEnabled() const
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
void RefData::enable()
|
||||
{
|
||||
mEnabled = true;
|
||||
}
|
||||
|
||||
void RefData::disable()
|
||||
{
|
||||
mEnabled = true;
|
||||
}
|
||||
|
||||
ESM::Position& RefData::getPosition()
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
void RefData::setCustomData (CustomData *data)
|
||||
{
|
||||
delete mCustomData;
|
||||
mCustomData = data;
|
||||
}
|
||||
|
||||
CustomData *RefData::getCustomData()
|
||||
{
|
||||
return mCustomData;
|
||||
}
|
||||
}
|
|
@ -3,24 +3,22 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <Ogre.h>
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
#include "../mwscript/locals.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "containerstore.hpp"
|
||||
#include <Ogre.h>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class Script;
|
||||
class CellRef;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class CustomData;
|
||||
|
||||
class RefData
|
||||
{
|
||||
Ogre::SceneNode* mBaseNode;
|
||||
|
@ -33,102 +31,58 @@ namespace MWWorld
|
|||
bool mEnabled;
|
||||
int mCount; // 0: deleted
|
||||
|
||||
// we are using shared pointer here to avoid having to create custom copy-constructor,
|
||||
// assignment operator and destructor. As a consequence though copying a RefData object
|
||||
// manually will probably give unexcepted results. This is not a problem since RefData
|
||||
// are never copied outside of container operations.
|
||||
boost::shared_ptr<MWMechanics::CreatureStats> mCreatureStats;
|
||||
boost::shared_ptr<MWMechanics::NpcStats> mNpcStats;
|
||||
boost::shared_ptr<MWMechanics::Movement> mMovement;
|
||||
|
||||
boost::shared_ptr<ContainerStore<RefData> > mContainerStore;
|
||||
|
||||
ESM::Position mPosition;
|
||||
|
||||
CustomData *mCustomData;
|
||||
|
||||
void copy (const RefData& refData);
|
||||
|
||||
void cleanup();
|
||||
|
||||
public:
|
||||
/// @param cr Used to copy constant data such as position into this class where it can
|
||||
/// be altered without effecting the original data. This makes it possible
|
||||
/// to reset the position as the orignal data is still held in the CellRef
|
||||
RefData(const ESMS::CellRef& cr) : mBaseNode(0), mHasLocals (false), mEnabled (true),
|
||||
mCount (1), mPosition(cr.pos) {}
|
||||
|
||||
/// @param cellRef Used to copy constant data such as position into this class where it can
|
||||
/// be altered without effecting the original data. This makes it possible
|
||||
/// to reset the position as the orignal data is still held in the CellRef
|
||||
RefData (const ESM::CellRef& cellRef);
|
||||
|
||||
std::string getHandle()
|
||||
{
|
||||
return mBaseNode->getName();
|
||||
}
|
||||
Ogre::SceneNode* getBaseNode(){
|
||||
return mBaseNode;
|
||||
}
|
||||
void setBaseNode(Ogre::SceneNode* base){
|
||||
mBaseNode = base;
|
||||
}
|
||||
RefData (const RefData& refData);
|
||||
|
||||
int getCount() const
|
||||
{
|
||||
return mCount;
|
||||
}
|
||||
~RefData();
|
||||
|
||||
void setLocals (const ESM::Script& script)
|
||||
{
|
||||
if (!mHasLocals)
|
||||
{
|
||||
mLocals.configure (script);
|
||||
mHasLocals = true;
|
||||
}
|
||||
}
|
||||
RefData& operator= (const RefData& refData);
|
||||
|
||||
/// Return OGRE handle (may be empty).
|
||||
std::string getHandle();
|
||||
|
||||
void setCount (int count)
|
||||
{
|
||||
mCount = count;
|
||||
}
|
||||
/// Return OGRE base node (can be a null pointer).
|
||||
Ogre::SceneNode* getBaseNode();
|
||||
|
||||
MWScript::Locals& getLocals()
|
||||
{
|
||||
return mLocals;
|
||||
}
|
||||
/// Set OGRE base node (can be a null pointer).
|
||||
void setBaseNode (Ogre::SceneNode* base);
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
int getCount() const;
|
||||
|
||||
void enable()
|
||||
{
|
||||
mEnabled = true;
|
||||
}
|
||||
void setLocals (const ESM::Script& script);
|
||||
|
||||
void disable()
|
||||
{
|
||||
mEnabled = true;
|
||||
}
|
||||
void setCount (int count);
|
||||
|
||||
boost::shared_ptr<MWMechanics::CreatureStats>& getCreatureStats()
|
||||
{
|
||||
return mCreatureStats;
|
||||
}
|
||||
MWScript::Locals& getLocals();
|
||||
|
||||
boost::shared_ptr<MWMechanics::NpcStats>& getNpcStats()
|
||||
{
|
||||
return mNpcStats;
|
||||
}
|
||||
bool isEnabled() const;
|
||||
|
||||
boost::shared_ptr<MWMechanics::Movement>& getMovement()
|
||||
{
|
||||
return mMovement;
|
||||
}
|
||||
void enable();
|
||||
|
||||
boost::shared_ptr<ContainerStore<RefData> >& getContainerStore()
|
||||
{
|
||||
return mContainerStore;
|
||||
}
|
||||
void disable();
|
||||
|
||||
ESM::Position& getPosition()
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
ESM::Position& getPosition();
|
||||
|
||||
void setCustomData (CustomData *data);
|
||||
///< Set custom data (potentially replacing old custom data). The ownership of \æ data is
|
||||
/// transferred to this.
|
||||
|
||||
CustomData *getCustomData();
|
||||
///< May return a 0-pointer. The ownership of the return data object is not transferred.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "store.hpp"
|
||||
#include "components/esm/records.hpp"
|
||||
#include "components/esm/loadcell.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
@ -36,7 +35,7 @@ namespace ESMS
|
|||
{
|
||||
LiveCellRef(const CellRef& cref, const X* b = NULL) : base(b), ref(cref),
|
||||
mData(ref) {}
|
||||
|
||||
|
||||
|
||||
LiveCellRef(const X* b = NULL) : base(b), mData(ref) {}
|
||||
|
||||
|
@ -187,7 +186,7 @@ namespace ESMS
|
|||
++iter)
|
||||
if (!functor (iter->ref, iter->mData))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue