#include "class.hpp" #include #include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" #include "ptr.hpp" #include "refdata.hpp" #include "nullaction.hpp" #include "failedaction.hpp" #include "actiontake.hpp" #include "containerstore.hpp" #include "../mwgui/tooltips.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/magiceffects.hpp" namespace MWWorld { std::map > Class::sClasses; Class::Class() {} Class::~Class() {} void Class::insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const { } void Class::insertObject(const Ptr& ptr, const std::string& mesh, MWPhysics::PhysicsSystem& physics) const { } bool Class::apply (const MWWorld::Ptr& ptr, const std::string& id, const MWWorld::Ptr& actor) const { return false; } void Class::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const { throw std::runtime_error ("class does not represent an actor"); } bool Class::canSell (const MWWorld::ConstPtr& item, int npcServices) const { return false; } int Class::getServices(const ConstPtr &actor) const { throw std::runtime_error ("class does not have services"); } MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const { throw std::runtime_error ("class does not have creature stats"); } MWMechanics::NpcStats& Class::getNpcStats (const Ptr& ptr) const { throw std::runtime_error ("class does not have NPC stats"); } bool Class::hasItemHealth (const ConstPtr& ptr) const { return false; } int Class::getItemHealth(const ConstPtr &ptr) const { if (ptr.getCellRef().getCharge() == -1) return getItemMaxHealth(ptr); else return ptr.getCellRef().getCharge(); } int Class::getItemMaxHealth (const ConstPtr& ptr) const { throw std::runtime_error ("class does not have item health"); } void Class::hit(const Ptr& ptr, float attackStrength, int type) const { throw std::runtime_error("class cannot hit"); } void Class::block(const Ptr &ptr) const { throw std::runtime_error("class cannot block"); } bool Class::canBeActivated(const Ptr& ptr) const { return !getName(ptr).empty(); } void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const { throw std::runtime_error("class cannot be hit"); } std::shared_ptr Class::activate (const Ptr& ptr, const Ptr& actor) const { return std::shared_ptr (new NullAction); } std::shared_ptr Class::use (const Ptr& ptr, bool force) const { return std::shared_ptr (new NullAction); } ContainerStore& Class::getContainerStore (const Ptr& ptr) const { throw std::runtime_error ("class does not have a container store"); } InventoryStore& Class::getInventoryStore (const Ptr& ptr) const { throw std::runtime_error ("class does not have an inventory store"); } /* Start of tes3mp addition Make it possible to check whether a class has a container store */ bool Class::hasContainerStore(const Ptr &ptr) const { return false; } /* End of tes3mp addition */ bool Class::hasInventoryStore(const Ptr &ptr) const { return false; } void Class::lock (const Ptr& ptr, int lockLevel) const { throw std::runtime_error ("class does not support locking"); } void Class::unlock (const Ptr& ptr) const { throw std::runtime_error ("class does not support unlocking"); } bool Class::canLock(const ConstPtr &ptr) const { return false; } void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const { throw std::runtime_error ("class does not support time-based uses"); } float Class::getRemainingUsageTime (const ConstPtr& ptr) const { return -1; } std::string Class::getScript (const ConstPtr& ptr) const { return ""; } float Class::getSpeed (const Ptr& ptr) const { return 0; } float Class::getJump (const Ptr& ptr) const { return 0; } int Class::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const { throw std::runtime_error ("class does not support enchanting"); } MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const { throw std::runtime_error ("movement settings not supported by class"); } osg::Vec3f Class::getRotationVector (const Ptr& ptr) const { return osg::Vec3f (0, 0, 0); } std::pair, bool> Class::getEquipmentSlots (const ConstPtr& ptr) const { return std::make_pair (std::vector(), false); } int Class::getEquipmentSkill (const ConstPtr& ptr) const { return -1; } int Class::getValue (const ConstPtr& ptr) const { throw std::logic_error ("value not supported by this class"); } float Class::getCapacity (const MWWorld::Ptr& ptr) const { throw std::runtime_error ("capacity not supported by this class"); } float Class::getWeight(const ConstPtr &ptr) const { throw std::runtime_error ("weight not supported by this class"); } float Class::getEncumbrance (const MWWorld::Ptr& ptr) const { throw std::runtime_error ("encumbrance not supported by class"); } bool Class::isEssential (const MWWorld::ConstPtr& ptr) const { return false; } float Class::getArmorRating (const MWWorld::Ptr& ptr) const { throw std::runtime_error("Class does not support armor rating"); } const Class& Class::get (const std::string& key) { if (key.empty()) throw std::logic_error ("Class::get(): attempting to get an empty key"); std::map >::const_iterator iter = sClasses.find (key); if (iter==sClasses.end()) throw std::logic_error ("Class::get(): unknown class key: " + key); return *iter->second; } bool Class::isPersistent(const ConstPtr &ptr) const { throw std::runtime_error ("class does not support persistence"); } void Class::registerClass(const std::string& key, std::shared_ptr instance) { instance->mTypeName = key; sClasses.insert(std::make_pair(key, instance)); } std::string Class::getUpSoundId (const ConstPtr& ptr) const { throw std::runtime_error ("class does not have an up sound"); } std::string Class::getDownSoundId (const ConstPtr& ptr) const { throw std::runtime_error ("class does not have an down sound"); } std::string Class::getSoundIdFromSndGen(const Ptr &ptr, const std::string &type) const { throw std::runtime_error("class does not support soundgen look up"); } std::string Class::getInventoryIcon (const MWWorld::ConstPtr& ptr) const { throw std::runtime_error ("class does not have any inventory icon"); } MWGui::ToolTipInfo Class::getToolTipInfo (const ConstPtr& ptr, int count) const { throw std::runtime_error ("class does not have a tool tip"); } bool Class::showsInInventory (const ConstPtr& ptr) const { // NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken. // Vanilla likely uses a hack like this since there's no other way to prevent it from // being shown or taken. return (ptr.getCellRef().getRefId() != "werewolfrobe"); } bool Class::hasToolTip (const ConstPtr& ptr) const { return false; } std::string Class::getEnchantment (const ConstPtr& ptr) const { return ""; } void Class::adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const { } std::string Class::getModel(const MWWorld::ConstPtr &ptr) const { return ""; } bool Class::useAnim() const { return false; } void Class::getModelsToPreload(const Ptr &ptr, std::vector &models) const { std::string model = getModel(ptr); if (!model.empty()) models.push_back(model); } std::string Class::applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { throw std::runtime_error ("class can't be enchanted"); } std::pair Class::canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const { return std::make_pair (1, ""); } void Class::adjustPosition(const MWWorld::Ptr& ptr, bool force) const { } std::shared_ptr Class::defaultItemActivate(const Ptr &ptr, const Ptr &actor) const { if(!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return std::shared_ptr(new NullAction()); if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::Sound *sound = store.get().searchRandom("WolfItem"); std::shared_ptr action(new MWWorld::FailedAction("#{sWerewolfRefusal}")); if(sound) action->setSound(sound->mId); return action; } std::shared_ptr action(new ActionTake(ptr)); action->setSound(getUpSoundId(ptr)); return action; } MWWorld::Ptr Class::copyToCellImpl(const ConstPtr &ptr, CellStore &cell) const { throw std::runtime_error("unable to copy class to cell"); } MWWorld::Ptr Class::copyToCell(const ConstPtr &ptr, CellStore &cell, int count) const { Ptr newPtr = copyToCellImpl(ptr, cell); newPtr.getCellRef().unsetRefNum(); // This RefNum is only valid within the original cell of the reference newPtr.getRefData().setCount(count); return newPtr; } MWWorld::Ptr Class::copyToCell(const ConstPtr &ptr, CellStore &cell, const ESM::Position &pos, int count) const { Ptr newPtr = copyToCell(ptr, cell, count); newPtr.getRefData().setPosition(pos); return newPtr; } bool Class::isBipedal(const ConstPtr &ptr) const { return false; } bool Class::canFly(const ConstPtr &ptr) const { return false; } bool Class::canSwim(const ConstPtr &ptr) const { return false; } bool Class::canWalk(const ConstPtr &ptr) const { return false; } bool Class::isPureWaterCreature(const MWWorld::Ptr& ptr) const { return canSwim(ptr) && !isBipedal(ptr) && !canFly(ptr) && !canWalk(ptr); } bool Class::isPureFlyingCreature(const Ptr& ptr) const { return canFly(ptr) && !isBipedal(ptr) && !canSwim(ptr) && !canWalk(ptr); } bool Class::isPureLandCreature(const Ptr& ptr) const { return canWalk(ptr) && !isBipedal(ptr) && !canFly(ptr) && !canSwim(ptr); } bool Class::isMobile(const MWWorld::Ptr& ptr) const { return canSwim(ptr) || canWalk(ptr) || canFly(ptr); } int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const { throw std::runtime_error("class does not support skills"); } int Class::getBloodTexture (const MWWorld::ConstPtr& ptr) const { throw std::runtime_error("class does not support gore"); } void Class::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const {} void Class::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const {} int Class::getBaseGold(const MWWorld::ConstPtr& ptr) const { throw std::runtime_error("class does not support base gold"); } bool Class::isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const { return false; } int Class::getDoorState (const MWWorld::ConstPtr &ptr) const { throw std::runtime_error("this is not a door"); } void Class::setDoorState (const MWWorld::Ptr &ptr, int state) const { throw std::runtime_error("this is not a door"); } float Class::getNormalizedEncumbrance(const Ptr &ptr) const { float capacity = getCapacity(ptr); float encumbrance = getEncumbrance(ptr); if (encumbrance == 0) return 0.f; if (capacity == 0) return 1.f; return encumbrance / capacity; } std::string Class::getSound(const MWWorld::ConstPtr&) const { return std::string(); } int Class::getBaseFightRating(const ConstPtr &ptr) const { throw std::runtime_error("class does not support fight rating"); } std::string Class::getPrimaryFaction (const MWWorld::ConstPtr& ptr) const { return std::string(); } int Class::getPrimaryFactionRank (const MWWorld::ConstPtr& ptr) const { return -1; } float Class::getEffectiveArmorRating(const ConstPtr &armor, const Ptr &actor) const { throw std::runtime_error("class does not support armor ratings"); } }