Page 1 of 2
Partial journal sharing?
Posted: 17 Mar 2018, 15:10
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?
Re: Partial journal sharing?
Posted: 18 Mar 2018, 14:43
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}
Re: Partial journal sharing?
Posted: 18 Mar 2018, 16:56
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
Re: Partial journal sharing?
Posted: 18 Mar 2018, 17:39
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
Re: Partial journal sharing?
Posted: 18 Mar 2018, 18:19
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
Re: Partial journal sharing?
Posted: 20 Mar 2018, 13:47
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
Re: Partial journal sharing?
Posted: 21 Mar 2018, 08:38
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!
Re: Partial journal sharing?
Posted: 21 Mar 2018, 12:34
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.
Re: Partial journal sharing?
Posted: 22 Mar 2018, 02:51
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.
Re: Partial journal sharing?
Posted: 22 Mar 2018, 13:25
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.