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?
Partial journal sharing?
Re: Partial journal sharing?
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}
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?
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
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?
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?
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
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?
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?
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!
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?
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.
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.
-
- Posts: 256
- Joined: 19 Jul 2016, 01:02
Re: Partial journal sharing?
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()
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?
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 results in a for loop that doesn't go through it.
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