diff --git a/_datafiles/world/default/mobs/tutorial/scripts/58-training_dummy.js b/_datafiles/world/default/mobs/tutorial/scripts/58-training_dummy.js
index 92a1cc8b..141bad64 100644
--- a/_datafiles/world/default/mobs/tutorial/scripts/58-training_dummy.js
+++ b/_datafiles/world/default/mobs/tutorial/scripts/58-training_dummy.js
@@ -6,7 +6,8 @@ function onDie(mob, room, eventDetails) {
teacherMob = getTeacher(room);
- teacherMob.Command('say You did it! Head west to complete your training.');
+ teacherMob.Command('say You did it! As you can see you gain experience points for combat victories.');
+ teacherMob.Command('say Now head west to complete your training.', 2.0);
}
diff --git a/_datafiles/world/default/rooms/tutorial/900.js b/_datafiles/world/default/rooms/tutorial/900.js
index 3a6290a5..2b9ea638 100644
--- a/_datafiles/world/default/rooms/tutorial/900.js
+++ b/_datafiles/world/default/rooms/tutorial/900.js
@@ -18,12 +18,10 @@ function onCommand(cmd, rest, user, room) {
teacherMob = getTeacher(room);
- var extraDelay = 0;
// Make sure they are only doing stuff that's allowed.
if ( cmd == "east" && !canGoEast ) {
teacherMob.Command("say Not so hasty! Lets finish the basics before you leave this area.");
- extraDelay = 1.0;
ignoreCommand = true;
}
@@ -36,19 +34,16 @@ function onCommand(cmd, rest, user, room) {
teacherMob.Command("say Good job!", 1.0);
- extraDelay = 1.0;
-
if ( fullCommand == "look orb" ) {
- teacherMob.Command('say As you can see, looking at me shows you a description and some information about what I\'m carrying.', 2.0);
- extraDelay = 2.0;
+ teacherMob.Command('say As you can see, looking at me shows you a description and some information about what I\'m carrying.', 1.0);
}
if ( fullCommand == "look east" ) {
- teacherMob.Command('say Looking into exits like that shows you what (or who) is in a room before you visit it.', 2.0);
- teacherMob.Command('say Later when you find objects, you can look at them in the same manner.', 3.0);
- teacherMob.Command('say It\'s always worth trying to look at something you\'re curious about, just in case.', 4.0);
- teacherMob.Command('emote considers for a moment.', 5.0);
- extraDelay = 7.0;
+ teacherMob.Command('say Looking into exits like that shows you what (or who) is in a room before you visit it.', 1.0);
+ teacherMob.Command('say Later when you find objects, you can look at them in the same manner.', 1.0);
+ teacherMob.Command('say It\'s always worth trying to look at something you\'re curious about, just in case.', 1.0);
+ teacherMob.Command('emote considers for a moment.', 1.0);
+ teacherMob.Command('noop', 3.0);
}
commandNow++;
@@ -63,28 +58,28 @@ function onCommand(cmd, rest, user, room) {
switch (commandNow) {
case 0:
- teacherMob.Command('say The first thing you need to learn is how to inspect your surroundings', extraDelay+1.0);
- teacherMob.Command('say type look and hit enter to see a description of the area you are in.', extraDelay+2.0);
+ teacherMob.Command('say The first thing you need to learn is how to inspect your surroundings', 1.0);
+ teacherMob.Command('say type look and hit enter to see a description of the area you are in.', 1.0);
break;
case 1:
- teacherMob.Command('say You can also look at creatures or people in the room.', extraDelay+1.0);
- teacherMob.Command('say type look orb to look at me, ' + teacherMob.GetCharacterName(true) + '.', extraDelay+2.0);
+ teacherMob.Command('say You can also look at creatures or people in the room.', 1.0);
+ teacherMob.Command('say type look orb to look at me, ' + teacherMob.GetCharacterName(true) + '.', 1.0);
break;
case 2:
- teacherMob.Command('say Try the look command again, but this time, pay attention to any exits.', extraDelay+1.0);
+ teacherMob.Command('say Try the look command again, but this time, pay attention to any exits.', 1.0);
break;
case 3:
- teacherMob.Command('say Did you notice there is an exit to the east?', extraDelay+1.0);
- teacherMob.Command('say type look east to look into the east room.', extraDelay+2.0);
+ teacherMob.Command('say Did you notice there is an exit to the east?', 1.0);
+ teacherMob.Command('say type look east to look into the east room.', 1.0);
break;
case 4:
canGoEast = true;
- teacherMob.Command('say It\'s time to move on to the next thing you\'ll learn about.', extraDelay+1.0);
- teacherMob.Command('say type east to travel through the east exit.', extraDelay+2.0);
+ teacherMob.Command('say It\'s time to move on to the next thing you\'ll learn about.', 1.0);
+ teacherMob.Command('say type east to travel through the east exit.', 1.0);
break;
default:
- teacherMob.Command('say It\'s time to move on to the next thing you\'ll learn about.', extraDelay+1.0);
- teacherMob.Command('say type east to travel through the east exit.', extraDelay+2.0);
+ teacherMob.Command('say It\'s time to move on to the next thing you\'ll learn about.', 1.0);
+ teacherMob.Command('say type east to travel through the east exit.', 1.0);
break;
}
@@ -105,9 +100,9 @@ function onEnter(user, room) {
teacherMob.Command('emote appears in a ' + UtilApplyColorPattern("flash of light!", "glowing"));
teacherMob.Command('say Welcome to the Newbie School!', 1.0);
- teacherMob.Command('say I\'ll give you some tips to help you get started.', 2.0);
- teacherMob.Command('say In this area you\'ll learn the basics of inspecting your environment with the look command.', 3.0);
- teacherMob.Command('say type look and hit enter to see a description of the area you are in.', 5.0);
+ teacherMob.Command('say I\'ll give you some tips to help you get started.', 1.0);
+ teacherMob.Command('say In this area you\'ll learn the basics of inspecting your environment with the look command.', 1.0);
+ teacherMob.Command('say type look and hit enter to see a description of the area you are in.', 1.0);
}
diff --git a/_datafiles/world/default/rooms/tutorial/901.js b/_datafiles/world/default/rooms/tutorial/901.js
index 712134f4..27340dd8 100644
--- a/_datafiles/world/default/rooms/tutorial/901.js
+++ b/_datafiles/world/default/rooms/tutorial/901.js
@@ -19,7 +19,6 @@ function onCommand(cmd, rest, user, room) {
teacherMob = getTeacher(room);
- var extraDelay = 0;
// Make sure they are only doing stuff that's allowed.
if ( cmd == "south" && !canGoSouth ) {
@@ -35,18 +34,15 @@ function onCommand(cmd, rest, user, room) {
if ( teach_commands[commandNow] == fullCommand ) {
teacherMob.Command("say Good job!", 1.0);
- extraDelay = 1.0;
if ( cmd == "status" ) {
- teacherMob.Command('say You can see how much gold you carry, your Level, and even attributes like Strength and Smarts.', 2.0);
- teacherMob.Command('say It\'s a lot of information, but you quickly learn to only pay attention to the important stuff.', 3.0);
- extraDelay = 3.0;
+ teacherMob.Command('say You can see how much Gold you carry, your Level, and even attributes like Strength and Smarts.', 1.0);
+ teacherMob.Command('say It\'s a lot of information, but you\'ll quickly learn to only pay attention to the important stuff.', 1.0);
}
if ( cmd == "inventory" ) {
- teacherMob.Command('say Hmm, it doesn\'t look like you\'re carrying much other than that sharp stick.', 2.0);
- teacherMob.Command('say Remember, you can look at stuff you\'re carrying any time you want.', 3.0);
- extraDelay = 3.0;
+ teacherMob.Command('say Hmm, it doesn\'t look like you\'re carrying much other than that sharp stick.', 1.0);
+ teacherMob.Command('say Remember, you can look at stuff you\'re carrying any time you want.', 1.0);
}
commandNow++;
@@ -67,24 +63,26 @@ function onCommand(cmd, rest, user, room) {
user.GiveItem(itm);
}
- teacherMob.Command('say To see all of your characters stats, type status.', extraDelay+1.0);
+ teacherMob.Command('say To see all of your characters stats, type status.', 1.0);
break;
case 1:
- teacherMob.Command('say To only peek at your inventory, type inventory.', extraDelay+1.0);
+ teacherMob.Command('say To only peek at your inventory, type inventory.', 1.0);
break;
case 2:
- teacherMob.Command('say As you solve quests and defeat enemies in combat, you\'ll gain experience points and your character will "Level up".', extraDelay+1.0);
- teacherMob.Command('say For quick look at your progress, type experience.', extraDelay+2.0);
+ teacherMob.Command('say As you solve quests and defeat enemies in combat, you\'ll gain experience points and your character will "Level up".', 1.0);
+ teacherMob.Command('say For quick look at your progress, type experience.', 1.0);
break;
case 3:
teacherMob.Command('emote touches you and you feel more focused.');
user.GiveBuff(32, "training");
- teacherMob.Command('say Sometimes you might become afflicted with a condition. Conditions can have good or bad effects.',extraDelay+1.0);
- teacherMob.Command('say type conditions to see any statuses affecting you.', extraDelay+2.0);
+ teacherMob.Command('noop', 2);
+ teacherMob.Command('say Sometimes you might become afflicted with a condition. Conditions can have good or bad effects (and sometimes both!).',1.0);
+ teacherMob.Command('say type conditions to see any statuses affecting you.', 1.0);
break;
case 4:
user.GiveBuff(-32, "training");
- teacherMob.Command('say head south for the next lesson.', extraDelay+1.0);
+ teacherMob.Command('say Some special conditions might last indefinitely, such as natural abilities like night vision. Others may expire after enough time passes.', 1.0);
+ teacherMob.Command('say head south for the next lesson.', 1.0);
canGoSouth = true;
room.SetLocked("south", false);
break;
@@ -110,7 +108,7 @@ function onEnter(user, room) {
teacherMob.Command('emote appears in a ' + UtilApplyColorPattern("flash of light!", "glowing"));
teacherMob.Command('say Hi! I\'m here to teach you about inspecting your characters information.', 1.0);
- teacherMob.Command('say To get a detailed view of a LOT of information all at once, type status and hit enter.', 2.0);
+ teacherMob.Command('say To get a detailed view of a LOT of information all at once, type status and hit enter.', 1.0);
}
diff --git a/_datafiles/world/default/rooms/tutorial/902.js b/_datafiles/world/default/rooms/tutorial/902.js
index 6ef15b8a..243730e5 100644
--- a/_datafiles/world/default/rooms/tutorial/902.js
+++ b/_datafiles/world/default/rooms/tutorial/902.js
@@ -17,7 +17,6 @@ function onCommand(cmd, rest, user, room) {
teacherMob = getTeacher(room);
- var extraDelay = 0;
// Make sure they are only doing stuff that's allowed.
if ( cmd == "south" && !canGoSouth ) {
@@ -34,17 +33,13 @@ function onCommand(cmd, rest, user, room) {
teacherMob.Command("say Good job!", 1.0);
- extraDelay = 1.0;
-
if ( cmd == "equip stick" ) {
- teacherMob.Command('say Check it out! If you type status you\'ll see the stick is equipped!', 2.0);
- extraDelay = 2.0;
+ teacherMob.Command('say Check it out! If you type status you\'ll see the stick is equipped!', 1.0);
}
if ( cmd == "inventory" ) {
- teacherMob.Command('say Hmm, it doesn\'t look like you\'re carrying much other than that sharp stick.', 2.0);
- teacherMob.Command('say Remember, you can look at stuff you\'re carrying any time you want.', 3.0);
- extraDelay = 3.0;
+ teacherMob.Command('say Hmm, it doesn\'t look like you\'re carrying much other than that sharp stick.', 1.0);
+ teacherMob.Command('say Remember, you can look at stuff you\'re carrying any time you want.', 1.0);
}
commandNow++;
@@ -70,14 +65,14 @@ function onCommand(cmd, rest, user, room) {
user.GiveItem(itm);
}
- teacherMob.Command('say Go ahead and equip that sharp stick you\'ve got. Type equip stick.', extraDelay+1.0);
+ teacherMob.Command('say Go ahead and equip that sharp stick you\'ve got. Type equip stick.', 1.0);
break;
case 1:
getDummy(room);
- teacherMob.Command('say You may have noticed the training dummy here.', extraDelay+1.0);
- teacherMob.Command('say Go ahead and engage in combat by typing attack dummy.', extraDelay+2.0);
+ teacherMob.Command('say You may have noticed the training dummy here.', 1.0);
+ teacherMob.Command('say Go ahead and engage in combat by typing attack dummy. Don\'t worry, it can\'t hurt you.', 1.0);
break;
case 2:
// teacherMob.Command('say Head west to complete your training.');
@@ -110,7 +105,7 @@ function onEnter(user, room) {
user.GiveItem(itm);
}
- teacherMob.Command('say Go ahead and equip that sharp stick you\'ve got. Type equip stick.', 2.0);
+ teacherMob.Command('say Go ahead and equip that sharp stick you\'ve got. Type equip stick.', 1.0);
}
diff --git a/_datafiles/world/default/rooms/tutorial/903.js b/_datafiles/world/default/rooms/tutorial/903.js
index a00574b8..d5e21f83 100644
--- a/_datafiles/world/default/rooms/tutorial/903.js
+++ b/_datafiles/world/default/rooms/tutorial/903.js
@@ -16,8 +16,6 @@ function onCommand(cmd, rest, user, room) {
teacherMob = getTeacher(room);
- var extraDelay = 0;
-
fullCommand = cmd;
if ( rest.length > 0 ) {
fullCommand = cmd + ' ' + rest;
@@ -35,8 +33,6 @@ function onCommand(cmd, rest, user, room) {
teacherMob.Command("say Good job! You earned it!", 1.0);
}
- extraDelay = 1.0;
-
commandNow++;
} else {
@@ -50,24 +46,24 @@ function onCommand(cmd, rest, user, room) {
switch (commandNow) {
case 0:
- teacherMob.Command('emote gestures to the graduation cap on the ground.', extraDelay+2.0);
- teacherMob.Command('say type get cap to pick up the graduation cap.', extraDelay+3.0);
+ teacherMob.Command('emote gestures to the graduation cap on the ground.', 1.0);
+ teacherMob.Command('say type get cap to pick up the graduation cap.', 1.0);
break;
case 1:
- teacherMob.Command('say Go ahead and wear the graduation cap by typing equip cap.', extraDelay+2.0);
+ teacherMob.Command('say Go ahead and wear the graduation cap by typing equip cap.', 1.0);
break;
case 2:
- teacherMob.Command('say It\'s time to say goodbye', extraDelay+1.0);
- teacherMob.Command('say I\ll summon a portal to send you to the heart of Frostfang city, where your adventure begins.', extraDelay+2.0);
+ teacherMob.Command('say It\'s time to say goodbye', 1.0);
+ teacherMob.Command('say I\'ll summon a portal to send you to the heart of Frostfang city, where your adventure begins.', 1.0);
exits = room.GetExits();
if ( !exits.portal ) {
- teacherMob.Command('emote glows intensely, and a ' + UtilApplyColorPattern('swirling portal', 'pink') + ' appears!', extraDelay+3.0);
- room.AddTemporaryExit('swirling portal', ':pink', 0, 9000); // RoomId 0 is an alias for start room
+ teacherMob.Command('emote glows intensely, and a ' + UtilApplyColorPattern('swirling portal', 'pink') + ' appears!', 1.0);
+ room.AddTemporaryExit('swirling portal', ':pink', 0, "1 real day"); // RoomId 0 is an alias for start room. Portal can live a long time since the room is ephemeral.
}
- teacherMob.Command('say Enter the portal by typing swirling portal (or just portal) when you are ready.', extraDelay+4.0);
+ teacherMob.Command('say Enter the portal by typing swirling portal (or just portal) when you are ready.', 1.0);
break;
default:
@@ -94,9 +90,9 @@ function onEnter(user, room) {
teacherMob.Command('emote appears in a ' + UtilApplyColorPattern("flash of light!", "glowing"));
teacherMob.Command('say Congratulation on getting to the end of the training course!', 1.0);
- teacherMob.Command('drop cap', 2.0);
+ teacherMob.Command('drop cap', 1.0);
teacherMob.Command('emote gestures to the graduation cap on the ground.', 3.0);
- teacherMob.Command('say type get cap to pick up the graduation cap.', 4.0);
+ teacherMob.Command('say type get cap to pick up the graduation cap.', 1.0);
}
diff --git a/internal/mobs/mobs.go b/internal/mobs/mobs.go
index 0fd0927d..96386202 100644
--- a/internal/mobs/mobs.go
+++ b/internal/mobs/mobs.go
@@ -77,6 +77,7 @@ type Mob struct {
tempDataStore map[string]any
conversationId int // Identifier of conversation currently involved in.
Path PathQueue `yaml:"-"` // a pre-calculated path the mob is following.
+ lastCommandTurn uint64 // The last turn a command was scheduled for
}
func MobInstanceExists(instanceId int) bool {
@@ -324,17 +325,32 @@ func (m *Mob) Sleep(seconds int) {
func (m *Mob) Command(inputTxt string, waitSeconds ...float64) {
readyTurn := util.GetTurnCount()
+ turnDelay := uint64(0)
+
+ // m.lastCommandTurn is used so that subsequent calls to Command()
+ // are scheduled from this period forward.
+ // If it's been long enough that the current turn has surpassed the lastCommandTurn, we failover to that.
+ if readyTurn > m.lastCommandTurn {
+ m.lastCommandTurn = readyTurn
+ } else {
+ readyTurn = m.lastCommandTurn
+ }
+
if len(waitSeconds) > 0 {
- readyTurn += uint64(float64(configs.GetTimingConfig().SecondsToTurns(1)) * waitSeconds[0])
+ turnDelay = uint64(float64(configs.GetTimingConfig().SecondsToTurns(1)) * waitSeconds[0])
}
- for _, cmd := range strings.Split(inputTxt, `;`) {
+ for i, cmd := range strings.Split(inputTxt, `;`) {
+
+ // Update lastCommandTurn to whenever this command is scheduled for
+ m.lastCommandTurn = readyTurn + turnDelay + uint64(i)
+
events.AddToQueue(events.Input{
MobInstanceId: m.InstanceId,
InputText: cmd,
- ReadyTurn: readyTurn,
+ ReadyTurn: m.lastCommandTurn,
})
- readyTurn++
+
}
}