Answer the question
In order to leave comments, you need to log in
What template should I use for a quest machine with a large number of steps?
There is a script for a bot, for completing quests in one MMO game, created and designed by me.
The problem is that I don't like it, because I applied the anti-pattern (without realizing it, it was a long time ago ) God Object .
How it works
When I wrote it, I was thinking about a finite state machine that transitions from one state after performing the next step.
If step 87, say, succeeds, then the automaton will proceed to the next step 88.
If quest step 87 fails (for example, another player attacks the bot and prevents you from talking to the NPC)
then the step will be repeated and the automaton will again go to state 87. In each state, error handling is possible and the JumpStep command, thanks to which you can go from state 87 to 65 or any other. (for handling a death case in the middle of a quest)
Problem: how to implement all this in code?
I really didn’t want to create an array of objects and functions or sculpt a giant case of (aka switch in C ++) because it all eats up RAM + when you have to add a new method, you have to edit this array / case
I solved the problem using the RTTI Pascal chip thanks to which you can call an object's method by its name . The result is a class with a bunch of steps Step1 Step2 ... Step120 .. Inside the automaton I store the step number and when I need to go to the next step I just call
code like: call_method ('Step'+intToStr(Step_Num));
In reality, the code looks like this (S is for Step)
procedure TSE.S76;
begin
StepRes:=Go('Шнаин') and (Q([NPC_Shnain,DLG_Ischeznuvshiy_Sakum__v_protsesse_,1,1]) or WaitQS(Qu20,-1));
end;
{----------------------}
const Qu21=10334;
procedure TSE.S77;
begin
StepRes:=Go('Шнаин') and (Q([NPC_Shnain,DLG_Osmotr_kholma_Vetryanyykh_Melynits,1,1]) or WaitQS(Qu21,1));
end;
{----------------------}
procedure TSE.S78;
begin
StepRes:=true;
if PosOutRange('Gludio',5000) then
StepRes:=Escape(TravelSoe);
StepRes:=StepRes and Go('Батис') and (Q([NPC_Batis, DLG_Osmotr_kholma_Vetryanyykh_Melynits__v_protsesse_,1,1]) or WaitQS(Qu21,-1));
if stepRes then
prs['DqusetWeapon']:=QEvents.LastItemAdd;
end;
{----------------------}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question