From 0a60bde83406b7dbbf34a24b57f066ecbb834511 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 6 Aug 2010 22:20:20 +0200 Subject: [PATCH 1/8] added insertIntoContainer function to class hierarchy --- apps/openmw/CMakeLists.txt | 1 + apps/openmw/mwclass/apparatus.cpp | 8 +++++++ apps/openmw/mwclass/apparatus.hpp | 4 ++++ apps/openmw/mwclass/armor.cpp | 8 +++++++ apps/openmw/mwclass/armor.hpp | 4 ++++ apps/openmw/mwclass/book.cpp | 8 +++++++ apps/openmw/mwclass/book.hpp | 4 ++++ apps/openmw/mwclass/clothing.cpp | 8 +++++++ apps/openmw/mwclass/clothing.hpp | 4 ++++ apps/openmw/mwclass/containerutil.hpp | 31 +++++++++++++++++++++++++++ apps/openmw/mwclass/ingredient.cpp | 8 +++++++ apps/openmw/mwclass/ingredient.hpp | 4 ++++ apps/openmw/mwclass/light.cpp | 8 +++++++ apps/openmw/mwclass/light.hpp | 4 ++++ apps/openmw/mwclass/lockpick.cpp | 8 +++++++ apps/openmw/mwclass/lockpick.hpp | 4 ++++ apps/openmw/mwclass/misc.cpp | 8 +++++++ apps/openmw/mwclass/misc.hpp | 4 ++++ apps/openmw/mwclass/potion.cpp | 8 +++++++ apps/openmw/mwclass/potion.hpp | 4 ++++ apps/openmw/mwclass/probe.cpp | 8 +++++++ apps/openmw/mwclass/probe.hpp | 4 ++++ apps/openmw/mwclass/repair.cpp | 8 +++++++ apps/openmw/mwclass/repair.hpp | 4 ++++ apps/openmw/mwclass/weapon.cpp | 8 +++++++ apps/openmw/mwclass/weapon.hpp | 4 ++++ apps/openmw/mwworld/class.cpp | 7 +++++- apps/openmw/mwworld/class.hpp | 5 +++++ 28 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 apps/openmw/mwclass/containerutil.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c9112b0ee..c41ffb50b 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -141,6 +141,7 @@ set(GAMECLASS_HEADER mwclass/probe.hpp mwclass/repair.hpp mwclass/static.hpp + mwclass/containerutil.hpp ) source_group(apps\\openmw\\mwclass FILES ${GAMECLASS} ${GAMECLASS_HEADER}) diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 066eacd3f..fb2080ded 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Apparatus::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Apparatus::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.appas); + } + std::string Apparatus::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 7b3ccff6a..16d41a34a 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 786868c81..4c0550362 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Armor::getName (const MWWorld::Ptr& ptr) const @@ -30,6 +32,12 @@ namespace MWClass return ref->base->data.health; } + void Armor::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.armors); + } + std::string Armor::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index ebae75a9f..8b6c6e163 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -19,6 +19,10 @@ namespace MWClass virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const; ///< Return item max health or throw an exception, if class does not have item health + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 9c0a48409..8faef5494 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Book::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Book::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.books); + } + std::string Book::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index d45f569b5..c79545d55 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 2c0d76fb3..f1c769cd4 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Clothing::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Clothing::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.clothes); + } + std::string Clothing::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 09b66b92d..bd57f7849 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/containerutil.hpp b/apps/openmw/mwclass/containerutil.hpp new file mode 100644 index 000000000..5f89983ac --- /dev/null +++ b/apps/openmw/mwclass/containerutil.hpp @@ -0,0 +1,31 @@ +#ifndef GAME_MWCLASS_CONTAINERUTIL_H +#define GAME_MWCLASS_CONTAINERUTIL_H + +#include + +#include "../mwworld/ptr.hpp" +#include "../mwworld/containerstore.hpp" + +namespace MWClass +{ + template + void insertIntoContainerStore (const MWWorld::Ptr& ptr, + ESMS::CellRefList& containerStore) + { + if (!ptr.isEmpty()) + { + // TODO check stacking + + ESMS::LiveCellRef cellRef; + + cellRef.base = ptr.get()->base; + cellRef.ref = ptr.getCellRef(); + cellRef.mData = ptr.getRefData(); + + containerStore.list.push_back (cellRef); + + } + } +} + +#endif diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 81d19b2fa..7389ec5a7 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Ingredient::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Ingredient::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.ingreds); + } + std::string Ingredient::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index c2edd9484..8e1e14198 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 98e0b01b4..405aa2745 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Light::getName (const MWWorld::Ptr& ptr) const @@ -20,6 +22,12 @@ namespace MWClass return ref->base->name; } + void Light::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.lights); + } + std::string Light::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 08c3ddf7c..9627d5918 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index ce57e0c99..7062a0367 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Lockpick::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Lockpick::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.lockpicks); + } + std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index e009e9fdd..d9c8147e9 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index dda21aaa7..2d6614776 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Misc::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Misc::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.miscItems); + } + std::string Misc::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 526235aa0..ec61c5f3e 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index f8e9ee0a0..b368f5cb2 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Potion::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Potion::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.potions); + } + std::string Potion::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index c851d1b4e..ff1408533 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 3c22e4c7f..19f9ac8b2 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Probe::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Probe::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.probes); + } + std::string Probe::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 84e93d1ce..cf77700c7 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index f22b8607a..463daedfd 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Repair::getName (const MWWorld::Ptr& ptr) const @@ -17,6 +19,12 @@ namespace MWClass return ref->base->name; } + void Repair::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.repairs); + } + std::string Repair::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 803e21d51..c9619fb74 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index a7fce960c..471ae2634 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "containerutil.hpp" + namespace MWClass { std::string Weapon::getName (const MWWorld::Ptr& ptr) const @@ -30,6 +32,12 @@ namespace MWClass return ref->base->data.health; } + void Weapon::insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const + { + insertIntoContainerStore (ptr, containerStore.weapons); + } + std::string Weapon::getScript (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 01b6f8e13..1321fc962 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -19,6 +19,10 @@ namespace MWClass virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const; ///< Return item max health or throw an exception, if class does not have item health + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, + MWWorld::ContainerStore& containerStore) const; + ///< Insert into a containe + virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index f3b231974..85e5140ea 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -44,7 +44,12 @@ namespace MWWorld ContainerStore& Class::getContainerStore (const Ptr& ptr) const { throw std::runtime_error ("class does not have a container store"); - } + } + + void Class::insertIntoContainer (const Ptr& ptr, ContainerStore& containerStore) const + { + throw std::runtime_error ("class does not support inserting into a container"); + } std::string Class::getScript (const Ptr& ptr) const { diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 86345edd5..28d96d69f 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -64,6 +64,11 @@ namespace MWWorld ///< Return container store or throw an exception, if class does not have a /// container store (default implementation: throw an exceoption) + virtual void insertIntoContainer (const Ptr& ptr, ContainerStore& containerStore) + const; + ///< Insert into a container or throw an exception, if class does not support inserting into + /// a container. + virtual std::string getScript (const Ptr& ptr) const; ///< Return name of the script attached to ptr (default implementation: return an empty /// string). From 3ea85b46193aa5cf840fa1e94c36b8013d206e0b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 15:11:31 +0200 Subject: [PATCH 2/8] added AddItem instruction --- apps/openmw/CMakeLists.txt | 3 + apps/openmw/mwscript/containerextensions.cpp | 88 ++++++++++++++++++++ apps/openmw/mwscript/containerextensions.hpp | 25 ++++++ apps/openmw/mwscript/docs/vmformat.txt | 4 +- apps/openmw/mwscript/extensions.cpp | 8 +- apps/openmw/mwworld/manualref.hpp | 86 +++++++++++++++++++ 6 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 apps/openmw/mwscript/containerextensions.cpp create mode 100644 apps/openmw/mwscript/containerextensions.hpp create mode 100644 apps/openmw/mwworld/manualref.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c41ffb50b..a4883b77d 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -51,6 +51,7 @@ set(GAMESCRIPT mwscript/soundextensions.cpp mwscript/skyextensions.cpp mwscript/statsextensions.cpp + mwscript/containerextensions.cpp mwscript/extensions.cpp mwscript/globalscripts.cpp ) @@ -65,6 +66,7 @@ set(GAMESCRIPT_HEADER mwscript/soundextensions.hpp mwscript/skyextensions.hpp mwscript/statsextensions.hpp + mwscript/containerextensions.hpp mwscript/extensions.hpp mwscript/globalscripts.hpp ) @@ -93,6 +95,7 @@ set(GAMEWORLD_HEADER mwworld/nullaction.hpp mwworld/actionteleport.hpp mwworld/containerstore.hpp + mwworld/manualref.hpp ) source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp new file mode 100644 index 000000000..73111145b --- /dev/null +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -0,0 +1,88 @@ + +#include "containerextensions.hpp" + +#include + +#include +#include +#include + +#include "../mwworld/manualref.hpp" +#include "../mwworld/class.hpp" + +#include "interpretercontext.hpp" + +namespace MWScript +{ + namespace Container + { + class OpAddItem : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); + + MWWorld::Ptr ptr = context.getReference(); + + MWWorld::ManualRef ref (context.getWorld().getStore(), item); + + ref.getPtr().getRefData().setCount (count); + + MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(), + MWWorld::Class::get (ptr).getContainerStore (ptr)); + } + }; + + class OpAddItemExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); + + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + + MWWorld::ManualRef ref (context.getWorld().getStore(), item); + + ref.getPtr().getRefData().setCount (count); + + MWWorld::Class::get (ref.getPtr()).insertIntoContainer (ref.getPtr(), + MWWorld::Class::get (ptr).getContainerStore (ptr)); + } + }; + + const int opcodeAddItem = 0x2000076; + const int opcodeAddItemExplicit = 0x2000077; + + void registerExtensions (Compiler::Extensions& extensions) + { + extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit); + } + + void installOpcodes (Interpreter::Interpreter& interpreter) + { + interpreter.installSegment5 (opcodeAddItem, new OpAddItem); + interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItemExplicit); + } + } +} diff --git a/apps/openmw/mwscript/containerextensions.hpp b/apps/openmw/mwscript/containerextensions.hpp new file mode 100644 index 000000000..f99a71b4d --- /dev/null +++ b/apps/openmw/mwscript/containerextensions.hpp @@ -0,0 +1,25 @@ +#ifndef GAME_SCRIPT_CONTAINEREXTENSIONS_H +#define GAME_SCRIPT_CONTAINEREXTENSIONS_H + +namespace Compiler +{ + class Extensions; +} + +namespace Interpreter +{ + class Interpreter; +} + +namespace MWScript +{ + /// \brief stats-related script functionality (creatures and NPCs) + namespace Container + { + void registerExtensions (Compiler::Extensions& extensions); + + void installOpcodes (Interpreter::Interpreter& interpreter); + } +} + +#endif diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 5807f26d4..e2de2cbc1 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -77,4 +77,6 @@ op 0x200006c-0x200006e: ModDynamic (health, magicka, fatigue), explicit referenc op 0x200006f-0x2000071: GetDynamic (health, magicka, fatigue) op 0x2000072-0x2000074: GetDynamic (health, magicka, fatigue), explicit reference op 0x2000075: Activate -opcodes 0x2000076-0x3ffffff unused +op 0x2000076: AddItem +op 0x2000077: AddItem, explicit reference +opcodes 0x2000078-0x3ffffff unused diff --git a/apps/openmw/mwscript/extensions.cpp b/apps/openmw/mwscript/extensions.cpp index 3abaac58c..1b3d3df14 100644 --- a/apps/openmw/mwscript/extensions.cpp +++ b/apps/openmw/mwscript/extensions.cpp @@ -10,6 +10,7 @@ #include "guiextensions.hpp" #include "skyextensions.hpp" #include "statsextensions.hpp" +#include "containerextensions.hpp" namespace MWScript { @@ -21,8 +22,9 @@ namespace MWScript Sound::registerExtensions (extensions); Sky::registerExtensions (extensions); Stats::registerExtensions (extensions); + Container::registerExtensions (extensions); } - + void installOpcodes (Interpreter::Interpreter& interpreter) { Interpreter::installOpcodes (interpreter); @@ -32,6 +34,6 @@ namespace MWScript Sound::installOpcodes (interpreter); Sky::installOpcodes (interpreter); Stats::installOpcodes (interpreter); - } + Container::installOpcodes (interpreter); + } } - diff --git a/apps/openmw/mwworld/manualref.hpp b/apps/openmw/mwworld/manualref.hpp new file mode 100644 index 000000000..4b7edfa43 --- /dev/null +++ b/apps/openmw/mwworld/manualref.hpp @@ -0,0 +1,86 @@ +#ifndef GAME_MWWORLD_MANUALREF_H +#define GAME_MWWORLD_MANUALREF_H + +#include + +#include +#include + +#include "ptr.hpp" + +namespace MWWorld +{ + /// \brief Manually constructed live cell ref + class ManualRef + { + boost::any mRef; + Ptr mPtr; + + ManualRef (const ManualRef&); + ManualRef& operator= (const ManualRef&); + + template + bool create (const ESMS::RecListT& list, const std::string& name) + { + if (const T *instance = list.search (name)) + { + ESMS::LiveCellRef ref; + ref.base = instance; + + mRef = ref; + mPtr = Ptr (&boost::any_cast&> (mRef), 0); + + return true; + } + + return false; + } + + public: + + ManualRef (const ESMS::ESMStore& store, const std::string& name) + { + // create + if (!create (store.activators, name) && + !create (store.potions, name) && + !create (store.appas, name) && + !create (store.armors, name) && + !create (store.books, name) && + !create (store.clothes, name) && + !create (store.containers, name) && + !create (store.creatures, name) && + !create (store.doors, name) && + !create (store.ingreds, name) && + !create (store.creatureLists, name) && + !create (store.itemLists, name) && + !create (store.lights, name) && + !create (store.lockpicks, name) && + !create (store.miscItems, name) && + !create (store.npcs, name) && + !create (store.probes, name) && + !create (store.repairs, name) && + !create (store.statics, name) && + !create (store.weapons, name)) + throw std::logic_error ("failed to create manual cell ref for " + name); + + // initialise + ESM::CellRef& cellRef = mPtr.getCellRef(); + cellRef.refnum = -1; + cellRef.scale = 1; + cellRef.factIndex = 0; + cellRef.charge = 0; + cellRef.intv = 0; + cellRef.nam9 = 0; + cellRef.teleport = false; + cellRef.lockLevel = 0; + cellRef.unam = 0; + } + + const Ptr& getPtr() const + { + return mPtr; + } + }; +} + +#endif From 589f8b5ede58b7ecc2327b6579da66ddba6a7d3b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 16:21:07 +0200 Subject: [PATCH 3/8] added GetItemCount --- apps/openmw/CMakeLists.txt | 2 + apps/openmw/mwscript/containerextensions.cpp | 74 ++++++++++++++++++++ apps/openmw/mwscript/docs/vmformat.txt | 4 +- apps/openmw/mwworld/containerutil.cpp | 43 ++++++++++++ apps/openmw/mwworld/containerutil.hpp | 20 ++++++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 apps/openmw/mwworld/containerutil.cpp create mode 100644 apps/openmw/mwworld/containerutil.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a4883b77d..7e3532f41 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -83,6 +83,7 @@ set(GAMEWORLD mwworld/globals.cpp mwworld/class.cpp mwworld/actionteleport.cpp + mwworld/containerutil.cpp ) set(GAMEWORLD_HEADER mwworld/refdata.hpp @@ -96,6 +97,7 @@ set(GAMEWORLD_HEADER mwworld/actionteleport.hpp mwworld/containerstore.hpp mwworld/manualref.hpp + mwworld/containerutil.hpp ) source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER}) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 73111145b..dad88a7e1 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -9,6 +9,7 @@ #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerutil.hpp" #include "interpretercontext.hpp" @@ -71,18 +72,91 @@ namespace MWScript } }; + class OpGetItemCount : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWWorld::Ptr ptr = context.getReference(); + + std::vector list; + + MWWorld::listItemsInContainer (item, + MWWorld::Class::get (ptr).getContainerStore (ptr), + context.getWorld().getStore(), list); + + Interpreter::Type_Integer sum = 0; + + for (std::vector::iterator iter (list.begin()); iter!=list.end(); + ++iter) + { + sum += iter->getRefData().getCount(); + } + + runtime.push (sum); + } + }; + + class OpGetItemCountExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + + std::vector list; + + MWWorld::listItemsInContainer (item, + MWWorld::Class::get (ptr).getContainerStore (ptr), + context.getWorld().getStore(), list); + + Interpreter::Type_Integer sum = 0; + + for (std::vector::iterator iter (list.begin()); iter!=list.end(); + ++iter) + { + sum += iter->getRefData().getCount(); + } + + runtime.push (sum); + } + }; + const int opcodeAddItem = 0x2000076; const int opcodeAddItemExplicit = 0x2000077; + const int opcodeGetItemCount = 0x2000078; + const int opcodeGetItemCountExplicit = 0x2000079; void registerExtensions (Compiler::Extensions& extensions) { extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit); + extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount, + opcodeGetItemCountExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) { interpreter.installSegment5 (opcodeAddItem, new OpAddItem); interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItemExplicit); + interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount); + interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCountExplicit); } } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index e2de2cbc1..0b91bb8d5 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -79,4 +79,6 @@ op 0x2000072-0x2000074: GetDynamic (health, magicka, fatigue), explicit referenc op 0x2000075: Activate op 0x2000076: AddItem op 0x2000077: AddItem, explicit reference -opcodes 0x2000078-0x3ffffff unused +op 0x2000078: GetItemCount +op 0x2000079: GetItemCount, explicit reference +opcodes 0x200007a-0x3ffffff unused diff --git a/apps/openmw/mwworld/containerutil.cpp b/apps/openmw/mwworld/containerutil.cpp new file mode 100644 index 000000000..7c7e5e5e8 --- /dev/null +++ b/apps/openmw/mwworld/containerutil.cpp @@ -0,0 +1,43 @@ + +#include "containerutil.hpp" + +namespace +{ + template + void listItemsInContainerImp (const std::string& id, + ESMS::CellRefList& containerStore, + const ESMS::RecListT& store, std::vector& list) + { + if (const T *record = store.search (id)) + { + for (typename ESMS::CellRefList::List::iterator iter + (containerStore.list.begin()); + iter!=containerStore.list.end(); ++iter) + { + if (iter->base==record) + list.push_back (MWWorld::Ptr (&*iter, 0)); + } + } + } +} + +namespace MWWorld +{ + void listItemsInContainer (const std::string& id, + ContainerStore& containerStore, + const ESMS::ESMStore& store, std::vector& list) + { + listItemsInContainerImp (id, containerStore.potions, store.potions, list); + listItemsInContainerImp (id, containerStore.appas, store.appas, list); + listItemsInContainerImp (id, containerStore.armors, store.armors, list); + listItemsInContainerImp (id, containerStore.books, store.books, list); + listItemsInContainerImp (id, containerStore.clothes, store.clothes, list); + listItemsInContainerImp (id, containerStore.ingreds, store.ingreds, list); + listItemsInContainerImp (id, containerStore.lights, store.lights, list); + listItemsInContainerImp (id, containerStore.lockpicks, store.lockpicks, list); + listItemsInContainerImp (id, containerStore.miscItems, store.miscItems, list); + listItemsInContainerImp (id, containerStore.probes, store.probes, list); + listItemsInContainerImp (id, containerStore.repairs, store.repairs, list); + listItemsInContainerImp (id, containerStore.weapons, store.weapons, list); + } +} diff --git a/apps/openmw/mwworld/containerutil.hpp b/apps/openmw/mwworld/containerutil.hpp new file mode 100644 index 000000000..21e770404 --- /dev/null +++ b/apps/openmw/mwworld/containerutil.hpp @@ -0,0 +1,20 @@ +#ifndef GAME_MWWORLD_CONTAINERUTIL_H +#define GAME_MWWORLD_CONTAINERUTIL_H + +#include +#include + +#include + +#include "containerstore.hpp" +#include "ptr.hpp" +#include "refdata.hpp" + +namespace MWWorld +{ + void listItemsInContainer (const std::string& id, ContainerStore& containerStore, + const ESMS::ESMStore& store, std::vector& list); + ///< append all references with the given id to list. +} + +#endif From db24a55e365544cb17558a01714a16a7c4c0fe59 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 16:34:49 +0200 Subject: [PATCH 4/8] added sanity check for AddItem arguments --- apps/openmw/mwscript/containerextensions.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index dad88a7e1..c9601e594 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -1,6 +1,8 @@ #include "containerextensions.hpp" +#include + #include #include @@ -32,6 +34,9 @@ namespace MWScript Interpreter::Type_Integer count = runtime[0].mInteger; runtime.pop(); + if (count<0) + throw std::runtime_error ("second argument for AddItem must be non-negative"); + MWWorld::Ptr ptr = context.getReference(); MWWorld::ManualRef ref (context.getWorld().getStore(), item); @@ -61,6 +66,9 @@ namespace MWScript Interpreter::Type_Integer count = runtime[0].mInteger; runtime.pop(); + if (count<0) + throw std::runtime_error ("second argument for AddItem must be non-negative"); + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); MWWorld::ManualRef ref (context.getWorld().getStore(), item); From aa637cb9d4258a46af233b106b9d9c3f85e9b524 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 17:00:04 +0200 Subject: [PATCH 5/8] added RemoveItem --- apps/openmw/mwscript/containerextensions.cpp | 103 +++++++++++++++++++ apps/openmw/mwscript/docs/vmformat.txt | 4 +- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index c9601e594..1121d8eff 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -147,16 +147,117 @@ namespace MWScript } }; + class OpRemoveItem : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); + + if (count<0) + throw std::runtime_error ("second argument for RemoveItem must be non-negative"); + + MWWorld::Ptr ptr = context.getReference(); + + std::vector list; + + MWWorld::listItemsInContainer (item, + MWWorld::Class::get (ptr).getContainerStore (ptr), + context.getWorld().getStore(), list); + + for (std::vector::iterator iter (list.begin()); + iter!=list.end() && count; + ++iter) + { + if (iter->getRefData().getCount()<=count) + { + count -= iter->getRefData().getCount(); + iter->getRefData().setCount (0); + } + else + { + iter->getRefData().setCount (iter->getRefData().getCount()-count); + count = 0; + } + } + + // To be fully compatible with original Morrowind, we would need to check if + // count is >= 0 here and throw an exception. But let's be tollerant instead. + } + }; + + class OpRemoveItemExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + std::string item = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); + + if (count<0) + throw std::runtime_error ("second argument for RemoveItem must be non-negative"); + + MWWorld::Ptr ptr = context.getWorld().getPtr (id, false); + + std::vector list; + + MWWorld::listItemsInContainer (item, + MWWorld::Class::get (ptr).getContainerStore (ptr), + context.getWorld().getStore(), list); + + for (std::vector::iterator iter (list.begin()); + iter!=list.end() && count; + ++iter) + { + if (iter->getRefData().getCount()<=count) + { + count -= iter->getRefData().getCount(); + iter->getRefData().setCount (0); + } + else + { + iter->getRefData().setCount (iter->getRefData().getCount()-count); + count = 0; + } + } + + // To be fully compatible with original Morrowind, we would need to check if + // count is >= 0 here and throw an exception. But let's be tollerant instead. + } + }; + const int opcodeAddItem = 0x2000076; const int opcodeAddItemExplicit = 0x2000077; const int opcodeGetItemCount = 0x2000078; const int opcodeGetItemCountExplicit = 0x2000079; + const int opcodeRemoveItem = 0x200007a; + const int opcodeRemoveItemExplicit = 0x200007b; void registerExtensions (Compiler::Extensions& extensions) { extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit); extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount, opcodeGetItemCountExplicit); + extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem, + opcodeRemoveItemExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -165,6 +266,8 @@ namespace MWScript interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItemExplicit); interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount); interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCountExplicit); + interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem); + interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItemExplicit); } } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 0b91bb8d5..70e5fe8c2 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -81,4 +81,6 @@ op 0x2000076: AddItem op 0x2000077: AddItem, explicit reference op 0x2000078: GetItemCount op 0x2000079: GetItemCount, explicit reference -opcodes 0x200007a-0x3ffffff unused +op 0x200007a: RemoveItem +op 0x200007b: RemoveItem, explicit reference +opcodes 0x200007c-0x3ffffff unused From a7fe28ecbe4d02aaaf11b32d38a89b272ff10fdf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 20:25:17 +0200 Subject: [PATCH 6/8] implemented take action --- apps/openmw/CMakeLists.txt | 2 ++ apps/openmw/mwclass/apparatus.cpp | 8 ++++++++ apps/openmw/mwclass/apparatus.hpp | 4 ++++ apps/openmw/mwclass/armor.cpp | 8 ++++++++ apps/openmw/mwclass/armor.hpp | 4 ++++ apps/openmw/mwclass/book.cpp | 10 ++++++++++ apps/openmw/mwclass/book.hpp | 4 ++++ apps/openmw/mwclass/clothing.cpp | 8 ++++++++ apps/openmw/mwclass/clothing.hpp | 4 ++++ apps/openmw/mwclass/ingredient.cpp | 8 ++++++++ apps/openmw/mwclass/ingredient.hpp | 4 ++++ apps/openmw/mwclass/light.cpp | 15 +++++++++++++++ apps/openmw/mwclass/light.hpp | 4 ++++ apps/openmw/mwclass/lockpick.cpp | 8 ++++++++ apps/openmw/mwclass/lockpick.hpp | 4 ++++ apps/openmw/mwclass/misc.cpp | 8 ++++++++ apps/openmw/mwclass/misc.hpp | 4 ++++ apps/openmw/mwclass/potion.cpp | 8 ++++++++ apps/openmw/mwclass/potion.hpp | 4 ++++ apps/openmw/mwclass/probe.cpp | 8 ++++++++ apps/openmw/mwclass/probe.hpp | 4 ++++ apps/openmw/mwclass/repair.cpp | 8 ++++++++ apps/openmw/mwclass/repair.hpp | 4 ++++ apps/openmw/mwclass/weapon.cpp | 8 ++++++++ apps/openmw/mwclass/weapon.hpp | 4 ++++ apps/openmw/mwrender/cell.hpp | 22 ++++++++++++---------- apps/openmw/mwrender/interior.cpp | 10 ++++++++++ apps/openmw/mwrender/interior.hpp | 8 +++++--- apps/openmw/mwworld/actiontake.cpp | 23 +++++++++++++++++++++++ apps/openmw/mwworld/actiontake.hpp | 21 +++++++++++++++++++++ apps/openmw/mwworld/world.cpp | 21 +++++++++++++++++++++ apps/openmw/mwworld/world.hpp | 2 ++ 32 files changed, 249 insertions(+), 13 deletions(-) create mode 100644 apps/openmw/mwworld/actiontake.cpp create mode 100644 apps/openmw/mwworld/actiontake.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 7e3532f41..359a83e4f 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -83,6 +83,7 @@ set(GAMEWORLD mwworld/globals.cpp mwworld/class.cpp mwworld/actionteleport.cpp + mwworld/actiontake.cpp mwworld/containerutil.cpp ) set(GAMEWORLD_HEADER @@ -95,6 +96,7 @@ set(GAMEWORLD_HEADER mwworld/action.hpp mwworld/nullaction.hpp mwworld/actionteleport.hpp + mwworld/actiontake.hpp mwworld/containerstore.hpp mwworld/manualref.hpp mwworld/containerutil.hpp diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index fb2080ded..4b94d78d1 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Apparatus::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Apparatus::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 16d41a34a..4a514c94d 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 4c0550362..f4236b5f6 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + bool Armor::hasItemHealth (const MWWorld::Ptr& ptr) const { return true; diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 8b6c6e163..217a74a76 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const; ///< \return Item health data available? diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 8faef5494..3bea7d5b9 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,15 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Book::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + // TODO implement reading + + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Book::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index c79545d55..3f15e2278 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index f1c769cd4..c0e43bc3e 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Clothing::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index bd57f7849..ea358be68 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 7389ec5a7..9162384af 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Ingredient::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 8e1e14198..d742fae8b 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 405aa2745..7cb363bf8 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -6,6 +6,8 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" +#include "../mwworld/nullaction.hpp" #include "containerutil.hpp" @@ -22,6 +24,19 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Light::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + if (!(ref->base->data.flags & ESM::Light::Carry)) + return boost::shared_ptr (new MWWorld::NullAction); + + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Light::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 9627d5918..6d08d557c 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 7062a0367..ab1969480 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Lockpick::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index d9c8147e9..e15d9daee 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 2d6614776..f29a0be1f 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Misc::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Misc::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index ec61c5f3e..01542baed 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index b368f5cb2..0799b2031 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Potion::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index ff1408533..208c26c56 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 19f9ac8b2..08ec391a8 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Probe::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index cf77700c7..c17d53dab 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 463daedfd..9ed7f0e77 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + void Repair::insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const { diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index c9619fb74..52d045ebe 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual void insertIntoContainer (const MWWorld::Ptr& ptr, MWWorld::ContainerStore& containerStore) const; ///< Insert into a containe diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 471ae2634..c292c32dd 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/actiontake.hpp" #include "containerutil.hpp" @@ -19,6 +20,13 @@ namespace MWClass return ref->base->name; } + boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const + { + return boost::shared_ptr ( + new MWWorld::ActionTake (ptr)); + } + bool Weapon::hasItemHealth (const MWWorld::Ptr& ptr) const { return true; diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 1321fc962..6bc96381c 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -13,6 +13,10 @@ namespace MWClass ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. + virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const; + ///< Generate action for activation + virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const; ///< \return Item health data available? diff --git a/apps/openmw/mwrender/cell.hpp b/apps/openmw/mwrender/cell.hpp index d6dd944ca..8fa3f9f0f 100644 --- a/apps/openmw/mwrender/cell.hpp +++ b/apps/openmw/mwrender/cell.hpp @@ -3,31 +3,33 @@ #include -namespace MWRender +namespace MWRender { class CellRender { - public: - + public: + virtual ~CellRender() {}; - + /// Make the cell visible. Load the cell if necessary. virtual void show() = 0; - + /// Remove the cell from rendering, but don't remove it from /// memory. - virtual void hide() = 0; - + virtual void hide() = 0; + /// Destroy all rendering objects connected with this cell. virtual void destroy() = 0; - + /// Make the reference with the given handle visible. virtual void enable (const std::string& handle) = 0; - + /// Make the reference with the given handle invisible. virtual void disable (const std::string& handle) = 0; + + /// Remove the reference with the given handle permanently from the scene. + virtual void deleteObject (const std::string& handle) = 0; }; } #endif - diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index c67bc8878..d559a1216 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -237,6 +237,16 @@ void InteriorCellRender::disable (const std::string& handle) scene.getMgr()->getSceneNode (handle)->setVisible (false); } +void InteriorCellRender::deleteObject (const std::string& handle) +{ + if (!handle.empty()) + { + Ogre::SceneNode *node = scene.getMgr()->getSceneNode (handle); + node->removeAndDestroyAllChildren(); + scene.getMgr()->destroySceneNode (node); + } +} + // Magic function from the internets. Might need this later. /* void Scene::DestroyAllAttachedMovableObjects( SceneNode* i_pSceneNode ) diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index 0ef5ec85c..3d375f7f2 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -99,11 +99,13 @@ namespace MWRender /// Make the reference with the given handle visible. virtual void enable (const std::string& handle); - + /// Make the reference with the given handle invisible. - virtual void disable (const std::string& handle); + virtual void disable (const std::string& handle); + + /// Remove the reference with the given handle permanently from the scene. + virtual void deleteObject (const std::string& handle); }; } #endif - diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp new file mode 100644 index 000000000..b318f0796 --- /dev/null +++ b/apps/openmw/mwworld/actiontake.cpp @@ -0,0 +1,23 @@ + +#include "actiontake.hpp" + +#include "class.hpp" +#include "environment.hpp" +#include "world.hpp" + +namespace MWWorld +{ + ActionTake::ActionTake (const MWWorld::Ptr& object) : mObject (object) {} + + void ActionTake::execute (Environment& environment) + { + // insert into player's inventory + MWWorld::Ptr player = environment.mWorld->getPtr ("player", true); + + MWWorld::Class::get (mObject).insertIntoContainer (mObject, + MWWorld::Class::get (player).getContainerStore (player)); + + // remove from world + environment.mWorld->deleteObject (mObject); + } +} diff --git a/apps/openmw/mwworld/actiontake.hpp b/apps/openmw/mwworld/actiontake.hpp new file mode 100644 index 000000000..509ebc6bb --- /dev/null +++ b/apps/openmw/mwworld/actiontake.hpp @@ -0,0 +1,21 @@ +#ifndef GAME_MWWORLD_ACTIONTAKE_H +#define GAME_MWWORLD_ACTIONTAKE_H + +#include "action.hpp" +#include "ptr.hpp" + +namespace MWWorld +{ + class ActionTake : public Action + { + MWWorld::Ptr mObject; + + public: + + ActionTake (const MWWorld::Ptr& object); + + virtual void execute (Environment& environment); + }; +} + +#endif diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 1293d2daa..9b53f8111 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -611,4 +611,25 @@ namespace MWWorld return result.first; } + + void World::deleteObject (Ptr ptr) + { + if (ptr.getRefData().getCount()>0) + { + ptr.getRefData().setCount (0); + + if (MWRender::CellRender *render = searchRender (ptr.getCell())) + { + render->deleteObject (ptr.getRefData().getHandle()); + ptr.getRefData().setHandle (""); + + if (mActiveCells.find (ptr.getCell())!=mActiveCells.end() && + (ptr.getType()==typeid (ESMS::LiveCellRef) || + ptr.getType()==typeid (ESMS::LiveCellRef))) + { + mEnvironment.mMechanicsManager->removeActor (ptr); + } + } + } + } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index d20161698..2a7b8009a 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -134,6 +134,8 @@ namespace MWWorld std::string getFacedHandle(); ///< Return handle of the object the player is looking at + + void deleteObject (Ptr ptr); }; } From 2eee3d32f12dd8f0c510f6ef3954e0a5ba1c0943 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Aug 2010 20:29:10 +0200 Subject: [PATCH 7/8] fixed World::disable function --- apps/openmw/mwworld/world.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 581dcc586..296d1d0f2 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -384,9 +384,9 @@ namespace MWWorld void World::disable (Ptr reference) { - if (!reference.getRefData().isEnabled()) + if (reference.getRefData().isEnabled()) { - reference.getRefData().enable(); + reference.getRefData().disable(); if (MWRender::CellRender *render = searchRender (reference.getCell())) { From 8d85211fa19fb1a85c098ca6e430b0c14a31dff0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 8 Aug 2010 14:09:09 +0200 Subject: [PATCH 8/8] modified Npc and Creature class to let them store a copy of their own ID --- apps/esmtool/esmtool.cpp | 2 +- apps/openmw/mwworld/manualref.hpp | 17 +++++++ components/esm/loadcrea.hpp | 8 +++- components/esm/loadnpc.hpp | 6 ++- components/esm_store/reclists.hpp | 76 +++++++++++++++++++++++-------- components/esm_store/store.hpp | 4 +- 6 files changed, 88 insertions(+), 25 deletions(-) diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index ff8e53824..fe067d85d 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -180,7 +180,7 @@ int main(int argc, char**argv) case REC_CREA: { Creature b; - b.load(esm); + b.load(esm, id); if(quiet) break; cout << " Name: " << b.name << endl; break; diff --git a/apps/openmw/mwworld/manualref.hpp b/apps/openmw/mwworld/manualref.hpp index 4b7edfa43..b4d3f7007 100644 --- a/apps/openmw/mwworld/manualref.hpp +++ b/apps/openmw/mwworld/manualref.hpp @@ -36,6 +36,23 @@ namespace MWWorld return false; } + template + bool create (const ESMS::RecListWithIDT& list, const std::string& name) + { + if (const T *instance = list.search (name)) + { + ESMS::LiveCellRef ref; + ref.base = instance; + + mRef = ref; + mPtr = Ptr (&boost::any_cast&> (mRef), 0); + + return true; + } + + return false; + } + public: ManualRef (const ESMS::ESMStore& store, const std::string& name) diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 2a22cebe0..cbf39bd95 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -62,8 +62,12 @@ struct Creature // Defined in loadcont.hpp InventoryList inventory; - void load(ESMReader &esm) + std::string mId; + + void load(ESMReader &esm, const std::string& id) { + mId = id; + model = esm.getHNString("MODL"); original = esm.getHNOString("CNAM"); name = esm.getHNOString("FNAM"); @@ -93,7 +97,7 @@ struct Creature // AI_A - activate? esm.skipRecord(); - } + } }; } #endif diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index 0075996ac..61618c731 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -97,8 +97,12 @@ struct NPC std::string name, model, race, cls, faction, script, hair, head; // body parts - void load(ESMReader &esm) + std::string mId; + + void load(ESMReader &esm, const std::string& id) { + mId = id; + npdt52.gold = -10; model = esm.getHNOString("MODL"); diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 5763dc6f9..3b160259c 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -17,16 +17,16 @@ namespace ESMS { virtual void load(ESMReader &esm, const std::string &id) = 0; virtual int getSize() = 0; - + static std::string toLower (const std::string& name) { std::string lowerCase; - + std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), (int(*)(int)) std::tolower); - + return lowerCase; - } + } }; typedef std::map RecListList; @@ -53,15 +53,53 @@ namespace ESMS return NULL; return &list.find(id2)->second; } - + + // Find the given object ID (throws an exception if not found) + const X* find(const std::string &id) const + { + const X *object = search (id); + + if (!object) + throw std::runtime_error ("object " + id + " not found"); + + return object; + } + + int getSize() { return list.size(); } + }; + + /// Modified version of RecListT for records, that need to store their own ID + template + struct RecListWithIDT : RecList + { + typedef std::map MapType; + + MapType list; + + // Load one object of this type + void load(ESMReader &esm, const std::string &id) + { + std::string id2 = toLower (id); + list[id2].load(esm, id2); + } + + // Find the given object ID, or return NULL if not found. + const X* search(const std::string &id) const + { + std::string id2 = toLower (id); + if(list.find(id2) == list.end()) + return NULL; + return &list.find(id2)->second; + } + // Find the given object ID (throws an exception if not found) const X* find(const std::string &id) const { const X *object = search (id); - + if (!object) throw std::runtime_error ("object " + id + " not found"); - + return object; } @@ -80,7 +118,7 @@ namespace ESMS void load(ESMReader &esm, const std::string &id) { - std::string id2 = toLower (id); + std::string id2 = toLower (id); X& ref = list[id2]; ref.id = id; @@ -95,18 +133,18 @@ namespace ESMS return NULL; return &list.find(id2)->second; } - + // Find the given object ID (throws an exception if not found) const X* find(const std::string &id) const { const X *object = search (id); - + if (!object) throw std::runtime_error ("object " + id + " not found"); - + return object; } - + int getSize() { return list.size(); } }; @@ -180,7 +218,7 @@ namespace ESMS } } }; - + template struct ScriptListT : RecList { @@ -193,16 +231,16 @@ namespace ESMS { X ref; ref.load (esm); - + std::string realId = toLower (ref.data.name.toString()); - + std::swap (list[realId], ref); } // Find the given object ID, or return NULL if not found. const X* search(const std::string &id) const { - std::string id2 = toLower (id); + std::string id2 = toLower (id); if(list.find(id2) == list.end()) return NULL; return &list.find(id2)->second; @@ -212,15 +250,15 @@ namespace ESMS const X* find(const std::string &id) const { const X *object = search (id); - + if (!object) throw std::runtime_error ("object " + id + " not found"); - + return object; } int getSize() { return list.size(); } - }; + }; /* We need special lists for: diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index fd4a47d4b..6138014ef 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -40,7 +40,7 @@ namespace ESMS RecListT clothes; RecListT contChange; RecListT containers; - RecListT creatures; + RecListWithIDT creatures; RecListT creaChange; RecListT dialogs; RecListT doors; @@ -53,7 +53,7 @@ namespace ESMS RecListT lights; RecListT lockpicks; RecListT miscItems; - RecListT npcs; + RecListWithIDT npcs; RecListT npcChange; RecListT probes; RecListT races;