Custom quest support

For all talk about quest development - creation, testing, and quest system bug diagnosis.
User avatar
Jay_H
Posts: 3274
Joined: Tue Aug 25, 2015 1:54 am

Re: Custom quest support

Post by Jay_H » Mon Sep 23, 2019 11:45 pm

No problem. Thanks for the answer :)
Come join Lysandus' Tomb, a Daggerfall Unity fan Discord.
In-progress guide for Quest Pack 1 here.

imsobadatnicknames
Posts: 20
Joined: Sun Jun 02, 2019 4:28 pm

Re: Custom quest support

Post by imsobadatnicknames » Wed Jun 03, 2020 3:19 am

Kind of a dumb question, but is there a way to spawn non-hostile NPCs in a quest? I'm specifically asking about NPCs like Knights, Mages, Thieves etc. I only know how to spawn them in a way that makes them hostile to the player.

Also, I think this might be an impossibility but I lose nothing by asking so... is it possible to create a task that triggers when you're inside of any building of a given type instead of a specific building? What I mean is, instead of defining, e.g., a specific General Store at the start of the quest and then have a task that triggers when I'm inside that specific General Store, is it possible to have a task that triggers whenever I'm inside any general store?

I have an idea to create a sort of mod that spawns appropriate walking NPCs inside certain buildings, to make it seem like you're not the only person in the world who frequents places like shops and guilds. So for example, you could see Knights walking around inside armories and Fighers Guilds, or Mages and Spellswords inside Mages Guilds. I'm guessing the easiest way to do it would be to create a "quest" that starts at the beggining of the game and detects whenever you're inside an appropriate building, and spawns one NPC every few minutes.

I think it's a cool idea but, of course, all of this is dependant on what I said on the second paragraph (the ability to trigger tasks when the player enters a certain type of building rather than a specific building of the given type), so it might not even be possible. Just asking around to see how possible it would be.

User avatar
Jay_H
Posts: 3274
Joined: Tue Aug 25, 2015 1:54 am

Re: Custom quest support

Post by Jay_H » Wed Jun 03, 2020 3:28 am

imsobadatnicknames wrote:
Wed Jun 03, 2020 3:19 am
Kind of a dumb question, but is there a way to spawn non-hostile NPCs in a quest? I'm specifically asking about NPCs like Knights, Mages, Thieves etc. I only know how to spawn them in a way that makes them hostile to the player.
You have to spawn them and use the "restrain" command. There's also "unrestrain" as of 0.10.23, to make them hostile again.
Also, I think this might be an impossibility but I lose nothing by asking so... is it possible to create a task that triggers when you're inside of any building of a given type instead of a specific building? What I mean is, instead of defining, e.g., a specific General Store at the start of the quest and then have a task that triggers when I'm inside that specific General Store, is it possible to have a task that triggers whenever I'm inside any general store?
No, that capability exists for exteriors like farmhome, templehome, city, etc but not for individual buildings.
I have an idea to create a sort of mod that spawns appropriate walking NPCs inside certain buildings, to make it seem like you're not the only person in the world who frequents places like shops and guilds. So for example, you could see Knights walking around inside armories and Fighers Guilds, or Mages and Spellswords inside Mages Guilds. I'm guessing the easiest way to do it would be to create a "quest" that starts at the beggining of the game and detects whenever you're inside an appropriate building, and spawns one NPC every few minutes.
Kamer does that for Warm Ashes: Cities. I recommend going through its quest files to figure that out -- not sure myself how that's done, though I have a couple theories. However, they won't be walking around; enemies either track a foe or stand still.
Come join Lysandus' Tomb, a Daggerfall Unity fan Discord.
In-progress guide for Quest Pack 1 here.

imsobadatnicknames
Posts: 20
Joined: Sun Jun 02, 2019 4:28 pm

Re: Custom quest support

Post by imsobadatnicknames » Wed Jun 03, 2020 3:44 am

Alright, thank you for the response! I guess I'll check out Warm Ashes and dig around a little through its quest files.

So, I've never heard of the restrain command before but I'm guessing the way to use it would be something like

Code: Select all

Foe _knight_ is 2 Knight
and then

Code: Select all

