mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 15:09:43 +00:00
Add Lua bindings for journal
This commit is contained in:
parent
63e9a63c67
commit
c792582376
11 changed files with 218 additions and 4 deletions
|
@ -49,6 +49,11 @@ namespace MWBase
|
||||||
|
|
||||||
virtual ~Journal() {}
|
virtual ~Journal() {}
|
||||||
|
|
||||||
|
virtual MWDialogue::Quest& getQuest(const ESM::RefId& id) = 0;
|
||||||
|
///< Gets the quest requested. Creates it and inserts it in quests if it does not yet exist.
|
||||||
|
virtual MWDialogue::Quest* getQuestPtr(const ESM::RefId& id) = 0;
|
||||||
|
///< Gets a pointer to the requested quest. Will return nullptr if the quest has not been started.
|
||||||
|
|
||||||
virtual void addEntry(const ESM::RefId& id, int index, const MWWorld::Ptr& actor) = 0;
|
virtual void addEntry(const ESM::RefId& id, int index, const MWWorld::Ptr& actor) = 0;
|
||||||
///< Add a journal entry.
|
///< Add a journal entry.
|
||||||
/// @param actor Used as context for replacing of escape sequences (%name, etc).
|
/// @param actor Used as context for replacing of escape sequences (%name, etc).
|
||||||
|
@ -56,6 +61,9 @@ namespace MWBase
|
||||||
virtual void setJournalIndex(const ESM::RefId& id, int index) = 0;
|
virtual void setJournalIndex(const ESM::RefId& id, int index) = 0;
|
||||||
///< Set the journal index without adding an entry.
|
///< Set the journal index without adding an entry.
|
||||||
|
|
||||||
|
virtual int getQuestCount() const = 0;
|
||||||
|
///< Get the count of quests stored.
|
||||||
|
|
||||||
virtual int getJournalIndex(const ESM::RefId& id) const = 0;
|
virtual int getJournalIndex(const ESM::RefId& id) const = 0;
|
||||||
///< Get the journal index.
|
///< Get the journal index.
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
class ESMWriter;
|
class ESMWriter;
|
||||||
|
class RefId;
|
||||||
struct LuaScripts;
|
struct LuaScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ namespace MWBase
|
||||||
virtual void itemConsumed(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) = 0;
|
virtual void itemConsumed(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) = 0;
|
||||||
virtual void objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
virtual void objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
||||||
virtual void exteriorCreated(MWWorld::CellStore& cell) = 0;
|
virtual void exteriorCreated(MWWorld::CellStore& cell) = 0;
|
||||||
|
virtual void questUpdated(const ESM::RefId& questId, int stage) = 0;
|
||||||
// TODO: notify LuaManager about other events
|
// TODO: notify LuaManager about other events
|
||||||
// virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object,
|
// virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object,
|
||||||
// const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0;
|
// const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0;
|
||||||
|
|
|
@ -31,6 +31,16 @@ namespace MWDialogue
|
||||||
|
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
Quest* Journal::getQuestPtr(const ESM::RefId& id)
|
||||||
|
{
|
||||||
|
TQuestContainer::iterator iter = mQuests.find(id);
|
||||||
|
if (iter == mQuests.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
Topic& Journal::getTopic(const ESM::RefId& id)
|
Topic& Journal::getTopic(const ESM::RefId& id)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +145,10 @@ namespace MWDialogue
|
||||||
mTopics.erase(mTopics.find(topicId)); // All responses removed -> remove topic
|
mTopics.erase(mTopics.find(topicId)); // All responses removed -> remove topic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Journal::getQuestCount() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(mQuests.size());
|
||||||
|
}
|
||||||
int Journal::getJournalIndex(const ESM::RefId& id) const
|
int Journal::getJournalIndex(const ESM::RefId& id) const
|
||||||
{
|
{
|
||||||
TQuestContainer::const_iterator iter = mQuests.find(id);
|
TQuestContainer::const_iterator iter = mQuests.find(id);
|
||||||
|
|
|
@ -15,8 +15,6 @@ namespace MWDialogue
|
||||||
TTopicContainer mTopics;
|
TTopicContainer mTopics;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Quest& getQuest(const ESM::RefId& id);
|
|
||||||
|
|
||||||
Topic& getTopic(const ESM::RefId& id);
|
Topic& getTopic(const ESM::RefId& id);
|
||||||
|
|
||||||
bool isThere(const ESM::RefId& topicId, const ESM::RefId& infoId = ESM::RefId()) const;
|
bool isThere(const ESM::RefId& topicId, const ESM::RefId& infoId = ESM::RefId()) const;
|
||||||
|
@ -26,10 +24,19 @@ namespace MWDialogue
|
||||||
|
|
||||||
void clear() override;
|
void clear() override;
|
||||||
|
|
||||||
|
Quest* getQuestPtr(const ESM::RefId& id) override;
|
||||||
|
///< Gets a pointer to the requested quest. Will return nullptr if the quest has not been started.
|
||||||
|
|
||||||
|
Quest& getQuest(const ESM::RefId& id) override;
|
||||||
|
///< Gets the quest requested. Attempts to create it and inserts it in quests if it does not yet exist.
|
||||||
|
|
||||||
void addEntry(const ESM::RefId& id, int index, const MWWorld::Ptr& actor) override;
|
void addEntry(const ESM::RefId& id, int index, const MWWorld::Ptr& actor) override;
|
||||||
///< Add a journal entry.
|
///< Add a journal entry.
|
||||||
/// @param actor Used as context for replacing of escape sequences (%name, etc).
|
/// @param actor Used as context for replacing of escape sequences (%name, etc).
|
||||||
|
|
||||||
|
int getQuestCount() const override;
|
||||||
|
///< Get the count of saved quests.
|
||||||
|
|
||||||
void setJournalIndex(const ESM::RefId& id, int index) override;
|
void setJournalIndex(const ESM::RefId& id, int index) override;
|
||||||
///< Set the journal index without adding an entry.
|
///< Set the journal index without adding an entry.
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <components/esm3/queststate.hpp>
|
#include <components/esm3/queststate.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -52,6 +53,7 @@ namespace MWDialogue
|
||||||
void Quest::setIndex(int index)
|
void Quest::setIndex(int index)
|
||||||
{
|
{
|
||||||
// The index must be set even if no related journal entry was found
|
// The index must be set even if no related journal entry was found
|
||||||
|
MWBase::Environment::get().getLuaManager()->questUpdated(mTopic, index);
|
||||||
mIndex = index;
|
mIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +82,10 @@ namespace MWDialogue
|
||||||
mFinished = info->mQuestStatus == ESM::DialInfo::QS_Finished;
|
mFinished = info->mQuestStatus == ESM::DialInfo::QS_Finished;
|
||||||
|
|
||||||
if (info->mData.mJournalIndex > mIndex)
|
if (info->mData.mJournalIndex > mIndex)
|
||||||
|
{
|
||||||
mIndex = info->mData.mJournalIndex;
|
mIndex = info->mData.mJournalIndex;
|
||||||
|
MWBase::Environment::get().getLuaManager()->questUpdated(mTopic, mIndex);
|
||||||
|
}
|
||||||
|
|
||||||
for (TEntryIter iter(mEntries.begin()); iter != mEntries.end(); ++iter)
|
for (TEntryIter iter(mEntries.begin()); iter != mEntries.end(); ++iter)
|
||||||
if (iter->mInfoId == entry.mInfoId)
|
if (iter->mInfoId == entry.mInfoId)
|
||||||
|
|
|
@ -179,6 +179,17 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaManager::questUpdated(const ESM::RefId& questId, int stage)
|
||||||
|
{
|
||||||
|
if (mPlayer.isEmpty())
|
||||||
|
return; // The game is not started yet.
|
||||||
|
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||||
|
if (playerScripts)
|
||||||
|
{
|
||||||
|
playerScripts->onQuestUpdate(questId.serializeText(), stage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LuaManager::synchronizedUpdate()
|
void LuaManager::synchronizedUpdate()
|
||||||
{
|
{
|
||||||
if (mPlayer.isEmpty())
|
if (mPlayer.isEmpty())
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell });
|
mEngineEvents.addToQueue(EngineEvents::OnNewExterior{ cell });
|
||||||
}
|
}
|
||||||
|
void questUpdated(const ESM::RefId& questId, int stage) override;
|
||||||
|
|
||||||
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
registerEngineHandlers({ &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers,
|
registerEngineHandlers({ &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers,
|
||||||
&mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mOnFrameHandlers,
|
&mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mOnFrameHandlers,
|
||||||
&mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved });
|
&mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved, &mQuestUpdate });
|
||||||
}
|
}
|
||||||
|
|
||||||
void processInputEvent(const MWBase::LuaManager::InputEvent& event)
|
void processInputEvent(const MWBase::LuaManager::InputEvent& event)
|
||||||
|
@ -56,6 +56,7 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFrame(float dt) { callEngineHandlers(mOnFrameHandlers, dt); }
|
void onFrame(float dt) { callEngineHandlers(mOnFrameHandlers, dt); }
|
||||||
|
void onQuestUpdate(std::string_view questId, int stage) { callEngineHandlers(mQuestUpdate, questId, stage); }
|
||||||
|
|
||||||
bool consoleCommand(
|
bool consoleCommand(
|
||||||
const std::string& consoleMode, const std::string& command, const sol::object& selectedObject)
|
const std::string& consoleMode, const std::string& command, const sol::object& selectedObject)
|
||||||
|
@ -75,6 +76,7 @@ namespace MWLua
|
||||||
EngineHandlerList mTouchpadPressed{ "onTouchPress" };
|
EngineHandlerList mTouchpadPressed{ "onTouchPress" };
|
||||||
EngineHandlerList mTouchpadReleased{ "onTouchRelease" };
|
EngineHandlerList mTouchpadReleased{ "onTouchRelease" };
|
||||||
EngineHandlerList mTouchpadMoved{ "onTouchMove" };
|
EngineHandlerList mTouchpadMoved{ "onTouchMove" };
|
||||||
|
EngineHandlerList mQuestUpdate{ "onQuestUpdate" };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,143 @@
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
|
#include "../luamanagerimp.hpp"
|
||||||
|
#include <apps/openmw/mwbase/journal.hpp>
|
||||||
|
#include <apps/openmw/mwbase/world.hpp>
|
||||||
#include <apps/openmw/mwmechanics/npcstats.hpp>
|
#include <apps/openmw/mwmechanics/npcstats.hpp>
|
||||||
#include <apps/openmw/mwworld/class.hpp>
|
#include <apps/openmw/mwworld/class.hpp>
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
|
struct Quests
|
||||||
|
{
|
||||||
|
bool mMutable = false;
|
||||||
|
MWWorld::SafePtr::Id playerId;
|
||||||
|
using Iterator = typename MWBase::Journal::TQuestIter;
|
||||||
|
Iterator mIterator;
|
||||||
|
MWBase::Journal* const journal = MWBase::Environment::get().getJournal();
|
||||||
|
void reset() { mIterator = journal->questBegin(); }
|
||||||
|
bool isEnd() const { return mIterator == journal->questEnd(); }
|
||||||
|
void advance() { mIterator++; }
|
||||||
|
};
|
||||||
|
struct Quest
|
||||||
|
{
|
||||||
|
ESM::RefId mQuestId;
|
||||||
|
bool mMutable = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sol
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
struct is_automagical<MWLua::Quests> : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct is_automagical<MWLua::Quest> : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWLua
|
||||||
|
{
|
||||||
|
|
||||||
|
void addPlayerQuestBindings(sol::table& player, const Context& context)
|
||||||
|
{
|
||||||
|
MWBase::Journal* const journal = MWBase::Environment::get().getJournal();
|
||||||
|
|
||||||
|
// Quests
|
||||||
|
player["quests"] = [](const Object& player) {
|
||||||
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
Quests q = {};
|
||||||
|
if (player.ptr() != world->getPlayerPtr())
|
||||||
|
throw std::runtime_error("Must provide a player!");
|
||||||
|
if (dynamic_cast<const GObject*>(&player))
|
||||||
|
q.mMutable = true;
|
||||||
|
q.playerId = player.id();
|
||||||
|
return q;
|
||||||
|
};
|
||||||
|
sol::usertype<Quests> quests = context.mLua->sol().new_usertype<Quests>("Quests");
|
||||||
|
quests[sol::meta_function::to_string]
|
||||||
|
= [](const Quests& quests) { return "Quests[" + quests.playerId.toString() + "]"; };
|
||||||
|
quests[sol::meta_function::length] = [journal]() { return journal->getQuestCount(); };
|
||||||
|
quests[sol::meta_function::index] = sol::overload([](const Quests& quests, std::string_view index) -> Quest {
|
||||||
|
Quest q;
|
||||||
|
q.mQuestId = ESM::RefId::deserializeText(index);
|
||||||
|
q.mMutable = quests.mMutable;
|
||||||
|
return q;
|
||||||
|
});
|
||||||
|
quests[sol::meta_function::pairs] = [](sol::this_state ts, Quests& self) {
|
||||||
|
sol::state_view lua(ts);
|
||||||
|
self.reset();
|
||||||
|
return sol::as_function([lua, &self]() mutable -> std::pair<sol::object, sol::object> {
|
||||||
|
if (!self.isEnd())
|
||||||
|
{
|
||||||
|
Quest q;
|
||||||
|
q.mQuestId = (self.mIterator->first);
|
||||||
|
q.mMutable = self.mMutable;
|
||||||
|
auto result = sol::make_object(lua, q);
|
||||||
|
auto index = sol::make_object(lua, self.mIterator->first);
|
||||||
|
self.advance();
|
||||||
|
return { index, result };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { sol::lua_nil, sol::lua_nil };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Quest Functions
|
||||||
|
auto getQuestStage = [journal](const Quest& q) -> int {
|
||||||
|
auto quest = journal->getQuestPtr(q.mQuestId);
|
||||||
|
if (quest == nullptr)
|
||||||
|
return -1;
|
||||||
|
return journal->getJournalIndex(q.mQuestId);
|
||||||
|
};
|
||||||
|
auto setQuestStage = [context](const Quest& q, int stage) {
|
||||||
|
if (!q.mMutable)
|
||||||
|
throw std::runtime_error("Value can only be changed in global scripts!");
|
||||||
|
context.mLuaManager->addAction(
|
||||||
|
[q, stage] { MWBase::Environment::get().getJournal()->setJournalIndex(q.mQuestId, stage); },
|
||||||
|
"setQuestStageAction");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Player quests
|
||||||
|
sol::usertype<Quest> quest = context.mLua->sol().new_usertype<Quest>("Quest");
|
||||||
|
quest[sol::meta_function::to_string]
|
||||||
|
= [](const Quest& quest) { return "Quest [" + quest.mQuestId.serializeText() + "]"; };
|
||||||
|
quest["stage"] = sol::property(getQuestStage, setQuestStage);
|
||||||
|
quest["name"] = sol::readonly_property([journal](const Quest& q) -> sol::optional<std::string_view> {
|
||||||
|
auto quest = journal->getQuestPtr(q.mQuestId);
|
||||||
|
if (quest == nullptr)
|
||||||
|
return sol::nullopt;
|
||||||
|
return quest->getName();
|
||||||
|
});
|
||||||
|
quest["id"] = sol::readonly_property([](const Quest& q) -> std::string { return q.mQuestId.serializeText(); });
|
||||||
|
quest["isFinished"] = sol::property(
|
||||||
|
[journal](const Quest& q) -> bool {
|
||||||
|
auto quest = journal->getQuestPtr(q.mQuestId);
|
||||||
|
if (quest == nullptr)
|
||||||
|
return false;
|
||||||
|
return quest->isFinished();
|
||||||
|
},
|
||||||
|
[journal, context](const Quest& q, bool finished) {
|
||||||
|
if (!q.mMutable)
|
||||||
|
throw std::runtime_error("Value can only be changed in global scripts!");
|
||||||
|
context.mLuaManager->addAction(
|
||||||
|
[q, finished, journal] { journal->getQuest(q.mQuestId).setFinished(finished); },
|
||||||
|
"setQuestFinishedAction");
|
||||||
|
});
|
||||||
|
quest["addJournalEntry"] = [context](const Quest& q, const GObject& actor, int stage) {
|
||||||
|
MWWorld::Ptr ptr = actor.ptr();
|
||||||
|
|
||||||
|
// The journal mwscript function has a try function here, we will make the lua function throw an
|
||||||
|
// error. However, the addAction will cause it to error outside of this function.
|
||||||
|
context.mLuaManager->addAction(
|
||||||
|
[ptr, q, stage] { MWBase::Environment::get().getJournal()->addEntry(q.mQuestId, stage, ptr); },
|
||||||
|
"addJournalEntryAction");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void addPlayerBindings(sol::table player, const Context& context)
|
void addPlayerBindings(sol::table player, const Context& context)
|
||||||
{
|
{
|
||||||
|
@ -12,5 +145,6 @@ namespace MWLua
|
||||||
const MWWorld::Class& cls = o.ptr().getClass();
|
const MWWorld::Class& cls = o.ptr().getClass();
|
||||||
return cls.getNpcStats(o.ptr()).getBounty();
|
return cls.getNpcStats(o.ptr()).getBounty();
|
||||||
};
|
};
|
||||||
|
addPlayerQuestBindings(player, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -89,6 +89,8 @@ Engine handler is a function defined by a script, that can be called by the engi
|
||||||
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed.
|
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed.
|
||||||
| Usage example:
|
| Usage example:
|
||||||
| ``if key.symbol == 'z' and key.withShift then ...``
|
| ``if key.symbol == 'z' and key.withShift then ...``
|
||||||
|
* - onQuestUpdate(questId,stage)
|
||||||
|
- | Called when a quest is updated.
|
||||||
* - onKeyRelease(key)
|
* - onKeyRelease(key)
|
||||||
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is released.
|
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is released.
|
||||||
| Usage example:
|
| Usage example:
|
||||||
|
|
|
@ -717,6 +717,34 @@
|
||||||
-- @param openmw.core#GameObject actor
|
-- @param openmw.core#GameObject actor
|
||||||
-- @return #number
|
-- @return #number
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Returns a list containing quests @{<#PlayerQuest>} for the specified player, indexed by quest ID.
|
||||||
|
-- @function [parent=#Player] quests
|
||||||
|
-- @param openmw.core#GameObject player
|
||||||
|
-- @return #list<#PlayerQuest>
|
||||||
|
-- @usage -- Getting the quest for a specified index
|
||||||
|
-- stage = types.Player.quests(playerRef)["ms_fargothring].stage
|
||||||
|
-- --Get the name of all started quests
|
||||||
|
-- for x, quest in pairs(types.Player.quests(playerRef)) do print (quest.name) end
|
||||||
|
-- --Start a new quest, add it to the player's quest list but don't add any journal entries
|
||||||
|
-- types.Player.quests(playerRef)["ms_fargothring].stage = 0
|
||||||
|
|
||||||
|
--- @{#PlayerQuest}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @type PlayerQuest
|
||||||
|
-- @field #string id The quest ID.
|
||||||
|
-- @field #number stage The quest Stage. May only be changed by global scripts. Returns -1 if the quest has not been started or does not exist.
|
||||||
|
-- @field #bool isFinished Returns true if the quest is complete, false if not.
|
||||||
|
-- @field #string name The Quest's user friendly name. Not all quests have this. Will be nil if the quest has not been started.
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Sets the quest stage for the given quest, on the given player, and adds the entry to the journal, if there is an entry at the specified stage. Can only be used in global scripts.
|
||||||
|
-- @function [parent=#PlayerQuest] addJournalEntry
|
||||||
|
-- @param self
|
||||||
|
-- @param openmw.core#GameObject actor The actor who is the source of the journal entry, can be the same as player, their name is used in a similar manner as in dialogue.
|
||||||
|
-- @param #number stage Quest Stage
|
||||||
|
|
||||||
--- @{#Armor} functions
|
--- @{#Armor} functions
|
||||||
-- @field [parent=#types] #Armor Armor
|
-- @field [parent=#types] #Armor Armor
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue