Partial journal sharing?

Everything having to do with OpenMW's TES3MP branch.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Partial journal sharing?

Post by unelsson »

Fore tes3mp-server, is it possible to have journal sharing off by default, and only share main quest progress in Morrowind, Bloodmoon and Tribunal. That should let the main quest be co-opped, but give some amount of freedom to go on playing solo side quests. Players could play opposing great houses, perhaps a mod could resolve the conflicts https://www.nexusmods.com/morrowind/mods/10994 . Some unexpected bugs might still come though...

Some custom scripts for this?

What kind of tricks have server admins come up with playing without shared journal?
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

It took a while for me to find the correct parts of the code, as I went searching through tes3mp-code instead of Corescripts. I'm still looking, but.. well.. here's my detective work: Corescripts player/base.lua and myMod.lua are calling something if config.shareJournal == true. I assume they are calling a function in stateHelper. I'm not sure where and how the WorldInstance points though, a variable holding the world data I assume?

player/base.lua
https://github.com/TES3MP/CoreScripts/b ... e.lua#L147

myMod.lua
https://github.com/TES3MP/CoreScripts/b ... d.lua#L712

This, I assume, is the function that actually shares the journal.
https://github.com/TES3MP/CoreScripts/b ... er.lua#L99

So.. I wonder if it's possible to add couple of if-statements under stateHelper:LoadJournal to only selectively share certain journal entries, something like:
IF (JOURNAL_ENTRY == RELATED_TO_MAINQUEST) {SHARE_JOURNAL}
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

indeed, commenting out these lines from stateHelper.lua turns off journal sharing
115: tes3mp.AddJournalEntry(pid, journalItem.quest, journalItem.index, journalItem.actorRefId)
117: tes3mp.AddJournalIndex(pid, journalItem.quest, journalItem.index)

Question now is how to point to certain quests? Lets say I want to turn off Antabolis Informant -quest ( A1_2_AntabolisInformant ).. does some of these work?

if journalItem.quest ~= "A1_2_AntabolisInformant"?
...code for journal update...
end

if journalItem.index ~= "A1_2_AntabolisInformant"?
...code for journal update...
end
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

This code works.

Code: Select all

if journalItem.quest ~= "a1_2_antabolisinformant" then --DO NOT SHARE a1_2_antabolisinformant QUEST
        if journalItem.type == actionTypes.journal.ENTRY then

            if journalItem.actorRefId == nil then
                journalItem.actorRefId = "player"
            end

            tes3mp.AddJournalEntry(pid, journalItem.quest, journalItem.index, journalItem.actorRefId)

        else
            tes3mp.AddJournalIndex(pid, journalItem.quest, journalItem.index)
        end
end
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

Now, instead of just one quest, it's possible to change it like this to only share the main quest. I did a small test on this and it seems to work. I haven't played the whole main quest co-opped though... "cx" (backpath) is intentionally left out from this sharing.

stateHelper.lua, row 109

Code: Select all

if  string.sub(journalItem.quest, 1, 2) == "a1" or
        string.sub(journalItem.quest, 1, 2) == "a2" or
        string.sub(journalItem.quest, 1, 2) == "b1" or
        string.sub(journalItem.quest, 1, 2) == "b2" or
        string.sub(journalItem.quest, 1, 2) == "b3" or
        string.sub(journalItem.quest, 1, 2) == "b4" or
        string.sub(journalItem.quest, 1, 2) == "b5" or
        string.sub(journalItem.quest, 1, 2) == "b6" or
        string.sub(journalItem.quest, 1, 2) == "b7" or
        string.sub(journalItem.quest, 1, 2) == "b8" or
        string.sub(journalItem.quest, 1, 2) == "c0" or
        string.sub(journalItem.quest, 1, 2) == "c2" or
        string.sub(journalItem.quest, 1, 2) == "c3" then --Only share main quest
         
        ...code for journal sharing...

end
       
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

Below is my latest partial journal sharing code - replacement for function StateHelper:LoadJournal in file stateHelper.lua. Added a fix for corprus cure quest, essentially NOT sharing the final phases of corpruscure-quest for players who are infected with corprus.

Code: Select all

function StateHelper:LoadJournal(pid, stateObject)

    if stateObject.data.journal == nil then
        stateObject.data.journal = {}
    end

    tes3mp.InitializeJournalChanges(pid)

    -- Check if player is infected with corprus

    local playerHasCorprus = false
    for index, currentSpellBook in pairs(Players[pid].data.spellbook) do --check for corprus
        for spellindex, currentSpell in pairs(currentSpellBook) do
            print("currentSpell:")
            print(currentSpell)
            if currentSpell == "corprus" then
                playerHasCorprus = true
            else
            end
        end
    end

    for index, journalItem in pairs(stateObject.data.journal) do

    -- Share main quest for all players, except the corprusCureQuest's phases for players infected with corprus
    -- phases 40, 46 and 50 are the key phases for getting dwemer boots of levitation and curing corprus

    if  (journalItem.quest == "a2_3_corpruscure" and journalItem.index ~= 50 and journalItem.index ~= 46 and journalItem.index ~= 40) or
        (journalItem.quest == "a2_3_corpruscure" and playerHasCorprus == false) or
        (journalItem.quest ~= "a2_3_corpruscure" and (
        string.sub(journalItem.quest, 1, 2) == "a1" or
        string.sub(journalItem.quest, 1, 2) == "a2" or
        string.sub(journalItem.quest, 1, 2) == "b1" or
        string.sub(journalItem.quest, 1, 2) == "b2" or
        string.sub(journalItem.quest, 1, 2) == "b3" or
        string.sub(journalItem.quest, 1, 2) == "b4" or
        string.sub(journalItem.quest, 1, 2) == "b5" or
        string.sub(journalItem.quest, 1, 2) == "b6" or
        string.sub(journalItem.quest, 1, 2) == "b7" or
        string.sub(journalItem.quest, 1, 2) == "b8" or
        string.sub(journalItem.quest, 1, 2) == "c0" or
        string.sub(journalItem.quest, 1, 2) == "c2" or
        string.sub(journalItem.quest, 1, 2) == "c3")) then

        if journalItem.type == actionTypes.journal.ENTRY then

            if journalItem.actorRefId == nil then
                journalItem.actorRefId = "player"
            end

            tes3mp.AddJournalEntry(pid, journalItem.quest, journalItem.index, journalItem.actorRefId)

        else
            tes3mp.AddJournalIndex(pid, journalItem.quest, journalItem.index)
        end
    end
    end

    tes3mp.SendJournalChanges(pid)
end
User avatar
Greendogo
Posts: 1467
Joined: 26 Aug 2011, 02:04

Re: Partial journal sharing?

Post by Greendogo »

This will break some quests because the world the players inhabit is shared, and not instanced. Some changes are permanent, like killing PCs for example. If you didn't want other players to join other great houses, or to stunt their progression you could easily kill of the middling quest givers in their houses. The shared journal basically says "what's yours is mine"; that's not the best system, however while we don't have instancing or a world built for competing quest progressions (two different things in my opinion) it can help. Maybe trying non-shared journals would help guide the next steps in multiplayer.

Future mod-development needs to be done, in the actual editor as well as in the engine, to support more truly immersive quests. A non-shared journal is definitely one of them!
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

Partial journal sharing (main quest only) is still flawed, but I somehow like the middle ground between sharing all, and not sharing anything. I like this setting on a small private server, where you play with your friends, to minimize the chances of intentional quest breaking. In open servers there has to be something like npc respawning or world resetting to prevent someone killing all npcs. I like non-sharing/partial journal sharing also because it's a nice roleplaying element to think of what happens after a quest breaks when e.g. some important npc is killed is also interesting, how would the small Morrowind community solve these problems? This could indeed be a multiplayer mod.

At the present though, game doesn't save personal quest progress, other than the main quest. I wonder if that can be achieved with this tes3mp engine version.
davidcernat
Posts: 256
Joined: 19 Jul 2016, 01:02

Re: Partial journal sharing?

Post by davidcernat »

unelsson wrote: 21 Mar 2018, 12:34 At the present though, game doesn't save personal quest progress, other than the main quest. I wonder if that can be achieved with this tes3mp engine version.
It's not just possible. It's fairly easy.

Save personal quest progress to the Player's data, save main quest progress to the World data, and then load up both for every player.

You don't need to mess with stateHelper. Start over and just replace this line with your main quest checks:

https://github.com/TES3MP/CoreScripts/b ... d.lua#L735

Then replace these lines:

https://github.com/TES3MP/CoreScripts/b ... #L147-L151

With this:

Code: Select all

WorldInstance:LoadJournal(self.pid)
self:LoadJournal()
Also ensure this line is still used for newly created players:

https://github.com/TES3MP/CoreScripts/b ... e.lua#L193

Obviously, it would be more elegant if you added some new config options to config.lua that you could turn on and off instead of just breaking config.shareJournal, but that's the quick solution.
unelsson
Posts: 227
Joined: 17 Mar 2018, 14:57

Re: Partial journal sharing?

Post by unelsson »

The idea you propose is indeed what should be done, but I haven't been able to implement that yet.

Your proposed changes work, except that when saving player journal, the for-loop going over Players[pid].data.journal finds no entries at all, and therefore doesn't save the player's personal journal. It seems that personal quests aren't saving to this variable at all.

Therefore, changing this https://github.com/TES3MP/CoreScripts/b ... d.lua#L735 to

Code: Select all

for index, journalItem in pairs(Players[pid].data.journal) do
results in a for loop that doesn't go through it.
Post Reply