_spawn_ task:
	create foe _knight_ every 5 minutes 3 times with 50% success
	restrain _knight_
Right?

User avatar
Jay_H
Posts: 3274
Joined: Tue Aug 25, 2015 1:54 am

Re: Custom quest support

Post by Jay_H » Wed Jun 03, 2020 3:51 am

Yes, though I haven't experimented with it enough to know whether it restrains future enemies or just the ones currently spawned. But it works on all enemies of the class you choose, so that's right.
Come join Lysandus' Tomb, a Daggerfall Unity fan Discord.
In-progress guide for Quest Pack 1 here.

imsobadatnicknames
Posts: 20
Joined: Sun Jun 02, 2019 4:28 pm

Re: Custom quest support

Post by imsobadatnicknames » Thu Jun 04, 2020 3:24 pm

I think I figured out a reasonable enough workaround for what I want to do. It would be to have a "quest" that restarts every time the player enters a town and chooses a local Fighters Guild, Mages Guild, Tavern, and store of every type to start populating with NPCs when the player enters. With taverns and stores it would be kind of a shot in the dark wether the player would even enter the one that has been chosen by the quest, but most towns tend to have only one Fighters Guild and Mages guild so it'd be almost sure that the player would see the effect of more NPCs spawning as they spend time inside.

The only bit of knowledge I still need to find out would be how to make it so that the quest is always starts running at the beginning of the game. I'm guessing that's done in the questlist?

User avatar
Jay_H
Posts: 3274
Joined: Tue Aug 25, 2015 1:54 am

Re: Custom quest support

Post by Jay_H » Thu Jun 04, 2020 6:52 pm

Yeah, you can configure that in the quest list. I made a QuestList-Misc.txt file in Quest Pack 1:

Code: Select all

JHPFIRST, InitAtGameStart, M, 0, 0, Initializes a few quests
So that runs JHPFIRST when the character first loads. JHPFIRST does this:

Code: Select all

Message:  1010
<ce>                       Quest Pack #1 initiated.

QBN:

Clock _init_ 0:05
Clock _timer_ 0:02

--   Quest start-up:
    say 1010
    start timer _init_

_init_ task:
    start timer _timer_
    start quest JHCART
    pick one of _q1_ _q2_ _q3_

_level_ task:
    level 3 completed

variable _q1_
variable _q2_
variable _q3_
_p1_ task:
    when _q1_ and not _level_
    start quest JHPQB01

_p2_ task:
    when _q2_ and not _level_
    start quest JHPQB02

_p3_ task:
    when _q3_ and not _level_
    start quest JHPQB03

_timer_ task:
    end quest
So it then executes the rest of the starting tasks I want to make happen.
Come join Lysandus' Tomb, a Daggerfall Unity fan Discord.
In-progress guide for Quest Pack 1 here.

imsobadatnicknames
Posts: 20
Joined: Sun Jun 02, 2019 4:28 pm

Re: Custom quest support

Post by imsobadatnicknames » Thu Jun 04, 2020 9:26 pm

Thnak you, that helps a lot! So, I just cobbled this together (covering just the guilds), and haven't had time to test it yet but here's what I have so far. I've decided to name the mod "Populated Buildings"

So, first, I configured the Questlist like you said

Code: Select all

PB-STARTUP, InitAtGameStart, M, 0, 0, Mod startup
It will activate PB-STARTUP

Code: Select all

Quest: PB-STARTUP
DisplayName: PBStartup
-- Message panels
QRC:

Message: 1010
<ce>  Activate Populated Buildings?          

QBN:

--	Quest start-up:
    prompt 1010 yes _start_ no _quit_

_start_ task:
	start quest PB-MASTER

_quit_ task:
    end quest

Which will ask the player if they want to activate the mod, and if the player slects yes it will initialize PB-MASTER

Code: Select all

Quest: PB-MASTER
DisplayName: PBmaster
-- Message panels
QRC:

Message: 1010
<ce>  NPCs will spawn in shops, taverns, 
<ce>	guilds and temples          

QBN:


--	Quest start-up:
	say 1010


_entercity_ task:
	when pc enters city
	start quest PB-GUILDS
	clear _exitcity_

_exitcity_ task:
	when pc exits city
	clear _entercity_
	
 
