Popular Post Lindor 426 Posted May 20, 2023 Popular Post Share Posted May 20, 2023 (edited) I'm working on reviewing, cleaning, fixing, improving, commenting and increasing readibility of questscripts.txt. I want to post main fixes here. Final questscripts.txt can be downloaded when I finish my mod, but might take a while. On request, previews can be uploaded. I think it's best when I both post new fixes here and update it in OP to get a list without requiring a read-through of this topic. Fixes: CM_TimedKillCheatEvent: Spoiler function CM_TimedKillCheatEvent(quest_id) local index = CM_get_index(quest_id) if index then local cm_qtime = 60 * cm_timequest[index].time local cm_qkills = cm_timequest[index].kills local cm_dcount = cm_timequest[index].ecount if cm_qtime and cm_qkills and cm_dcount then if ((cm_qtime > 0) and (cm_qkills > 0)) then if (cm_dcount <= cm_qkills) and (cm_dcount > 0) then local remaining_factor = 1 - (cm_dcount / cm_qkills) local cm_tcount = math.floor(cm_qtime * remaining_factor * remaining_factor) if cm_tcount < 5 then do cm_tcount = 0 end end do cm_timequest[index].tcount = cm_tcount end if cm_tcount > 0 then do setTimer{id = quest_id, interval = 1, count = cm_tcount} end do showTimer{id = quest_id, cur = cm_tcount, max = cm_qtime} end else do looseQuest(quest_id) end end end end end end end Comparison operator fix from >= to >. This fix is mandatory, as it prevents quest stages from triggering at inappropriate events CM_TimerResolve: Spoiler function CM_TimerResolve(quest_id) local index = CM_get_index(quest_id) if CM_SessionOnline and index then if (getQuestState(quest_id)=="TASK_AWAITING") and (not cm_timequest[index].tcount) then do CM_TimedKillCheatEvent(quest_id) end end end end This is a missing brackets fix. Previously, it was checking if getQuestState(quest_id) == ("TASK_AWAITING" and not cm_timequest[index].tcount) then which is wrong. CM_GetSessionStatus: Spoiler CM_GetSessionStatus = function(args) local HeroRefs = getHeroRefs() local index = CM_get_index(args.id) if ((getn(HeroRefs) > 0) and index) then local myHeroRef = HeroRefs[1] local p = CM_convertPosition_To_SimpleTable(getPos{heroRef = myHeroRef}) if not cm_timequest[index].heropos then do cm_timequest[index].heropos = p end else local constant_position = true local pp = cm_timequest[index].heropos for I, c in ipairs(p) do if p[I] ~= pp[I] then do constant_position = false end do break end end end if not constant_position then do CM_SessionOnline = true end end end end end break statement added to skip unnecessary calculaions, sppeding up the function significantly given that the position table is large enough. getn: Spoiler function getn(inTable) local tableLength = 0 for key, value in ipairs(inTable) do do tableLength = key end end do return tableLength end end Absolutely mandatory. Previously, this funtion was using keywords as variable names which is a NoGo. CM_convertPosition_To_SimpleTable: Spoiler function CM_convertPosition_To_SimpleTable(args) local pos_table = {} local pos_args if type(args) == "string" then do pos_args = string.split(args, ";") end else do pos_args = args end end if type(pos_args) == "table" then if pos_args.sx then do pos_table[1] = pos_args.sx end elseif pos_args.x then do pos_table[1] = floor(pos_args.x / 3200) end else do pos_table[1] = pos_args[1] end end if pos_args.sy then do pos_table[2] = pos_args.sy end elseif pos_args.y then do pos_table[2] = floor(pos_args.y / 3200) end else do pos_table[2] = pos_args[2] end end if pos_args.sz then do pos_table[3] = pos_args.sz end elseif pos_args.layer then do pos_table[3] = pos_args.layer end else do pos_table[3] = pos_args[3] end end if pos_args.px then do pos_table[4] = pos_args.px end elseif pos_args.x then do pos_table[4] = pos_args.x - (pos_table[1] * 3200) end else do pos_table[4] = pos_args[4] end end if pos_args.py then pos_table[5] = pos_args.py elseif pos_args.y then do pos_table[5] = pos_args.y - (pos_table[2] * 3200) end else do pos_table[5] = pos_args[5] end end if pos_args.pz then do pos_table[6] = pos_args.pz end elseif pos_args.z then do pos_table[6] = pos_args.z end else do pos_table[6] = pos_args[6] end end if pos_args.orientation then do pos_table[7] = pos_args.orientation end else do pos_table[7] = pos_args[7] end end end do return pos_table end end Not that important. Previously that function had an unused variable. I deleted that. The "Platte8G" function exists twice. Rename one to "Platte8H". Doesn't matter which one. onInitWorldobjects: Spoiler function onInitWorldobjects(heroRef) do setWoobEffect({effect = "FXTYPE_SMOKEBIGWHITE", woid = 1021408807}) end do setWoobEffect({effect = "FXTYPE_QFX_SERAGATE", woid = 1021159739}) end do setWoobEffect({effect = "FXTYPE_QFX_SERAGATE", woid = 1022534681}) end do setWoobEffect({effect = "FXTYPE_QFX_SERAGATE", woid = 1051481207}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1051481207}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023046854}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023046905}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023046923}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023046947}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023047062}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023047090}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023047109}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023047127}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1024204972}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1022995142}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1017520695}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1017465035}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1024277602}) end do setWoobState({state = "WOOB_DOOR_LOCKED", woid = 1023948046}) end do setWoobEffect({effect = "FXTYPE_INVALID", woid = 1021159739}) end do setWoobEffect({effect = "FXTYPE_SIMPLELIGHT3", woid = 1023050165}) end do setWoobEffect({effect = "FXTYPE_SIMPLELIGHT3", woid = 1023050183}) end do setWoobEffect({effect = "FXTYPE_SIMPLELIGHT3", woid = 1023050188}) end do setWoobEffect({effect = "FXTYPE_SIMPLELIGHT3", woid = 1023050229}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586748}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586682}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586759}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586825}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586872}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586885}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586900}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586933}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586908}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1017607326}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587159}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1017608818}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1017608808}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587115}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587093}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587237}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587057}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587049}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587036}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586993}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586997}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016586984}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1016587006}) end do setWoobEffect({effect = "FXTYPE_CHEST1W", woid = 1022534330}) end do setWoobEffect({effect = "FXTYPE_PORTAL2", woid = 1050110364}) end do setWoobEffect({effect = "FXTYPE_PORTAL2", woid = 1052616164}) end do setWoobEffect({effect = "FXTYPE_MAGICLIGHT", woid = 1050703067}) end do setWoobEffect({effect = "FXTYPE_MAGICLIGHT", woid = 1050703089}) end do setWoobEffect({effect = "FXTYPE_MAGICLIGHT", woid = 1050703098}) end do setWoobEffect({effect = "FXTYPE_MAGICLIGHT", woid = 1050703107}) end do math.randomseed() end end fixed "FTYPE_MAGICLIGHT" spelling mistake to "FXTYPE_MAGICLIGHT" _AREA_CENTER_GHOSTVILLAGE: Spoiler function _AREA_CENTER_GHOSTVILLAGE(wpos) local AreaCreatures = { { Tag = 2, CID = 1077, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 1076, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 3, CID = 1080, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1078, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1079, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1081, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 300}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Originally, the creatures in the "AreaCreatures" table would overwrite each other until just one creature is left. The above code fisex that. _AREA_CENTER_HUMANS_CAPITAL: Spoiler function _AREA_CENTER_HUMANS_CAPITAL(wpos) local AreaCreatures = { { Tag = 1, CID = 316, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 325, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 318, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 1072, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 327, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 994, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 995, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 1043, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 2, CID = 321, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 736, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 691, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 692, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 966, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 329, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 963, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 578, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 965, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 323, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 331, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 712, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 3, CID = 574, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 575, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 576, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 320, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 322, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 997, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 998, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 999, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1000, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1001, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 330, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 324, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 983, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 984, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 985, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 978, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 332, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 979, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 980, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 500}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Originally, this function would spawn two creatures per spawn point instead of one as it should be. The above code fixes that. _AREA_CENTER_LIZARD_2: Spoiler function _AREA_CENTER_LIZARD_2(wpos) local AreaCreatures = { { Tag = 1, CID = 1047, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1473, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1474, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1475, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1476, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1477, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1827, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1828, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1829, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1830, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1831, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1832, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 3, CID = 1105, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1161, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1162, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1106, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1163, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1164, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 400}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Same issue as above, originally it was double the amount of creatures spawned. Edited May 22, 2023 by Lindor 1 1 Link to comment
Flix 5,116 Posted May 20, 2023 Share Posted May 20, 2023 The formatting alone was a much-needed change. I ran PFP's quest.txt through a code beautifier but it had too much trouble with questscripts.txt. Link to comment
Lindor 426 Posted May 20, 2023 Author Share Posted May 20, 2023 (edited) Welp, I'm doing it all by hand. For now, I'm only formatting every function which doesn't begin with "quest.setScript" and leave the rest alone. I'm already halfway through. Given the size, a full format by hand including the "real" questscripts could take about a year I think. I sorted everything into different files like events.lua, position.lua, teleport.lua etc. to increase overview. The idea is to build a tool which merges these files into a final questscripts.txt. This way you don't need to keep searching long. Edited May 20, 2023 by Lindor Link to comment
Lindor 426 Posted May 20, 2023 Author Share Posted May 20, 2023 The cutscenes questscripts are interesting. They are all nested functions; the outer function always defines an inner function called "feedback", but the feedback function is never called. Other than with object oriented programming languages like python, in lua functions defined without the "local" keyword really aren't local. I think the cutscenes functions are all just there to overwrite a global (hardcoded) feedback function. Which, if being called, plays a movie or some music or whatever. In a nutshell, the cutscenes questscripts don't actually play the movie, they define which movie is played next or which music is played next. The actual play happens inside by the "feedback" function, which is never called from inside questscripts.txt. Link to comment
Lindor 426 Posted May 20, 2023 Author Share Posted May 20, 2023 (edited) The "Platte8G" exists twice EDIT: I'm convinced that the second "Platte8G" was an accidental spelling mistake, it should be named "Platte8H" instead. Doesn't matter which one you rename, they both do the same. This should fix a broken teleporter somewhere. Edited May 20, 2023 by Lindor Link to comment
Lindor 426 Posted May 20, 2023 Author Share Posted May 20, 2023 (edited) would be interesting to know which teleporter this fixes. any ideas? EDIT: I think it's a teleporter in the blood forest which teleports your hero to sector BB-30 Edited May 20, 2023 by Lindor Link to comment
Lindor 426 Posted May 20, 2023 Author Share Posted May 20, 2023 Usually the hardcoded "getQuestState" function is called like this: getQuestState({id = 3650}) But for the functions "blutsee" and "blutgrotte" it's called like this: getQuestState(3650) getQuestState(3649) I don't know wether it's a bug or not, but I think so. These are questscripts for some blood forest quests I think. Any known bugs for these quests? Link to comment
Flix 5,116 Posted May 21, 2023 Share Posted May 21, 2023 2 hours ago, Lindor said: These are questscripts for some blood forest quests I think. Any known bugs for these quests? Yes. Androdion always said the main quest for the Blood Forest seemed to flow wrong. Actually speaking of which I just looked up these quests and I see a mismatch in one of the entries as well: quest.createQuest(3650, { id = 3650, name = "S_BI_3a_N_nn-Ice and Blood Mainstory - Gereinigtes Blut - T", The ID doesn't match. 1 Link to comment
Lindor 426 Posted May 21, 2023 Author Share Posted May 21, 2023 7 hours ago, Flix said: Yes. Androdion always said the main quest for the Blood Forest seemed to flow wrong. Actually speaking of which I just looked up these quests and I see a mismatch in one of the entries as well: quest.createQuest(3650, { id = 3650, name = "S_BI_3a_N_nn-Ice and Blood Mainstory - Gereinigtes Blut - T", The ID doesn't match. ? For me it looks like they match? 10 hours ago, Lindor said: I don't know wether it's a bug or not, but I think so. I found many more examples where the getQuestState function is called with an int as parameter. Actually it seems like the call with a table as a parameter is the exception and not vice versa. I still don't know if one of those routines is a bug. If the table call is a bug, then a couple of main quest scripts are a little bit broken, like the teleporting scripts at the Octagolamus valley. But ingame they seem to work well, so I think that the function can be called both ways, I'm just not 100% sure. Link to comment
Lindor 426 Posted May 21, 2023 Author Share Posted May 21, 2023 questID functions calling "getQuestState" via table quest name 339 scorpion "M_DE_1h_B_rr-DEB5b" 667 enterValley, enterDamm "M_OR_1i_B_nn-ORB6b" 712 oldDragon, oldDragonBack "M_DR_1k_G_rr-DRG6" 730 oldDragon, oldDragonBack "M_DR_1k_B_nn-DRB6a" 1287 showWaterfall "M_HE_1_nn-Startquest All" 1540 showWaterfall "M_OR_1g_G_nn-ORG5_Shaman-Ritual" 1570 enterDarkVillage "S_HU_3c_rr-Das Geisterdorf VT" 1559 showWaterfall "S_HE_1_N_db-Startquest Multiplayer All" 1622 scorpion "M_DE_1k_G_nn-DEG5" 3327 golemOben, golemUnten "S_HU_1_N_nn-Golem_Portal_DONOTDELETE" 3347 oldDragon, oldDragonBack, scorpion "S_DR_1_N_nn-Dragon Teleport - Free Play - DO NOT DELETE" 3714 Lichinsel "S_BI_3a_nn-Der verschollene General" 3782 Eisdungeon "S_BI_5_N_JT - Auf der Spur V" These are all the quests with table calls. For every ther call of the "getQuestState" function, the id is used directly as a parameter. Except showWaterfall, all functions are hero teleporting functions. Are there any bells ringing? Known bugs for these quests? Maybe similarities? Link to comment
Lindor 426 Posted May 21, 2023 Author Share Posted May 21, 2023 The function "onInitWorldobjects" uses "FTYPE_MAGICLIGHT" multiple times while it should be "FXTYPE_MAGICLIGHT". Spelling mistake. Link to comment
Lindor 426 Posted May 22, 2023 Author Share Posted May 22, 2023 (edited) Additional findings: the function "CM_FlushProtocol" doesn't seem to existin spite of being called by "CM_GarbageCollect"; either it's hardcoded or it's an unfinished idea the function "CM_ResolveQuestStates" doesn't do anything, looks like an unfinished idea the function "CM_Timed_OnPrecondsFulfilled" doesn't do anything, looks like an unfinished idea the function "CM_Timed_OnSetup" doesn't do anything, looks like an unfinished idea the function "CM_Timed_OnDeath" doesn't do anything, looks like an unfinished idea the function "CM_Timed_OnWon" doesn't do anything, looks like an unfinished idea the function "CM_Timed_OnLost" doesn't do anything, looks like an unfinished idea The CM patch scripts look like the very unfinished attempt to transform the questscripts.txt in a more overviewable state by scripting general functions for patterns within questsstages and then just calling the same functions over and over again. But as I said, it looks very unfinished. Next up I'll work on an overview of all hardcoded and non-hardcoded functions and variables. Edited May 22, 2023 by Lindor Link to comment
Lindor 426 Posted May 22, 2023 Author Share Posted May 22, 2023 There's a major mistake in the "_AREA_CENTER_GHOSTVILLAGE" function. The way the "AreaCreatures" table was set up, the entries would overwrite each other and in the end there's basically just one areacreature left. Here's the correction: function _AREA_CENTER_GHOSTVILLAGE(wpos) local AreaCreatures = { { Tag = 2, CID = 1077, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 1076, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 3, CID = 1080, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1078, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1079, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1081, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 300}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Link to comment
Lindor 426 Posted May 22, 2023 Author Share Posted May 22, 2023 18 hours ago, Lindor said: The function "onInitWorldobjects" uses "FTYPE_MAGICLIGHT" multiple times while it should be "FXTYPE_MAGICLIGHT". Spelling mistake. As can be seen here, the spelling mistake also exists in the dll files. I don't kow wether to use FTYPE or FXTYPE. Maybe none of those work due to the spelling mistake and other FX need to be applied instead or maybe both work and it doesn't matter. Needs to be tested (@Flix @idbeholdME @dimitrius154 someone wants to test? I can't dew it, my PC would potentially give false negatives due to it requiring minimum settings with PhysX disabled) Link to comment
Lindor 426 Posted May 22, 2023 Author Share Posted May 22, 2023 There's a big bug in the "_AREA_CENTER_HUMANS_CAPITAL" function. Originally it would spawn two creatures per spawn point. Here's the fix: function _AREA_CENTER_HUMANS_CAPITAL(wpos) local AreaCreatures = { { Tag = 1, CID = 316, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 325, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 318, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 1072, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 327, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 994, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 995, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 1, CID = 1043, Behaviour = "JOB_RICH_STATIST", Faction = 12, Equipment = 34 }, { Tag = 2, CID = 321, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 736, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 691, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 692, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 966, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 329, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 963, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 578, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 965, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 323, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 331, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 2, CID = 712, Behaviour = "JOB_KID", Faction = 12, Equipment = 43 }, { Tag = 3, CID = 574, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 575, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 576, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 320, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 322, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 997, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 998, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 999, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1000, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 1001, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 330, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 324, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 983, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 984, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 985, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 978, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 332, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 979, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 }, { Tag = 3, CID = 980, Behaviour = "JOB_POOR_STATIST", Faction = 12, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 500}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Link to comment
Lindor 426 Posted May 22, 2023 Author Share Posted May 22, 2023 9 minutes ago, Lindor said: There's a big bug in the "_AREA_CENTER_HUMANS_CAPITAL" function. Originally it would spawn two creatures per spawn point. Here's the fix: The same issue exists for "_AREA_CENTER_LIZARD_2". Fix: function _AREA_CENTER_LIZARD_2(wpos) local AreaCreatures = { { Tag = 1, CID = 1047, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1473, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1474, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1475, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1476, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1477, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1827, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1828, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1829, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1830, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1831, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 1, CID = 1832, Behaviour = "JOB_RICH_STATIST", Faction = 32, Equipment = 34 }, { Tag = 3, CID = 1105, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1161, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1162, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1106, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1163, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 }, { Tag = 3, CID = 1164, Behaviour = "JOB_POOR_STATIST", Faction = 32, Equipment = 33 } } local points, numPoints = getSpawnPoints({position = wpos, radius = 400}) local creatures = getn(AreaCreatures) if points then for id, object in ipairs(points) do local randomnumber = math.floor(math.random(1, creatures)) do spawnCreature({ behaviour = AreaCreatures[randomnumber].Behaviour, creature_id = AreaCreatures[randomnumber].CID, faction_id = AreaCreatures[randomnumber].Faction, equipset_id = AreaCreatures[randomnumber].Equipment, mortality = 0, position = object }) end end end end Link to comment
dimitrius154 612 Posted May 22, 2023 Share Posted May 22, 2023 On 5/21/2023 at 12:43 AM, Lindor said: I don't know wether it's a bug or not, but I think so. Looks like an alternate syntax. It's either GetQuestState(ID), or GetQuestState{id=ID} Link to comment
Lindor 426 Posted May 29, 2023 Author Share Posted May 29, 2023 On 5/20/2023 at 6:05 PM, Flix said: The formatting alone was a much-needed change. I ran PFP's quest.txt through a code beautifier but it had too much trouble with questscripts.txt. I have written my own lua code beautifier now and so far the results are promising. Can probably upload a fully formatted questscripts.txt in 2 weeks. Important functions formatting done by hand, actual questscripts formatting done by machine 1 Link to comment
Lindor 426 Posted June 10, 2023 Author Share Posted June 10, 2023 @dimitrius154 @Flix These are the cutscene functions being present in EE 3.2A: function cutscene_DM(args) function cutscene_DR_bad(args) function cutscene_DR_good(args) function cutscene_HE_bad(args) function cutscene_IN_bad(args) function cutscene_SE_good(args) function cutscene_SW(args) function cutscene_TG_bad(args) function cutscene_TG_good(args) It seems like there are three missing, one for DM, HE and SW each. It also seems like you added one of the missing functions in Addendum / Dark mod: function cutscene_HE_good(args) Do you two have more insights on them? Why are the missing functions not present? What are the consequences of adding cutscene_HE_good? Why are good and bad mixed into one function for DM / SW? Link to comment
dimitrius154 612 Posted June 10, 2023 Share Posted June 10, 2023 2 hours ago, Lindor said: Do you two have more insights on them? Why are the missing functions not present? What are the consequences of adding cutscene_HE_good? Why are good and bad mixed into one function for DM / SW? cutscene_HE_good is definitely present in vanilla, I've never tampered with it. These look like character starting cinematics, the devs must have considered alignment-dependent variations, but never made it happen, so there's no difference, whether _goog, or _bad is used. The SW introduction must have been coded last, so they didn't bother to make separate version. 1 Link to comment
Lindor 426 Posted June 10, 2023 Author Share Posted June 10, 2023 7 minutes ago, dimitrius154 said: cutscene_HE_good is definitely present in vanilla, I've never tampered with it. These look like character starting cinematics, the devs must have considered alignment-dependent variations, so there's no difference, whether _goog, or _bad is used. The SW introduction must have been coded last, so they didn't bother to make separate version. It was human error on my end, it's also present in EE 3.2A. Thx for clarification 1 Link to comment
Lindor 426 Posted June 10, 2023 Author Share Posted June 10, 2023 (edited) There is another questscripts.txt fix: One superfluous comma is breaking the syntax. Correction: do quest.setScript(2122, "OnDeath", function(args) local lizards = { {tcid = 6411, alive = true, behaviour = "Enemy_hunter"}, {tcid = 6413, alive = true, behaviour = "Enemy_warrior_kicknrush"}, {tcid = 6414, alive = true, behaviour = "Enemy_mage_phalanx"}, {tcid = 6415, alive = true, behaviour = "Enemy_mage_phalanx"}, {tcid = 6417, alive = true, behaviour = "Enemy_warrior_brave_ex"}, {tcid = 6418, alive = true, behaviour = "Enemy_warrior_brave_ex"}, {tcid = 6419, alive = true, behaviour = "Enemy_warrior_brave_ex"} } for I, lizard in ipair(lizards) do if args.tcid == lizard.tcid then do lizard.alive = false end do changeCreature({tcid = lizard.tcid, behaviour = "JOB_QUESTSTAGING", emotion = "ANIM_TYPE_SM20", mortality = "IMMORTAL", loopCount = - 1}) end end end if args.tcid == 6360 then for I, lizard in ipairs(lizards) do if lizard.alive == false then do changeCreature({tcid = lizard.tcid, behaviour = "JOB_QUESTSTAGING", emotion = "ANIM_TYPE_IDLE", loopCount = 1}) end do changeCreature({tcid = lizard.tcid, behaviour = lizard.behaviour, delay = 3}) end end end end end) end Previously, it would say "do lizard.alive = false,". The comma was breaking the syntax. I don't know wether this syntax bug was present prior to my prettification or not, but it would surprise me if it wasn't. EDIT: Actually the same issue exists for quest 2123 Edited June 10, 2023 by Lindor Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now