PB-MASTER will inform the player that NPCs will now be appearing in certain buildings (this is mostly just so I can see if the quest started correctly when I test it). When the player enters a city, it will activate the _entercity_ task, which will start the quest PB-GUILDS. Exiting the city will clear the _entercity_ task.

Code: Select all

Quest: PB-GUILDS
DisplayName: Populated Buildings - Guilds
-- Message panels
QRC:

Message: 1020
<ce>   test1              

QBN:

Foe _f1_ is Warrior
Foe _f2_ is Knight
Foe _f3_ is Mage
Foe _f4_ is Spellsword
Place _g1_ local magery
Place _g2_ local magery
Clock _restraintimer_ 0.00:01


--	Quest start-up:
	say 1020
	pc at _g1_ set _inside1_
	pc at _g2_ set _inside2_

_inside1_ task:

_inside2_ task:

_spawn1_ task:
	when _inside1_ 
	create foe _f1_ every 3 minutes 3 times with 50% success
	create foe _f2_ every 3 minutes 3 times with 50% success
	restrain foe _f1_
	restrain foe _f2_
	start timer _restraintimer_

_spawn2_ task:
	when _inside2_ 
	create foe _f3_ every 3 minutes 3 times with 50% success
	create foe _f4_ every 3 minutes 3 times with 50% success
	restrain foe _f3_
	restrain foe _f4_
	start timer _restraintimer_


_restraintimer_ task:

_restrain1_ task:
	when _inside1_ and _restraintimer_
	restrain foe _f1_
	restrain foe _f2_
	start timer _restraintimer_
	clear _restrain1_

_restrain2_ task:
	when _inside2_ and _restraintimer_
	restrain foe _f1_
	restrain foe _f2_
	start timer _restraintimer_
	clear _restrain2_

_exitcity_ task:
	when pc exits city
	end quest

When initialized, PB-GUILDS will display a message that says "test1" (again, this is only to inform me that the quest initialized correctly and will be removed later). It will choose two random guilds in town. When the player enters any of those guilds, the _spawn1_ or _spawn2_ task will create some foes and restrain them.

The _restraintimer_ part is something I'm not entirely sure about. Since I'm not sure either if restrain will work on future NPCs or only the ones that are created when it's used, I have created a one-minute timer. When the timer reaches 0 and the player is inside any of the two guilds chosen by the quest, the _restrain1_ or _restrain2_ task will fire up, restraining any hostile NPCs that have been created in the meantime, and then it will restrain the timer.
I'm not sure if just saying "start timer _reatraintimer_" is the right way to restar a timer, or if I´m doing it wrong :lol:

User avatar
Jay_H
Posts: 3274
Joined: Tue Aug 25, 2015 1:54 am

Re: Custom quest support

Post by Jay_H » Thu Jun 04, 2020 9:50 pm

There is a sure way to restrain future-spawned enemies instantly, but I'm not sure how much we should use it because I think it's performance-heavy. No one's done any stress tests on it, so it's hard to say how much it would take (particularly if multiple quests use this hack at the same time). See this:

Code: Select all

_day_ task:
    daily from 0:00 to 23:59
    restrain foe _vamp_
    clear _day_
This restrains any spawned _vamp_ foe over and over again, multiple times per second, as this task fights for control of itself (in vain).
Come join Lysandus' Tomb, a Daggerfall Unity fan Discord.
In-progress guide for Quest Pack 1 here.

imsobadatnicknames
Posts: 20
Joined: Sun Jun 02, 2019 4:28 pm

Re: Custom quest support

Post by imsobadatnicknames » Thu Jun 04, 2020 10:10 pm

Hmmmmmm, that is interesting. However, since multiple versions of this quest are intended to be running a the same time, I think it could get pretty resource-intensive, so I think I'm gonna stick to my 1-minute timer workaround. I just wasn't sure if the

Code: Select all

_restrain2_ task:
	when _inside2_ and _restraintimer_
	restrain foe _f1_
	restrain foe _f2_
	start timer _restraintimer_
	clear _restrain2_
structure would work. Is writing "start timer _restraintimer_" enough to make the timer start counting down again, or do I need to do any extra steps like putting something along the lines of "clear _restraintimer_" in there?

Post Reply