[Scummvm-git-logs] scummvm master -> bf65d18086e1215c045397f2e1cc9554d57ec3b8

dreammaster noreply at scummvm.org
Mon May 11 04:29:46 UTC 2026


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
244d183529 MADS: DRAGONSPHERE: Added room 117
6df29a1295 MADS: DRAGONSPHERE: Added room 116
cf6e77fd0f MADS: DRAGONSPHERE: Added room 116
a3ee41524d MADS: DRAGONSPHERE: Added room 118
bf65d18086 MADS: DRAGONSPHERE: Added room 119


Commit: 244d183529d3f8f82218ecd8edaf5e44f081513d
    https://github.com/scummvm/scummvm/commit/244d183529d3f8f82218ecd8edaf5e44f081513d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-11T14:26:58+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 117

Changed paths:
    engines/mads/madsv2/dragonsphere/rooms/room117.cpp


diff --git a/engines/mads/madsv2/dragonsphere/rooms/room117.cpp b/engines/mads/madsv2/dragonsphere/rooms/room117.cpp
index dc4075112a2..ecd3435202a 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room117.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room117.cpp
@@ -22,7 +22,9 @@
 #include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
 #include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
 #include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,6 +41,9 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[4];     /* Animation handles     */
 };
 
 #define local (&scratch)
@@ -46,26 +51,100 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
 
-void room_117_init() {
+/* ========================= Sprites ========================= */
 
-}
+#define fx_swim_to_left      1 /* rm117c0 */
+#define fx_swim_to_right     2 /* rm117c1 */
 
-void room_117_daemon() {
 
-}
+/* ======================== Triggers ========================= */
+
+#define ROOM_117_SWIM_LEFT   70
+#define ROOM_117_SWIM_RIGHT  80
+#define ROOM_117_BUBBLES     90
+
+
+static void room_117_init() {
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();  /* clear interface */
+	kernel_set_interface_mode(INTER_CONVERSATION);
+
+	if (kernel.teleported_in) {
+		inter_give_to_player(crystal_ball);
+		inter_give_to_player(shifter_ring);
+		inter_give_to_player(magic_belt);
+		global[player_persona] = PLAYER_IS_PID;
+	}
 
-void room_117_pre_parser() {
+	player.commands_allowed = false;
+	player.walker_visible = false;
 
+	if (previous_room == 109) {
+		/* Seal comes from Dungeon room */
+		ss[fx_swim_to_right] = kernel_load_series(kernel_name('c', 1), false);
+		global[no_load_walker] = false;
+		kernel_timing_trigger(TENTH_SECOND, ROOM_117_SWIM_RIGHT);
+
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		/* Seal comes from below Way station rm 113 */
+		ss[fx_swim_to_left] = kernel_load_series(kernel_name('c', 0), false);
+		kernel_timing_trigger(TENTH_SECOND, ROOM_117_SWIM_LEFT);
+	}
+
+	section_1_music();
 }
 
-void room_117_parser() {
+static void room_117_daemon() {
+	switch (kernel.trigger) {
+	case ROOM_117_SWIM_LEFT:
+		seq[fx_swim_to_left] = kernel_seq_forward(ss[fx_swim_to_left], false, 7, 0, 0, 1);
+		kernel_seq_trigger(seq[fx_swim_to_left],
+			KERNEL_TRIGGER_EXPIRE, 0, ROOM_117_SWIM_LEFT + 1);
+		kernel_seq_trigger(seq[fx_swim_to_left],
+			KERNEL_TRIGGER_SPRITE, 21, ROOM_117_BUBBLES);
+		sound_play(N_RushingWater);
+		break;
+
+	case ROOM_117_SWIM_LEFT + 1:
+		global[no_load_walker] = true;
+		new_room = 109;
+		break;
+
+	case ROOM_117_SWIM_RIGHT:
+		seq[fx_swim_to_left] = kernel_seq_forward(ss[fx_swim_to_left], false, 7, 0, 0, 1);
+		kernel_seq_trigger(seq[fx_swim_to_left],
+			KERNEL_TRIGGER_EXPIRE, 0, ROOM_117_SWIM_RIGHT + 1);
+		kernel_seq_trigger(seq[fx_swim_to_left],
+			KERNEL_TRIGGER_SPRITE, 4, ROOM_117_BUBBLES);
+		kernel_seq_trigger(seq[fx_swim_to_left],
+			KERNEL_TRIGGER_SPRITE, 24, ROOM_117_BUBBLES);
+		sound_play(N_RushingWater);
+		break;
+
+	case ROOM_117_BUBBLES:
+		sound_play(N_WaterBubbles);
+		break;
+
+	case ROOM_117_SWIM_RIGHT + 1:
+		new_room = 113;
+		break;
+	}
+}
+
+static void room_117_pre_parser() {
+	// No implementation
+}
 
+static void room_117_parser() {
+	// No implementation
 }
 
 void room_117_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
 }
 
 void room_117_preload() {


Commit: 6df29a12953228f577f2f83645bb1d67f975f6f9
    https://github.com/scummvm/scummvm/commit/6df29a12953228f577f2f83645bb1d67f975f6f9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-11T14:26:58+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 116

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/inventory.h
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room116.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/inventory.h b/engines/mads/madsv2/dragonsphere/mads/inventory.h
index 0523348fba7..ce6340e228d 100644
--- a/engines/mads/madsv2/dragonsphere/mads/inventory.h
+++ b/engines/mads/madsv2/dragonsphere/mads/inventory.h
@@ -36,8 +36,11 @@ enum {
 	bone             =  6,
 	fruit            =  7,
 	pid_doll         =  8,
+	key_crown        = 13,
 	statue           = 15,
+	soul_egg         = 17,
 	magic_belt       = 18,
+	amulet           = 19,
 	crystal_ball     = 29,
 	shifter_ring     = 32,
 	rare_coin        = 38,
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index c48ea3a0a78..a17b79d4dcc 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -40,6 +40,7 @@ enum {
 	N_QueenMother        =  45,
 	N_TurnDiaryPage      =  65,
 	N_WallGrinds         =  67,
+	N_RushingWater       =  71,
 	N_DragonInWater      =  72,
 	N_OldMachinery       =  74,
 	N_DogWhimper         =  79,
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index df0b0b359b8..f4e64f18066 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -62,6 +62,7 @@ enum {
 	words_dates                =  78,
 	words_statue               =  79,
 	words_bottle_of_flies      =  80,
+	N_WaterBubbles             =  86,
 	words_thrust               =  87,
 	words_torch                =  93,
 	words_rope                 = 101,
@@ -144,6 +145,7 @@ enum {
 	words_scullery_maid        = 266,
 	words_ward                 = 268,
 	words_darkness_beast       = 269,
+	words_guard                = 272,
 	words_doorway              = 277,
 	words_faerie               = 278,
 	words_guard_captain        = 280,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
index 42e1dac31fa..7a94c583a29 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
@@ -22,7 +22,9 @@
 #include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
 #include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
 #include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,6 +41,27 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[4];     /* Animation handles     */
+
+	int16 temp;             /* for synching sprites */
+	int16 kingsicle_id;     /* hotspot id for frozen king */
+	int16 bear_status;      /* for when player is a bear */
+	int16 animation_running;
+	int16 current_frame;    /* helps keep track of frame animation is on */
+	int16 just_melted;      /* the king just melted - free up player commands */
+
+	int16 king_frame;       /* animation frame being held for King stuff */
+	int16 king_action;      /* Type of action to run for King animation */
+	int16 king_talk_count;  /* counter for King talking */
+	int16 anim_1_running;
+
+	int16 lift_frame;       /* animation frame being held for lifting King stuff */
+	int16 lift_action;      /* Type of action to run for lifting King animation */
+	int16 anim_2_running;
+
+	int16 invoked_ring;
 };
 
 #define local (&scratch)
@@ -46,22 +69,620 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
+
+
+/* ========================= Sprites ========================= */
+
+#define fx_door                 1  /* rm116x  */
+#define fx_open_door            2  /* rm116g  */ 
+#define fx_kingsicle            3  /* rm116a4 */
+#define fx_bear_morph           4  /* rm116b1 */
+#define fx_give_soul            5  /* pdrm_6  */
+#define fx_spill                6  /* rm116x1 */
+#define fx_smoke                7  /* rm116a5 */
+#define fx_single_king          8  /* rm116a3 */
+
+
+/* ======================== Triggers ========================= */
+
+#define ROOM_116_DOOR_CLOSES    70
+#define ROOM_116_YOU_TALK       78
+#define ROOM_116_ME_TALK        79
+#define ROOM_116_LEAVE_ROOM     81
+
+
+/* walk points */
+#define START_X_ROOM_119        291
+#define START_Y_ROOM_119        84
+#define START_X_ROOM_115        196
+#define START_Y_ROOM_115        152
+
+#define WALK_TO_X_FROM_119      246
+#define WALK_TO_Y_FROM_119      98
+
+#define WALK_TO_KINGSICLE_X     165
+#define WALK_TO_KINGSICLE_Y     145
+
+#define WALK_TO_KING_SOUL_X     152
+#define WALK_TO_KING_SOUL_Y     145
+
+/* conversations */
+/* conv013.con   */
+#define CONVERSATION_WITH_KING  13
+
+/* dynamic hotspots */
+#define KING_X                  120
+#define KING_Y                  95
+#define KING_X_SIZE             13
+#define KING_Y_SIZE             50
+
+/* animation descriptions */
+#define KING_OFF_ICE            1
+#define KING_THRU_DOOR          2
+
+/* animations */
+/* rm116a.aa - bear pulls king off pedestal */
+
+/* for bear_status */
+#define HAS_NEVER_BEEN_A_BEAR   0
+#define FIRST_TIME_BEAR         1
+#define IS_PID_AGAIN            2 
+#define IS_A_BEAR_AGAIN         3 
+
+#define KING_SHUT_UP            0
+#define KING_TALK               1
 
-void room_116_init() {
 
+static void room_116_init() {
+	local->invoked_ring = false;
+
+	ss[fx_spill] = kernel_load_series(kernel_name('x', 1), false);
+
+	if (global[king_is_in_stairwell]) {
+		seq[fx_spill] = kernel_seq_stamp(ss[fx_spill], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_spill], 15);
+	}
+
+	ss[fx_open_door] = kernel_load_series(kernel_name('g', -1), false);
+	ss[fx_door] = kernel_load_series(kernel_name('x', -1), false);
+	ss[fx_single_king] = kernel_load_series(kernel_name('a', 3), false);
+
+	if (global[king_status] == KING_CAPTIVE) {
+		ss[fx_bear_morph] = kernel_load_series(kernel_name('b', 1), false);
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->bear_status = HAS_NEVER_BEEN_A_BEAR;
+		local->just_melted = false;
+		local->anim_1_running = false;
+		local->anim_2_running = false;
+		local->animation_running = false;
+	}
+
+	conv_get(CONVERSATION_WITH_KING);
+
+	if (global[king_status] == KING_CAPTIVE) {
+		ss[fx_give_soul] = kernel_load_series("*PDRM_6", false);
+		ss[fx_kingsicle] = kernel_load_series(kernel_name('a', 4), false);
+		seq[fx_kingsicle] = kernel_seq_stamp(ss[fx_kingsicle], false, KERNEL_FIRST);
+
+
+		local->kingsicle_id = kernel_add_dynamic(words_king, words_walk_to, SYNTAX_MASC_NOT_PROPER,
+			seq[fx_kingsicle], 0, 0, 0, 0);
+		kernel_dynamic_hot[local->kingsicle_id].prep = PREP_ON;
+		kernel_seq_depth(seq[fx_kingsicle], 5);
+		kernel_dynamic_walk(local->kingsicle_id, WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_NORTHWEST);
+
+	} else if (!global[king_is_in_stairwell]) {
+		if (global[king_status] == KING_WITHOUT_SOUL) {
+			ss[fx_give_soul] = kernel_load_series("*PDRM_6", false);
+		}
+		aa[1] = kernel_run_animation(kernel_name('C', -1), 0);
+		local->anim_1_running = true;
+		local->king_action = KING_SHUT_UP;
+		local->kingsicle_id = kernel_add_dynamic(words_king, words_walk_to, SYNTAX_MASC_NOT_PROPER,
+			KERNEL_NONE, KING_X, KING_Y, KING_X_SIZE,
+			KING_Y_SIZE);
+		kernel_dynamic_walk(local->kingsicle_id, WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_WEST);
+	}
+
+	if (previous_room == 119) {        /* Player comes from Stairwell*/
+		seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_door], 14);
+		player_first_walk(START_X_ROOM_119, START_Y_ROOM_119, FACING_SOUTHWEST,
+			WALK_TO_X_FROM_119, WALK_TO_Y_FROM_119, FACING_SOUTHWEST,
+			false);
+		player_walk_trigger(ROOM_116_DOOR_CLOSES);
+
+	} else if (previous_room != KERNEL_RESTORING_GAME) {  /* Player comes from Darkness Beast room 115*/
+		player.x = START_X_ROOM_115;
+		player.y = START_Y_ROOM_115;
+		player.facing = FACING_NORTH;
+		seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_door], 14);
+
+	} else {
+		seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_door], 14);
+		if (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) {
+			player.walker_visible = false;
+			seq[fx_bear_morph] = kernel_seq_stamp(ss[fx_bear_morph], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_bear_morph], 4);
+		}
+		if (conv_restore_running == CONVERSATION_WITH_KING) {
+			local->king_action = KING_SHUT_UP;
+			player.facing = FACING_WEST;
+			conv_run(CONVERSATION_WITH_KING);
+			if (global[king_status] == KING_WITH_SOUL) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+		}
+	}
+
+	section_1_music();
 }
 
-void room_116_daemon() {
+static void handle_animation_lift() {
+	int lift_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->lift_frame) {
+		local->lift_frame = kernel_anim[aa[2]].frame;
+		lift_reset_frame = -1;
+
+		switch (local->lift_frame) {
+		case 9:
+			kernel_seq_delete(seq[fx_kingsicle]);
+			kernel_delete_dynamic(local->kingsicle_id);
+			break;
 
+		case 26:
+			seq[fx_single_king] = kernel_seq_stamp(ss[fx_single_king], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_single_king], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_single_king], KERNEL_ANIM, aa[2]);
+			break;
+
+		case 31:
+			if (player_said_1(crystal_ball)) {
+				text_show(11617);
+				inter_move_object(crystal_ball, NOWHERE);
+				text_show(970);
+			}
+			kernel_abort_animation(aa[2]);
+			aa[0] = kernel_run_animation(kernel_name('k', -1), 0);
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_NOW, 0);
+			kernel_reset_animation(aa[0], 33);
+			local->just_melted = true;
+			local->animation_running = KING_OFF_ICE;
+			local->anim_2_running = false;
+			lift_reset_frame = -1;
+			break;
+		}
+
+		if (lift_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], lift_reset_frame);
+			local->lift_frame = lift_reset_frame;
+		}
+	}
 }
 
-void room_116_pre_parser() {
 
+static void handle_animation_king() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[1]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame) {
+		case 1:  /* end of talk 1 */
+		case 2:  /* end of talk 2 */
+		case 3:  /* end of talk 3 */
+			if (local->king_action == KING_TALK) {
+
+				king_reset_frame = imath_random(0, 2);
+				++local->king_talk_count;
+				if (local->king_talk_count > 15) {
+					local->king_action = KING_SHUT_UP;
+					local->king_talk_count = 0;
+					king_reset_frame = 0; /* freeze */
+				}
+
+			} else {
+				king_reset_frame = 0; /* freeze */
+			}
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
 }
 
-void room_116_parser() {
+static void room_116_daemon() {
+	int reset_frame;
+
+	if (local->anim_1_running) {
+		handle_animation_king();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_lift();
+	}
+
+	if (local->animation_running == KING_OFF_ICE) {
+		if (kernel_anim[aa[0]].frame != local->current_frame) {
+			local->current_frame = kernel_anim[aa[0]].frame;
+			reset_frame = -1;
+
+			switch (local->current_frame) {
+			case 34:
+				kernel_seq_delete(seq[fx_single_king]);
+				break; /* delete king on ice so he can melt */
+
+			case 43:
+				player.walker_visible = true;
+				player_demand_facing(FACING_WEST);
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+				break;
+
+			case 73:
+				if (local->just_melted) {
+					kernel_load_variant(1);
+					local->just_melted = false;
+					local->bear_status = IS_PID_AGAIN;
+					global[king_status] = KING_WITHOUT_SOUL;
+					kernel_delete_dynamic(local->kingsicle_id);
+					local->kingsicle_id = kernel_add_dynamic(words_king, words_walk_to, SYNTAX_MASC_NOT_PROPER,
+						KERNEL_NONE, KING_X, KING_Y, KING_X_SIZE,
+						KING_Y_SIZE);
+					kernel_dynamic_hot[local->kingsicle_id].prep = PREP_ON;
+					kernel_dynamic_walk(local->kingsicle_id, WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_WEST);
+					player.commands_allowed = true;
+
+					kernel_abort_animation(aa[0]);
+					reset_frame = -1;
+					local->animation_running = 0;
+					aa[1] = kernel_run_animation(kernel_name('c', -1), 0);
+					local->king_action = KING_SHUT_UP;
+					local->anim_1_running = true;
+
+					conv_run(CONVERSATION_WITH_KING);
+					conv_export_value(0);
+				}
+				break;
+			}
+
+			if (reset_frame >= 0) {
+				if (reset_frame != kernel_anim[aa[0]].frame) {
+					kernel_reset_animation(aa[0], reset_frame);
+					local->current_frame = reset_frame;
+				}
+			}
+		}
+	}
 
+	if (kernel.trigger >= ROOM_116_DOOR_CLOSES) {
+		switch (kernel.trigger) {
+		case ROOM_116_DOOR_CLOSES:
+			kernel_seq_delete(seq[fx_door]);
+			sound_play(N_DoorCloses);
+			seq[fx_door] = kernel_seq_backward(ss[fx_door], false,
+				7, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_seq_range(seq[fx_door], 1, 5);
+			kernel_seq_trigger(seq[fx_door],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_116_DOOR_CLOSES + 1);
+			break;
+
+		case ROOM_116_DOOR_CLOSES + 1:
+			local->temp = seq[fx_door];
+			seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_synch(KERNEL_SERIES, seq[fx_door], KERNEL_SERIES, local->temp);
+			player.commands_allowed = true;
+			break;
+		}
+	}
+}
+
+static void room_116_pre_parser() {
+	if (!player_parse(words_look, 0) &&
+	    !player_parse(words_push, words_king, 0) &&
+	    !player_parse(7, words_king, words_cave_floor, 0) &&
+	    !player_parse(words_pull, words_king, 0) &&
+	    !player_parse(words_take, words_king, 0) &&
+	    !player_parse(words_walk_to, words_king, 0) &&
+	    (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) &&
+	    global[king_status] == KING_CAPTIVE &&
+	    (player.need_to_walk || player_parse(words_revert, 0))) {
+
+		switch (kernel.trigger) {
+		case 0:
+			player.commands_allowed = false;
+			player.ready_to_walk = false;
+			kernel_seq_delete(seq[fx_bear_morph]);
+			seq[fx_bear_morph] = kernel_seq_backward(ss[fx_bear_morph], false, 8, 1, 0, 0);
+			kernel_seq_depth(seq[fx_bear_morph], 4);
+			kernel_seq_trigger(seq[fx_bear_morph], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			break;
+
+		case 1:
+			local->bear_status = IS_PID_AGAIN;
+			player.walker_visible = true;
+			player.commands_allowed = true;
+			if (!player_parse(words_revert, 0)) {
+				player.ready_to_walk = true;
+			}
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_bear_morph]);
+			break;
+		}
+	}
+
+	if (player_parse(words_invoke_power_of, words_crystal_ball, 0)) {
+		if (local->bear_status == HAS_NEVER_BEEN_A_BEAR ||
+		    local->bear_status == IS_PID_AGAIN) {
+			if (global[king_status] == KING_CAPTIVE ||
+			    global[king_status] == KING_WITHOUT_SOUL) {
+				player_walk(WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_WEST);
+			}
+		}
+	}
+}
+
+static void room_116_conv13() {
+	bool flag1 = false, flag2 = false;
+
+	if (player_verb == 3) {
+		flag1 = flag2 = true;
+
+		if (kernel.trigger == 0)
+			conv_me_trigger(81);
+	}
+
+	if (kernel.trigger == 81)
+		new_room = local->invoked_ring ? 115 : 110;
+
+	if (kernel.trigger == 78)
+		local->king_action = 1;
+	if (kernel.trigger == 79)
+		local->king_action = 0;
+
+	if (!flag2)
+		conv_me_trigger(79);
+	if (!flag1)
+		conv_you_trigger(78);
+
+	local->king_talk_count = 0;
+}
+
+static void room_116_parser() {
+	if (conv_control.running == CONVERSATION_WITH_KING) {
+		room_116_conv13();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_parse(words_revert, 0) &&
+	    (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN)) {
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		text_show(global[king_status] == KING_CAPTIVE ? 11601 : 11608);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_parse(words_talk_to, words_king, 0)) {
+		if (global[king_status] == KING_CAPTIVE) {
+			text_show(11626);
+		} else {
+			conv_run(CONVERSATION_WITH_KING);
+			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
+			conv_export_value(0);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	// Door to stairwell (room 119) — noun 230
+	if (player_parse(words_walk_through, 230, 0) ||
+	    player_parse(words_open, 230, 0) ||
+	    player_parse(words_pull, 230, 0)) {
+		switch (kernel.trigger) {
+		case 0:
+			player.commands_allowed = false;
+			if (local->anim_1_running) {
+				kernel_abort_animation(aa[1]);
+				local->anim_1_running = false;
+				aa[0] = kernel_run_animation(kernel_name('f', -1), 0);  // TODO: verify 'f' animation
+			}
+			kernel_seq_delete(seq[fx_door]);
+			seq[fx_door] = kernel_seq_pingpong(ss[fx_door], false, 7, 0, 0, 5);  // TODO: verify pingpong count
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_seq_trigger(seq[fx_door], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			kernel_timing_trigger(45, 3);  // TODO: verify timing
+			break;
+		case 1:
+			kernel_seq_delete(seq[fx_door]);
+			sound_play(N_DoorOpens);
+			seq[fx_open_door] = kernel_seq_forward(ss[fx_open_door], false, 7, 0, 0, 0);
+			kernel_seq_depth(seq[fx_open_door], 14);
+			kernel_seq_trigger(seq[fx_open_door], KERNEL_TRIGGER_EXPIRE, 0, 2);
+			break;
+		case 2:
+			local->temp = seq[fx_open_door];
+			kernel_seq_delete(seq[fx_open_door]);
+			seq[fx_open_door] = kernel_seq_stamp(ss[fx_open_door], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_open_door], 14);
+			kernel_synch(KERNEL_SERIES, seq[fx_open_door], KERNEL_SERIES, local->temp);
+			break;
+		case 3:
+			player.walker_visible = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_open_door]);
+			kernel_timing_trigger(1, 4);
+			break;
+		case 4:
+			player_walk(START_X_ROOM_119, START_Y_ROOM_119, FACING_EAST);
+			if (!global[king_is_in_stairwell])  // TODO: verify condition
+				player_walk_trigger(5);
+			break;
+		case 5:
+			if (global[king_is_in_stairwell]) {  // TODO: verify condition
+				seq[fx_spill] = kernel_seq_stamp(ss[fx_spill], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_spill], 15);
+			}
+			kernel_seq_delete(seq[fx_open_door]);
+			sound_play(N_DoorCloses);
+			seq[fx_door] = kernel_seq_backward(ss[fx_door], false, 7, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_seq_trigger(seq[fx_door], KERNEL_TRIGGER_EXPIRE, 0, 6);
+			break;
+		case 6:
+			local->temp = seq[fx_door];
+			kernel_seq_delete(seq[fx_door]);
+			seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_synch(KERNEL_SERIES, seq[fx_door], KERNEL_SERIES, local->temp);
+			new_room = 119;
+			break;
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	// Door to darkness beast room (room 115) — noun 228
+	if (player_parse(words_walk_through, 228, 0) ||
+	    player_parse(words_open, 228, 0) ||
+	    player_parse(words_pull, 228, 0)) {
+		// TODO: verify exact behavior (conv + export or direct room change)
+		new_room = 115;
+		player.command_ready = false;
+		return;
+	}
+
+	// Can't shift into seal/snake while a bear
+	if ((player_parse(words_shift_into_seal, 0) || player_parse(words_shift_into_snake, 0)) &&
+	    (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN)) {
+		text_show(11622);  // TODO: verify text ID
+		player.command_ready = false;
+		return;
+	}
+
+	// Shift into bear / invoke crystal ball (bear transformation)
+	if (player_parse(words_shift_into_bear, 0) ||
+	    player_parse(words_invoke_power_of, words_crystal_ball, 0)) {
+		if (local->bear_status == HAS_NEVER_BEEN_A_BEAR ||
+		    local->bear_status == IS_PID_AGAIN) {
+			switch (kernel.trigger) {
+			case 0:
+				player.commands_allowed = false;
+				player.walker_visible = false;
+				kernel_seq_delete(seq[fx_bear_morph]);
+				seq[fx_bear_morph] = kernel_seq_forward(ss[fx_bear_morph], false, 8, 0, 0, 0);
+				kernel_seq_depth(seq[fx_bear_morph], 4);
+				kernel_seq_trigger(seq[fx_bear_morph], KERNEL_TRIGGER_EXPIRE, 0, 1);
+				break;
+			case 1:
+				if (local->bear_status == HAS_NEVER_BEEN_A_BEAR)
+					local->bear_status = FIRST_TIME_BEAR;
+				else
+					local->bear_status = IS_A_BEAR_AGAIN;
+				player.commands_allowed = true;
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_bear_morph]);
+				break;
+			case 2:
+				// TODO: verify case 2 content
+				break;
+			}
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	// Bear grabs king / gives soul to king
+	if (player_parse(words_push, words_king, 0) ||
+	    player_parse(words_pull, words_king, 0) ||
+	    player_parse(words_take, words_king, 0)) {
+		if (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) {
+			switch (kernel.trigger) {
+			case 0:
+				if (player_has(crystal_ball)) {
+					sound_play(N_InvokeCrystalBall);
+					kernel_timing_trigger(1, 3);
+				} else {
+					player_walk(WALK_TO_KING_SOUL_X, WALK_TO_KING_SOUL_Y, FACING_WEST);
+					player_walk_trigger(1);
+				}
+				break;
+			case 1:
+				if (!player_has(crystal_ball)) {
+					seq[fx_give_soul] = kernel_seq_pingpong(ss[fx_give_soul], false, 7, 0, 0, 0);
+					kernel_seq_depth(seq[fx_give_soul], 3);
+					kernel_seq_trigger(seq[fx_give_soul], KERNEL_TRIGGER_EXPIRE, 0, 2);
+					kernel_timing_trigger(60, 3);  // TODO: verify timing
+				}
+				break;
+			case 2:
+				sound_play(97);
+				ss[fx_smoke] = kernel_load_series(kernel_name('a', 5), false);
+				seq[fx_smoke] = kernel_seq_forward(ss[fx_smoke], false, 7, 0, 0, 0);
+				kernel_seq_depth(seq[fx_smoke], 1);
+				kernel_seq_range(seq[fx_smoke], KERNEL_FIRST, KERNEL_LAST);
+				kernel_seq_trigger(seq[fx_smoke], KERNEL_TRIGGER_EXPIRE, 0, 4);
+				break;
+			case 3:
+				if (player_has(crystal_ball)) {
+					text_show(11617);
+					inter_move_object(crystal_ball, NOWHERE);
+					text_show(970);
+					kernel_timing_trigger(1, 6);
+				} else {
+					player.walker_visible = true;
+					kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_give_soul]);
+				}
+				break;
+			case 4:
+				matte_deallocate_series(ss[fx_smoke], -1);
+				kernel_timing_trigger(1, 5);
+				break;
+			case 5:
+				kernel_timing_trigger(10, 6);
+				break;
+			case 6:
+				if (!player_has(crystal_ball)) {
+					inter_move_object(soul_egg, NOWHERE);
+					text_show(11614);
+				}
+				global[king_status] = KING_WITH_SOUL;
+				global[player_score] += 5;
+				player.commands_allowed = true;
+				conv_run(CONVERSATION_WITH_KING);
+				conv_export_value(1);
+				break;
+			}
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	// TODO: look/look_at specific noun responses
+
+	// Bear form verb filter
+	if (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) {
+		text_show(32);
+		player.command_ready = false;
+		return;
+	}
+
+	// TODO: words_heal + words_king response
+	// TODO: words_sword / words_attack + words_king response
 }
 
 void room_116_synchronize(Common::Serializer &s) {
@@ -74,8 +695,24 @@ void room_116_preload() {
 	room_parser_code_pointer = room_116_parser;
 	room_daemon_code_pointer = room_116_daemon;
 
+	if (kernel.teleported_in) {
+		inter_give_to_player(key_crown);
+		inter_give_to_player(crystal_ball);
+		inter_give_to_player(shifter_ring);
+		inter_give_to_player(soul_egg);
+		inter_give_to_player(amulet);
+		global[player_persona] = PLAYER_IS_PID;
+	}
+
 	section_1_walker();
 	section_1_interface();
+
+	if ((global[king_status] != KING_CAPTIVE) && (!global[king_is_in_stairwell])) {
+		kernel_initial_variant = 1;
+	}
+
+	vocab_make_active(words_king);
+	vocab_make_active(words_walk_to);
 }
 
 } // namespace Rooms


Commit: cf6e77fd0f72e779147e27eb73aa55748a882b35
    https://github.com/scummvm/scummvm/commit/cf6e77fd0f72e779147e27eb73aa55748a882b35
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-11T14:26:58+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 116

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room116.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index a17b79d4dcc..531a7ef617c 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -45,6 +45,7 @@ enum {
 	N_OldMachinery       =  74,
 	N_DogWhimper         =  79,
 	N_BeastSnd           =  80,
+	N_GrabKing           =  82,
 	N_JumpDownWell       =  93,
 	N_BooksRumble        =  94,
 	N_McMornTipsTable    = 100
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index f4e64f18066..85806952da0 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -33,8 +33,12 @@ enum {
 	words_take                 =   4,
 	words_push                 =   5,
 	words_open                 =   6,
+	words_put                  =   7,
 	words_talk_to              =   8,
+	words_give                 =   9,
 	words_pull                 =  10,
+	words_close                =  11,
+	words_throw                =  12,
 	words_walk_to              =  13,
 	words_floor                =  16,
 	words_walk_across          =  17,
@@ -123,6 +127,8 @@ enum {
 	words_crank                = 224,
 	words_bucket               = 225,
 	words_jump_down            = 226,
+	words_door_to_darkness     = 228,
+	words_door_to_stairwell    = 230,
 	words_painting             = 231,
 	words_document             = 232,
 	words_ink_bottle           = 233,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
index 7a94c583a29..89159454c22 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
@@ -75,7 +75,7 @@ static Scratch scratch;
 /* ========================= Sprites ========================= */
 
 #define fx_door                 1  /* rm116x  */
-#define fx_open_door            2  /* rm116g  */ 
+#define fx_open_door            2  /* rm116g  */
 #define fx_kingsicle            3  /* rm116a4 */
 #define fx_bear_morph           4  /* rm116b1 */
 #define fx_give_soul            5  /* pdrm_6  */
@@ -118,6 +118,7 @@ static Scratch scratch;
 #define KING_Y_SIZE             50
 
 /* animation descriptions */
+#define KING_NO_ANIMATION       0
 #define KING_OFF_ICE            1
 #define KING_THRU_DOOR          2
 
@@ -127,8 +128,8 @@ static Scratch scratch;
 /* for bear_status */
 #define HAS_NEVER_BEEN_A_BEAR   0
 #define FIRST_TIME_BEAR         1
-#define IS_PID_AGAIN            2 
-#define IS_A_BEAR_AGAIN         3 
+#define IS_PID_AGAIN            2
+#define IS_A_BEAR_AGAIN         3
 
 #define KING_SHUT_UP            0
 #define KING_TALK               1
@@ -157,7 +158,7 @@ static void room_116_init() {
 		local->just_melted = false;
 		local->anim_1_running = false;
 		local->anim_2_running = false;
-		local->animation_running = false;
+		local->animation_running = KING_NO_ANIMATION;
 	}
 
 	conv_get(CONVERSATION_WITH_KING);
@@ -434,7 +435,7 @@ static void room_116_pre_parser() {
 	}
 }
 
-static void room_116_conv13() {
+static void room_116_conversation_with_king() {
 	bool flag1 = false, flag2 = false;
 
 	if (player_verb == 3) {
@@ -462,21 +463,18 @@ static void room_116_conv13() {
 
 static void room_116_parser() {
 	if (conv_control.running == CONVERSATION_WITH_KING) {
-		room_116_conv13();
-		player.command_ready = false;
-		return;
+		room_116_conversation_with_king();
+		goto handled;
 	}
 
 	if (player_parse(words_revert, 0) &&
 	    (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN)) {
-		player.command_ready = false;
-		return;
+		goto handled;
 	}
 
 	if (player.look_around) {
 		text_show(global[king_status] == KING_CAPTIVE ? 11601 : 11608);
-		player.command_ready = false;
-		return;
+		goto handled;
 	}
 
 	if (player_parse(words_talk_to, words_king, 0)) {
@@ -487,41 +485,42 @@ static void room_116_parser() {
 			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
 			conv_export_value(0);
 		}
-		player.command_ready = false;
-		return;
+		goto handled;
 	}
 
-	// Door to stairwell (room 119) — noun 230
-	if (player_parse(words_walk_through, 230, 0) ||
-	    player_parse(words_open, 230, 0) ||
-	    player_parse(words_pull, 230, 0)) {
+	if (player_parse(words_walk_through, words_door_to_stairwell, 0) ||
+	    player_parse(words_open, words_door_to_stairwell, 0) ||
+	    player_parse(words_pull, words_door_to_stairwell, 0)) {
 		switch (kernel.trigger) {
 		case 0:
 			player.commands_allowed = false;
-			if (local->anim_1_running) {
+
+			if (global[king_status] == KING_WITH_SOUL && !global[king_is_in_stairwell]) {
 				kernel_abort_animation(aa[1]);
 				local->anim_1_running = false;
-				aa[0] = kernel_run_animation(kernel_name('f', -1), 0);  // TODO: verify 'f' animation
+				aa[0] = kernel_run_animation(kernel_name('B', -1), 0);
+				local->animation_running = KING_THRU_DOOR;
 			}
-			kernel_seq_delete(seq[fx_door]);
-			seq[fx_door] = kernel_seq_pingpong(ss[fx_door], false, 7, 0, 0, 5);  // TODO: verify pingpong count
-			kernel_seq_depth(seq[fx_door], 14);
-			kernel_seq_trigger(seq[fx_door], KERNEL_TRIGGER_EXPIRE, 0, 1);
-			kernel_timing_trigger(45, 3);  // TODO: verify timing
+
+			player.walker_visible = false;
+			seq[fx_open_door] = kernel_seq_pingpong(ss[fx_open_door], false, 8, 2, 0, 0);
+			kernel_seq_player(seq[fx_open_door], -1);
+			kernel_seq_trigger(seq[fx_open_door], KERNEL_TRIGGER_SPRITE, 2, 1);
+			kernel_seq_trigger(seq[fx_open_door], KERNEL_TRIGGER_EXPIRE, 0, 3);
 			break;
+
 		case 1:
 			kernel_seq_delete(seq[fx_door]);
 			sound_play(N_DoorOpens);
-			seq[fx_open_door] = kernel_seq_forward(ss[fx_open_door], false, 7, 0, 0, 0);
-			kernel_seq_depth(seq[fx_open_door], 14);
-			kernel_seq_trigger(seq[fx_open_door], KERNEL_TRIGGER_EXPIRE, 0, 2);
+			seq[fx_open_door] = kernel_seq_forward(ss[fx_door], false, 7, 0, 0, 0);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_seq_trigger(seq[fx_door], KERNEL_TRIGGER_EXPIRE, 0, 2);
 			break;
 		case 2:
-			local->temp = seq[fx_open_door];
-			kernel_seq_delete(seq[fx_open_door]);
-			seq[fx_open_door] = kernel_seq_stamp(ss[fx_open_door], false, KERNEL_LAST);
-			kernel_seq_depth(seq[fx_open_door], 14);
-			kernel_synch(KERNEL_SERIES, seq[fx_open_door], KERNEL_SERIES, local->temp);
+			local->temp = seq[fx_door];
+			seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_door], 14);
+			kernel_synch(KERNEL_SERIES, seq[fx_door], KERNEL_SERIES, local->temp);
 			break;
 		case 3:
 			player.walker_visible = true;
@@ -530,15 +529,17 @@ static void room_116_parser() {
 			break;
 		case 4:
 			player_walk(START_X_ROOM_119, START_Y_ROOM_119, FACING_EAST);
-			if (!global[king_is_in_stairwell])  // TODO: verify condition
+
+			if (global[king_status] == KING_WITH_SOUL && global[king_is_in_stairwell])
 				player_walk_trigger(5);
 			break;
 		case 5:
-			if (global[king_is_in_stairwell]) {  // TODO: verify condition
+			if (global[king_status] != KING_CAPTIVE || global[king_is_in_stairwell]) {
 				seq[fx_spill] = kernel_seq_stamp(ss[fx_spill], false, KERNEL_FIRST);
-				kernel_seq_depth(seq[fx_spill], 15);
+				kernel_seq_depth(seq[fx_spill], 10);
 			}
-			kernel_seq_delete(seq[fx_open_door]);
+
+			kernel_seq_delete(seq[fx_door]);
 			sound_play(N_DoorCloses);
 			seq[fx_door] = kernel_seq_backward(ss[fx_door], false, 7, 0, 0, 1);
 			kernel_seq_depth(seq[fx_door], 14);
@@ -546,100 +547,179 @@ static void room_116_parser() {
 			break;
 		case 6:
 			local->temp = seq[fx_door];
-			kernel_seq_delete(seq[fx_door]);
 			seq[fx_door] = kernel_seq_stamp(ss[fx_door], false, KERNEL_FIRST);
 			kernel_seq_depth(seq[fx_door], 14);
 			kernel_synch(KERNEL_SERIES, seq[fx_door], KERNEL_SERIES, local->temp);
 			new_room = 119;
 			break;
 		}
-		player.command_ready = false;
-		return;
+		goto handled;
 	}
 
-	// Door to darkness beast room (room 115) — noun 228
-	if (player_parse(words_walk_through, 228, 0) ||
-	    player_parse(words_open, 228, 0) ||
-	    player_parse(words_pull, 228, 0)) {
-		// TODO: verify exact behavior (conv + export or direct room change)
-		new_room = 115;
-		player.command_ready = false;
-		return;
+	if (player_parse(words_walk_through, words_door_to_darkness, 0) ||
+			player_parse(words_open, 228, 0) ||
+			player_parse(words_pull, 228, 0)) {
+		if (global[king_status] == KING_WITH_SOUL && !global[king_is_in_stairwell]) {
+			conv_run(13);
+			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
+			conv_export_value(1);
+		} else {
+			new_room = 115;
+		}
+		goto handled;
 	}
 
 	// Can't shift into seal/snake while a bear
 	if ((player_parse(words_shift_into_seal, 0) || player_parse(words_shift_into_snake, 0)) &&
 	    (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN)) {
-		text_show(11622);  // TODO: verify text ID
-		player.command_ready = false;
-		return;
+		text_show(990);
+		goto handled;
 	}
 
 	// Shift into bear / invoke crystal ball (bear transformation)
 	if (player_parse(words_shift_into_bear, 0) ||
 	    player_parse(words_invoke_power_of, words_crystal_ball, 0)) {
-		if (local->bear_status == HAS_NEVER_BEEN_A_BEAR ||
-		    local->bear_status == IS_PID_AGAIN) {
+		if (player_parse(words_shift_into_bear, 0) &&
+				(local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN)) {
+			text_show(11629);
+			goto handled;
+		} else if ((local->bear_status == HAS_NEVER_BEEN_A_BEAR || local->bear_status == IS_PID_AGAIN) &&
+				global[king_status] == KING_CAPTIVE) {
 			switch (kernel.trigger) {
 			case 0:
 				player.commands_allowed = false;
+				player_walk(WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_NORTHWEST);
+				player_walk_trigger(1);
+				break;
+
+			case 1:
+				if (player_parse(words_invoke_power_of, 0))
+					sound_play(N_InvokeCrystalBall);
+
 				player.walker_visible = false;
-				kernel_seq_delete(seq[fx_bear_morph]);
-				seq[fx_bear_morph] = kernel_seq_forward(ss[fx_bear_morph], false, 8, 0, 0, 0);
+				seq[fx_bear_morph] = kernel_seq_forward(ss[fx_bear_morph], false, 8, 0, 0, 1);
 				kernel_seq_depth(seq[fx_bear_morph], 4);
-				kernel_seq_trigger(seq[fx_bear_morph], KERNEL_TRIGGER_EXPIRE, 0, 1);
+				kernel_seq_range(seq[fx_bear_morph], KERNEL_FIRST, KERNEL_LAST);
+				kernel_synch(1, seq[fx_bear_morph], 2, 0);
+				kernel_seq_trigger(seq[fx_bear_morph], KERNEL_TRIGGER_EXPIRE, 0, 2);
 				break;
-			case 1:
+
+			case 2:
+				local->temp = seq[fx_bear_morph];
+
+				if (player_parse(words_crystal_ball, 0)) {
+					aa[fx_open_door] = kernel_run_animation(kernel_name('a', -1), 0);
+					local->anim_2_running = true;
+					global[crystal_ball_dead] = true;
+				} else {
+					seq[fx_bear_morph] = kernel_seq_stamp(ss[fx_bear_morph], 0, KERNEL_LAST);
+					kernel_seq_depth(seq[fx_bear_morph], 4);
+					kernel_synch(KERNEL_SERIES, seq[fx_bear_morph], KERNEL_SERIES, local->temp);
+					player.commands_allowed = true;
+				}
+
+				if (local->bear_status == HAS_NEVER_BEEN_A_BEAR) {
+					global[player_score] += 5;
+					local->bear_status = FIRST_TIME_BEAR;
+				} else if (local->bear_status == IS_PID_AGAIN) {
+					local->bear_status = IS_A_BEAR_AGAIN;
+				}
+
 				if (local->bear_status == HAS_NEVER_BEEN_A_BEAR)
 					local->bear_status = FIRST_TIME_BEAR;
 				else
 					local->bear_status = IS_A_BEAR_AGAIN;
-				player.commands_allowed = true;
-				kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_bear_morph]);
 				break;
+			}
+		}
+
+		goto handled;
+	}
+
+	// Bear grabs king / gives soul to king
+	if ((player_parse(words_push, words_king, 0) ||
+		player_parse(words_pull, words_king, 0) ||
+		player_parse(words_take, words_king, 0) ||
+		player_parse(words_put, words_king, words_cave_floor)) &&
+		global[king_status] == KING_CAPTIVE) {
+		if (local->bear_status == HAS_NEVER_BEEN_A_BEAR) {
+			kernel_seq_delete(seq[fx_bear_morph]);
+			player.commands_allowed = false;
+			local->anim_2_running = true;
+			aa[fx_bear_morph] = kernel_run_animation(kernel_name('a', -1), 0);
+		} else {
+			switch (kernel.trigger) {
+			case 0:
+				player.commands_allowed = false;
+				player_walk(WALK_TO_KINGSICLE_X, WALK_TO_KINGSICLE_Y, FACING_NORTH);
+				player_walk_trigger(1);
+				break;
+
+			case 1:
+				player.walker_visible = false;
+				seq[fx_open_door] = kernel_seq_pingpong(ss[fx_open_door], 0, 9, 0, 0, 2);
+				kernel_seq_player(seq[fx_open_door], -1);
+				kernel_seq_trigger(seq[fx_open_door], 0, 0, 8);
+				break;
+
 			case 2:
-				// TODO: verify case 2 content
+				player.walker_visible = true;
+				kernel_synch(2, 0, 1, seq[fx_open_door]);
+				kernel_timing_trigger(12, 3);
+				sound_play(N_GrabKing);
+				break;
+
+			case 3:
+				text_show(game.difficulty == 0 ? 11612 : 11613);
+				player.commands_allowed = true;
 				break;
 			}
-			player.command_ready = false;
-			return;
 		}
+
+		goto handled;
 	}
 
-	// Bear grabs king / gives soul to king
-	if (player_parse(words_push, words_king, 0) ||
-	    player_parse(words_pull, words_king, 0) ||
-	    player_parse(words_take, words_king, 0)) {
-		if (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) {
+	if (player_parse(words_give, 82, words_king) ||
+			player_parse(words_invoke_power_of, words_crystal_ball) ||
+			player_parse(words_put, 82, words_king))  {
+		if ((player_parse(words_give, 82, words_king) || player_parse(words_put, 82, words_king)) &&
+				global[king_status] == KING_CAPTIVE) {
+			text_show(11630);
+		} else if (global[king_status] == KING_WITHOUT_SOUL) {
 			switch (kernel.trigger) {
 			case 0:
-				if (player_has(crystal_ball)) {
+				if (player_parse(words_crystal_ball, 0)) {
 					sound_play(N_InvokeCrystalBall);
 					kernel_timing_trigger(1, 3);
 				} else {
+					player.commands_allowed = false;
 					player_walk(WALK_TO_KING_SOUL_X, WALK_TO_KING_SOUL_Y, FACING_WEST);
 					player_walk_trigger(1);
 				}
 				break;
+
 			case 1:
-				if (!player_has(crystal_ball)) {
-					seq[fx_give_soul] = kernel_seq_pingpong(ss[fx_give_soul], false, 7, 0, 0, 0);
-					kernel_seq_depth(seq[fx_give_soul], 3);
-					kernel_seq_trigger(seq[fx_give_soul], KERNEL_TRIGGER_EXPIRE, 0, 2);
-					kernel_timing_trigger(60, 3);  // TODO: verify timing
+				if (!player_parse(words_crystal_ball, 0)) {
+					player.walker_visible = false;
+					seq[fx_give_soul] = kernel_seq_pingpong(ss[fx_give_soul], -1, 8, 0, 0, 2);
+					kernel_seq_player(seq[fx_give_soul], -1);
+					kernel_seq_trigger(seq[fx_give_soul], 2, 4, 2);
+					kernel_seq_trigger(seq[fx_give_soul], 0, 0, 3);
 				}
 				break;
+
 			case 2:
 				sound_play(97);
 				ss[fx_smoke] = kernel_load_series(kernel_name('a', 5), false);
-				seq[fx_smoke] = kernel_seq_forward(ss[fx_smoke], false, 7, 0, 0, 0);
+				seq[fx_smoke] = kernel_seq_forward(ss[fx_smoke], false, 8, 0, 0, 1);
 				kernel_seq_depth(seq[fx_smoke], 1);
 				kernel_seq_range(seq[fx_smoke], KERNEL_FIRST, KERNEL_LAST);
 				kernel_seq_trigger(seq[fx_smoke], KERNEL_TRIGGER_EXPIRE, 0, 4);
 				break;
+
 			case 3:
-				if (player_has(crystal_ball)) {
-					text_show(11617);
+				if (player_parse(109, 0)) {
+					text_show(11618);
 					inter_move_object(crystal_ball, NOWHERE);
 					text_show(970);
 					kernel_timing_trigger(1, 6);
@@ -648,41 +728,128 @@ static void room_116_parser() {
 					kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_give_soul]);
 				}
 				break;
+
 			case 4:
 				matte_deallocate_series(ss[fx_smoke], -1);
 				kernel_timing_trigger(1, 5);
 				break;
+
 			case 5:
 				kernel_timing_trigger(10, 6);
 				break;
+
 			case 6:
-				if (!player_has(crystal_ball)) {
+				if (!player_parse(crystal_ball, 0)) {
 					inter_move_object(soul_egg, NOWHERE);
 					text_show(11614);
 				}
+
 				global[king_status] = KING_WITH_SOUL;
 				global[player_score] += 5;
 				player.commands_allowed = true;
+				local->king_action = 0;
 				conv_run(CONVERSATION_WITH_KING);
-				conv_export_value(1);
+				conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
 				break;
 			}
-			player.command_ready = false;
-			return;
 		}
+
+		goto handled;
+	}
+
+	if (player_parse(words_invoke, words_signet_ring, 0)) {
+		if (global[king_status] == KING_WITH_SOUL && !global[king_is_in_stairwell]) {
+			conv_run(13);
+			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
+			conv_export_value(1);
+			local->invoked_ring = true;
+		} else {
+			new_room = 110;
+		}
+
+		goto handled;
 	}
 
-	// TODO: look/look_at specific noun responses
+	if (player_parse(words_look, 0) || player_parse(words_look_at, 0)) {
+		if (player_parse(words_cave_floor, 0)) {
+			text_show(11602);
+			goto handled;
+		} else if (player_parse(words_cave_wall, 0)) {
+			text_show(11603);
+			goto handled;
+		} else if (player_parse(229, 0)) {
+			text_show(global[king_status] == KING_CAPTIVE ? 11604 : 11609);
+			goto handled;
+		} else if (player_parse(words_door_to_stairwell, 0)) {
+			text_show(11605);
+			goto handled;
+		} else if (player_parse(words_door_to_darkness, 0)) {
+			text_show(11606);
+			goto handled;
+		} else if (player_parse(words_king, 0) && global[king_status] == KING_CAPTIVE) {
+			text_show(11607);
+			goto handled;
+		} else if (player_parse(words_king, 0) && global[king_status] == KING_OFF_ICE) {
+			text_show(11610);
+			goto handled;
+		} else if (player_parse(words_king, 0) && conv_control.running != 13) {
+			text_show(11611);
+			goto handled;
+		}
+	}
 
-	// Bear form verb filter
-	if (local->bear_status == FIRST_TIME_BEAR || local->bear_status == IS_A_BEAR_AGAIN) {
+	if (player_parse(words_gaze_into, words_crystal_ball, 0) && global[king_status] == KING_CAPTIVE) {
+		text_show(11615);
+		goto handled;
+	}
+	if (player_parse(words_gaze_into, words_crystal_ball, 0) && global[king_status] == KING_WITHOUT_SOUL) {
+		text_show(11616);
+		goto handled;
+	}
+
+	if (player_parse(words_close, words_door_to_stairwell, 0)) {
+		text_show(42);
+		goto handled;
+	}
+
+	if ((local->bear_status != FIRST_TIME_BEAR || local->bear_status != IS_A_BEAR_AGAIN) &&
+			!player_parse(words_look, 0) &&
+			!player_parse(words_take, 0) &&
+			!player_parse(words_push, 0) &&
+			!player_parse(words_open, 0) &&
+			!player_parse(words_put, 0) &&
+			!player_parse(words_talk_to, 0) &&
+			!player_parse(words_give, 0) &&
+			!player_parse(words_pull, 0) &&
+			!player_parse(words_close, 0) &&
+			!player_parse(words_throw, 0) &&
+			!player_parse(words_swim_to, 0) &&
+			!player_parse(words_swim_towards, 0)) {
 		text_show(32);
-		player.command_ready = false;
-		return;
+		goto handled;
 	}
 
-	// TODO: words_heal + words_king response
-	// TODO: words_sword / words_attack + words_king response
+	if (player_parse(words_heal, words_king) && global[king_status] != KING_WITH_SOUL) {
+		text_show(11622);
+		goto handled;
+	}
+
+	if (player_parse(words_sword, words_attack, words_king, 0) ||
+			player_parse(words_sword, words_carve_up, words_king, 0) ||
+			player_parse(words_sword, words_thrust, words_king, 0)) {
+		if (global[king_status] == KING_CAPTIVE) {
+			text_show(11621);
+			goto handled;
+		} else {
+			goto done;
+		}
+	}
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_116_synchronize(Common::Serializer &s) {


Commit: a3ee41524dd0d1eba83287f557f798c21f6c445f
    https://github.com/scummvm/scummvm/commit/a3ee41524dd0d1eba83287f557f798c21f6c445f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-11T14:26:58+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 118

Changed paths:
    engines/mads/madsv2/dragonsphere/rooms/room116.cpp
    engines/mads/madsv2/dragonsphere/rooms/room118.cpp


diff --git a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
index 89159454c22..2be2d9184b7 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
@@ -845,6 +845,8 @@ static void room_116_parser() {
 		}
 	}
 
+	goto done;
+
 handled:
 	player.command_ready = false;
 
@@ -853,7 +855,23 @@ done:
 }
 
 void room_116_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.temp);
+	s.syncAsSint16LE(scratch.kingsicle_id);
+	s.syncAsSint16LE(scratch.bear_status);
+	s.syncAsSint16LE(scratch.animation_running);
+	s.syncAsSint16LE(scratch.current_frame);
+	s.syncAsSint16LE(scratch.just_melted);
+	s.syncAsSint16LE(scratch.king_frame);
+	s.syncAsSint16LE(scratch.king_action);
+	s.syncAsSint16LE(scratch.king_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.lift_frame);
+	s.syncAsSint16LE(scratch.lift_action);
+	s.syncAsSint16LE(scratch.anim_2_running);
+	s.syncAsSint16LE(scratch.invoked_ring);
 }
 
 void room_116_preload() {
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room118.cpp b/engines/mads/madsv2/dragonsphere/rooms/room118.cpp
index 8147a4720ab..5b204deb6c3 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room118.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room118.cpp
@@ -22,6 +22,7 @@
 #include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
 #include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
 #include "mads/madsv2/core/kernel.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
@@ -39,6 +40,11 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[4];     /* Animation handles     */
+
+	int16 guard_id;         /* hotspot id for guard */
 };
 
 #define local (&scratch)
@@ -46,26 +52,130 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
 
-void room_118_init() {
+/* ========================= Sprites ========================= */
 
-}
+#define fx_guard             1     /* rm118e */
 
-void room_118_daemon() {
+/* walk points */
+#define START_X_ROOM_110     124
+#define START_Y_ROOM_110     100
+#define START_X_ROOM_106     84
+#define START_Y_ROOM_106     152
 
-}
+#define WALK_TO_GUARD_X      124
+#define WALK_TO_GUARD_Y      106
+
+/* Animations */
+/*   rm118a.aa  - guard walking */
+
+/* random numbers */
+#define RANDOM_LOW_NUMBER    0
+#define RANDOM_HIGH_NUMBER   189
+
+
+static void room_118_init() {
+	int random;
 
-void room_118_pre_parser() {
+	// Pick a random frame to start the guard animation
+	random = imath_random(RANDOM_LOW_NUMBER, RANDOM_HIGH_NUMBER);
+	kernel_anim[0].repeat = true;
+	aa[0] = kernel_run_animation(kernel_name('a', -1), 0);
+	kernel_reset_animation(aa[0], random);
+	local->guard_id = kernel_add_dynamic(words_guard, words_walk_to, SYNTAX_MASC_NOT_PROPER,
+		KERNEL_NONE, 0, 0, 0, 0);
+	kernel_dynamic_walk(local->guard_id, WALK_TO_GUARD_X, WALK_TO_GUARD_Y, FACING_NORTH);
+	kernel_dynamic_anim(local->guard_id, aa[0], 0);
+	kernel_dynamic_anim(local->guard_id, aa[0], 1);
+	kernel_dynamic_anim(local->guard_id, aa[0], 2);
+	kernel_dynamic_anim(local->guard_id, aa[0], 3);
 
+	if (previous_room == 110) {
+		// Player comes from Way Station
+		player.x = START_X_ROOM_110;
+		player.y = START_Y_ROOM_110;
+		player.facing = FACING_SOUTH;
+
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		// Player comes from Throne room rm106
+		player.x = START_X_ROOM_106;
+		player.y = START_Y_ROOM_106;
+		player.facing = FACING_NORTHEAST;
+	}
+
+	section_1_music();
+}
+
+static void room_118_daemon() {
+	// No implementation
 }
 
-void room_118_parser() {
+static void room_118_pre_parser() {
+	// No implementation
+}
 
+static void room_118_parser() {
+	if (player.look_around) {
+		text_show(11801);
+		goto handled;
+	}
+
+	if (player_parse(37, 157, 0)) {
+		new_room = 110;
+		goto handled;
+	}
+
+	if (player_parse(37, 164, 0)) {
+		new_room = 106;
+		goto handled;
+	}
+
+	if (player_parse(3, 0) || player_parse(30, 0)) {
+		if (player_parse(171, 0)) { text_show(11802); goto handled; }
+		if (player_parse(157, 0)) { text_show(11803); goto handled; }
+		if (player_parse(161, 0)) { text_show(11804); goto handled; }
+		if (player_parse(160, 0)) { text_show(11806); goto handled; }
+		if (player_parse(159, 0)) { text_show(11807); goto handled; }
+		if (player_parse(24, 0))  { text_show(11809); goto handled; }
+		if (player_parse(164, 0)) { text_show(11810); goto handled; }
+		if (player_parse(180, 0)) { text_show(11811); goto handled; }
+		if (player_parse(272, 0)) { text_show(11812); goto handled; }
+	}
+
+	if (player_parse(8, 272, 0)) {
+		text_show(11813);
+		goto handled;
+	}
+
+	if (player_parse(6, 0)) {
+		if (player_parse(160, 0) || player_parse(159, 0)) {
+			text_show(11808);
+			goto handled;
+		}
+	}
+
+	if (player_parse(6, 0) || player_parse(10, 0) || player_parse(162, 0)) {
+		if (player_parse(161, 0)) {
+			text_show(11805);
+			goto handled;
+		}
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_118_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.guard_id);
 }
 
 void room_118_preload() {
@@ -76,6 +186,9 @@ void room_118_preload() {
 
 	section_1_walker();
 	section_1_interface();
+
+	vocab_make_active(words_guard);
+	vocab_make_active(words_walk_to);
 }
 
 } // namespace Rooms


Commit: bf65d18086e1215c045397f2e1cc9554d57ec3b8
    https://github.com/scummvm/scummvm/commit/bf65d18086e1215c045397f2e1cc9554d57ec3b8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-11T14:29:30+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 119

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/conv.h
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room116.cpp
    engines/mads/madsv2/dragonsphere/rooms/room119.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/conv.h b/engines/mads/madsv2/dragonsphere/mads/conv.h
index 3034744ec27..9fd0350de36 100644
--- a/engines/mads/madsv2/dragonsphere/mads/conv.h
+++ b/engines/mads/madsv2/dragonsphere/mads/conv.h
@@ -140,14 +140,18 @@ enum {
 };
 
 enum {
-	conv034_five_b_b = 4,
-	conv034_seven_only = 7,
-	conv034_eight_b_b = 9,
-	conv034_eight_only = 10,
-	conv034_nine_only = 11,
-	conv034_final_only = 15,
-	conv034_exit_a_a = 16,
-	conv034_exit_b_b = 17
+	conv034_five_b_b    =  4,
+	conv034_seven_only  =  7,
+	conv034_eight_b_b   =  9,
+	conv034_eight_only  = 10,
+	conv034_nine_only   = 11,
+	conv034_final_only  = 15,
+	conv034_exit_a_a    = 16,
+	conv034_exit_b_b    = 17
+};
+
+enum {
+	conv035_exit_b_b    =  3
 };
 
 } // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index 531a7ef617c..a18cd0aea28 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -37,6 +37,7 @@ enum {
 	N_SealMus            =  35,
 	N_UnderGroundMus     =  36,
 	N_WayStationMus      =  37,
+	N_Angels             =  42,
 	N_QueenMother        =  45,
 	N_TurnDiaryPage      =  65,
 	N_WallGrinds         =  67,
@@ -46,6 +47,8 @@ enum {
 	N_DogWhimper         =  79,
 	N_BeastSnd           =  80,
 	N_GrabKing           =  82,
+	N_MagicDoorOpens     =  88,
+	N_MagicDoorUnlocked  =  89,
 	N_JumpDownWell       =  93,
 	N_BooksRumble        =  94,
 	N_McMornTipsTable    = 100
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index 85806952da0..3981b7aa926 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -63,12 +63,15 @@ enum {
 	words_bone                 =  62,
 	words_doll                 =  66,
 	words_heal                 =  68,
+	words_key_crown            =  76,
+	words_wear                 =  77,
 	words_dates                =  78,
 	words_statue               =  79,
 	words_bottle_of_flies      =  80,
 	N_WaterBubbles             =  86,
 	words_thrust               =  87,
 	words_torch                =  93,
+	words_pour_contents_of     =  99,
 	words_rope                 = 101,
 	words_tie                  = 102,
 	words_crystal_ball         = 109,
@@ -89,6 +92,8 @@ enum {
 	words_passageway_to_east   = 151,
 	words_cave_floor           = 152,
 	words_castle               = 156,
+	words_door                 = 166,
+	words_wall_switch          = 167,
 	words_stairs               = 168,
 	words_walk_down            = 169,
 	words_edge_of_abyss        = 170,
@@ -97,6 +102,7 @@ enum {
 	words_brazier              = 175,
 	words_door_to_throne_room  = 176,
 	words_dining_table         = 178,
+	words_activate             = 179,
 	words_dungeon_floor        = 182,
 	words_bedding              = 185,
 	words_floor_grate          = 186,
@@ -128,7 +134,7 @@ enum {
 	words_bucket               = 225,
 	words_jump_down            = 226,
 	words_door_to_darkness     = 228,
-	words_door_to_stairwell    = 230,
+	words_door_to_north        = 230,
 	words_painting             = 231,
 	words_document             = 232,
 	words_ink_bottle           = 233,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
index 2be2d9184b7..3cdddb2e487 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room116.cpp
@@ -488,9 +488,9 @@ static void room_116_parser() {
 		goto handled;
 	}
 
-	if (player_parse(words_walk_through, words_door_to_stairwell, 0) ||
-	    player_parse(words_open, words_door_to_stairwell, 0) ||
-	    player_parse(words_pull, words_door_to_stairwell, 0)) {
+	if (player_parse(words_walk_through, words_door_to_north, 0) ||
+	    player_parse(words_open, words_door_to_north, 0) ||
+	    player_parse(words_pull, words_door_to_north, 0)) {
 		switch (kernel.trigger) {
 		case 0:
 			player.commands_allowed = false;
@@ -560,7 +560,7 @@ static void room_116_parser() {
 			player_parse(words_open, 228, 0) ||
 			player_parse(words_pull, 228, 0)) {
 		if (global[king_status] == KING_WITH_SOUL && !global[king_is_in_stairwell]) {
-			conv_run(13);
+			conv_run(CONVERSATION_WITH_KING);
 			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
 			conv_export_value(1);
 		} else {
@@ -759,7 +759,7 @@ static void room_116_parser() {
 
 	if (player_parse(words_invoke, words_signet_ring, 0)) {
 		if (global[king_status] == KING_WITH_SOUL && !global[king_is_in_stairwell]) {
-			conv_run(13);
+			conv_run(CONVERSATION_WITH_KING);
 			conv_export_value(global[king_status] == KING_WITH_SOUL ? 1 : 0);
 			conv_export_value(1);
 			local->invoked_ring = true;
@@ -780,7 +780,7 @@ static void room_116_parser() {
 		} else if (player_parse(229, 0)) {
 			text_show(global[king_status] == KING_CAPTIVE ? 11604 : 11609);
 			goto handled;
-		} else if (player_parse(words_door_to_stairwell, 0)) {
+		} else if (player_parse(words_door_to_north, 0)) {
 			text_show(11605);
 			goto handled;
 		} else if (player_parse(words_door_to_darkness, 0)) {
@@ -807,7 +807,7 @@ static void room_116_parser() {
 		goto handled;
 	}
 
-	if (player_parse(words_close, words_door_to_stairwell, 0)) {
+	if (player_parse(words_close, words_door_to_north, 0)) {
 		text_show(42);
 		goto handled;
 	}
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room119.cpp b/engines/mads/madsv2/dragonsphere/rooms/room119.cpp
index 7a173f21521..5ac9bc5d6fa 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room119.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room119.cpp
@@ -22,6 +22,7 @@
 #include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
 #include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
 #include "mads/madsv2/core/kernel.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
@@ -39,6 +40,21 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[4];     /* Animation handles     */
+
+	int16 pid_frame;       /* animation frame being held for pid stuff */
+	int16 pid_action;      /* Type of action to run for pid animation */
+	int16 pid_talk_count;  /* counter for pid talking */
+	int16 anim_0_running;
+
+	int16 king_frame;       /* animation frame being held for king stuff */
+	int16 king_action;      /* Type of action to run for king animation */
+	int16 king_talk_count;  /* counter for king talking */
+	int16 anim_1_running;
+
+	int16 invoked_ring;
 };
 
 #define local (&scratch)
@@ -46,26 +62,601 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
+
+
+/* ========================= Sprites ========================= */
+
+#define fx_torch_fire          0       /* rm109x1  */
+#define fx_door_room           1       /* rm109y0  */
+#define fx_door_door           2       /* rm109y1  */
+#define fx_button              3       /* rm109x0  */
+
+
+/* ======================== Triggers ========================= */
+
+#define ROOM_119_BUTTON_ACTION 60
+#define ROOM_119_STONE_DOOR    65
+#define ROOM_119_WOOD_DOOR     70
+#define ROOM_119_TEXT          75
+#define ROOM_119_LEAVE_ROOM    79
+
+
+#define PID_NOTHING            0
+#define PID_UP_EXIT            1
+#define PID_DOWN_EXIT          2
+#define PID_BUTTON             3
+#define PID_CROWN              4
+#define PID_CONV               5
+
+#define KING_FACE_UP_STAIRS    0
+#define KING_OTHER             1
+
+#define CONVERSATION_WITH_KING 35
+
 
 void room_119_init() {
+	local->invoked_ring = false;
+
+	if (kernel.teleported_in) {
+		inter_give_to_player(key_crown);
+		inter_give_to_player(crystal_ball);
+		inter_give_to_player(shifter_ring);
+		inter_give_to_player(magic_belt);
+		inter_give_to_player(sword);
+		inter_give_to_player(amulet);
+		global[player_persona] = PLAYER_IS_PID;
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+	}
+
+	conv_get(CONVERSATION_WITH_KING);
+
+	/* Load sprite series */
+	ss[fx_torch_fire] = kernel_load_series(kernel_name('x', 1), false);
+	ss[fx_button] = kernel_load_series(kernel_name('x', 0), false);
+	ss[fx_door_room] = kernel_load_series(kernel_name('y', 0), false);
+	ss[fx_door_door] = kernel_load_series(kernel_name('y', 1), false);
+
+	/* Start continuous sequences */
+	seq[fx_torch_fire] = kernel_seq_forward(ss[fx_torch_fire], false, 7, 0, 0, 0);
+
+	aa[0] = kernel_run_animation(kernel_name('p', 1), 0);
+	local->anim_0_running = true;
+	local->pid_action = PID_NOTHING;
+
+	if (previous_room == KERNEL_RESTORING_GAME || previous_room == 104) {
+		kernel_reset_animation(aa[0], 47);
+	} else {
+		player.commands_allowed = false;
+	}
+
+	if (global[king_status] == KING_WITH_SOUL) {
+		global[king_is_in_stairwell] = true;
+		aa[1] = kernel_run_animation(kernel_name('k', 1), 0);
+		local->anim_1_running = true;
+		local->king_action = KING_FACE_UP_STAIRS;
+		if (previous_room == KERNEL_RESTORING_GAME || previous_room == 104) {
+			kernel_reset_animation(aa[1], 8);
+		} else {
+			player.commands_allowed = false;
+		}
+	} else {
+		kernel_flip_hotspot(words_king, false);
+	}
+
+	if (global[books_status] == BOOKS_PULLED ||
+		global[books_status] == BOOKS_PULLED2) {
+		seq[fx_button] = kernel_seq_stamp(ss[fx_button], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_button], 15);
+	}
+
+	if (global[wooden_door_open]) {
+		seq[fx_door_door] = kernel_seq_stamp(ss[fx_door_door], false, 6);
+		kernel_seq_depth(seq[fx_door_door], 14);
+	}
+
+	section_1_music();
+}
+
+
+static void handle_animation_pid() {
+	int pid_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[0]].frame;
+		pid_reset_frame = -1;
+
+		switch (local->pid_frame) {
+		case 109:
+			/* just pushed button */
+			kernel_timing_trigger(1, ROOM_119_BUTTON_ACTION);
+			break;
+
+		case 131:
+			/* just put on crown */
+			if (global[books_status] == BOOKS_PULLED ||
+					global[books_status] == BOOKS_PULLED2) {
+				sound_play(N_MagicDoorOpens);
+				sound_play(N_Angels);
+				kernel_timing_trigger(1, ROOM_119_WOOD_DOOR);
+			}
+			break;
+
+		case 103:  /* end of climb down from top stairs */
+		case 170:  /* end of climb down from bottom     */
+			new_room = 116;
+			break;
+
+		case 181:
+			/* end of climb up into 104 */
+			global[no_load_walker] = true;
+			new_room = 104;
+			break;
+
+		case 86:
+			/* end of climb down stairs and leave room */
+			local->king_action = KING_OTHER;
+			break;
+
+		case 97:
+			/* almost end of climb down stairs and leave room */
+			if (global[king_status] == KING_WITH_SOUL) {
+				local->pid_action = PID_CONV;
+				conv_run(CONVERSATION_WITH_KING);
+				if (global[king_status] == KING_WITH_SOUL) {
+					conv_export_value(1);
+				} else {
+					conv_export_value(0);
+				}
+				conv_export_value(1);
+			}
+			break;
+
+		case 98:
+			/* almost end of climb down stairs and leave room */
+			if (global[king_status] == KING_WITH_SOUL) {
+				if (local->pid_action == PID_CONV) {
+					pid_reset_frame = 97;
+				}
+			}
+			break;
+
+		case 113: /* almost end of push button */
+		case 150: /* almost end of wear crown  */
+		case 46:  /* almost end of freeze      */
+			player.commands_allowed = true;
+			break;
+
+		case 114: /* end of push button */
+		case 151: /* end of wear crown  */
+		case 47:  /* end of freeze      */
+			if (local->pid_frame == 151) {
+				if (global[books_status] == BOOKS_PULLED ||
+						global[books_status] == BOOKS_PULLED2) {
+					local->pid_action = PID_UP_EXIT;
+					/* climb up stairs to 104 */
+				} else {
+					kernel_timing_trigger(2, ROOM_119_TEXT);
+				}
+
+			} else if (local->pid_frame == 114) {
+				kernel_timing_trigger(2, ROOM_119_TEXT + 1);
+			}
+
+			switch (local->pid_action) {
+
+			case PID_NOTHING:
+				pid_reset_frame = 46; /* freeze */
+				break;
+
+			case PID_UP_EXIT:
+				player.commands_allowed = false;
+				pid_reset_frame = 172;  /* climb up stairs to 104 */
+				break;
+
+			case PID_DOWN_EXIT:
+				player.commands_allowed = false;
+				pid_reset_frame = 47;  /* climb down stairs to 116 */
+				break;
+
+			case PID_BUTTON:
+				player.commands_allowed = false;
+				pid_reset_frame = 103;  /* push button */
+				local->pid_action = PID_NOTHING;
+				break;
+
+			case PID_CROWN:
+				player.commands_allowed = false;
+				pid_reset_frame = 114;  /* wear crown */
+				local->pid_action = PID_NOTHING;
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_king() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[1]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame) {
 
+		case 8:
+			/* king looking up staircase at Pid */
+			if (local->king_action == KING_FACE_UP_STAIRS) {
+				king_reset_frame = 7; /* freeze looking up stairs */
+			}
+			break;
+
+		case 15:
+			/* repeat end of king anim */
+			king_reset_frame = 14;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
 }
 
-void room_119_daemon() {
+static void room_119_daemon() {
+	int temp;
+
+	if (local->anim_0_running) {
+		handle_animation_pid();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_king();
+	}
+
+	if ((global[books_status] == BOOKS_PULLED) ||
+		(global[books_status] == BOOKS_PULLED2)) {
+
+		switch (kernel.trigger) {
+
+		case ROOM_119_WOOD_DOOR:
+			player.commands_allowed = false;
+			seq[fx_door_room] = kernel_seq_forward(ss[fx_door_room], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door_room], 14);
+			kernel_seq_range(seq[fx_door_room], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_door_room],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_WOOD_DOOR + 1);
+			break;
+
+		case ROOM_119_WOOD_DOOR + 1:
+			seq[fx_door_room] = kernel_seq_stamp(ss[fx_door_room], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_door_room], 14);
+			player.commands_allowed = false;
+			break;
+		}
+
+	} else if (global[wooden_door_open]) {
+		switch (kernel.trigger) {
+		case ROOM_119_WOOD_DOOR:
+			player.commands_allowed = false;
+			kernel_seq_delete(seq[fx_door_door]);
+			seq[fx_door_door] = kernel_seq_backward(ss[fx_door_door], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door_door], 14);
+			kernel_seq_range(seq[fx_door_door], 1, 6);
+			kernel_seq_trigger(seq[fx_door_door],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_WOOD_DOOR + 1);
+			break;
+
+		case ROOM_119_WOOD_DOOR + 1:
+			global[wooden_door_open] = false;
+			player.commands_allowed = true;
+			break;
+		}
+
+	} else {
+		switch (kernel.trigger) {
+		case ROOM_119_WOOD_DOOR:
+			player.commands_allowed = false;
+			seq[fx_door_door] = kernel_seq_forward(ss[fx_door_door], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door_door], 14);
+			kernel_seq_range(seq[fx_door_door], 1, 6);
+			kernel_seq_trigger(seq[fx_door_door],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_WOOD_DOOR + 1);
+			break;
+
+		case ROOM_119_WOOD_DOOR + 1:
+			seq[fx_door_door] = kernel_seq_stamp(ss[fx_door_door], false, 6);
+			kernel_seq_depth(seq[fx_door_door], 14);
+			global[wooden_door_open] = true;
+			player.commands_allowed = true;
+			break;
+		}
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_119_STONE_DOOR:
+		sound_play(N_MagicDoorOpens);
+		temp = seq[fx_door_door];
+		kernel_seq_delete(seq[fx_door_door]);
+		player.commands_allowed = false;
+		seq[fx_door_door] = kernel_seq_forward(ss[fx_door_door], false, 6, 0, 0, 1);
+		kernel_seq_depth(seq[fx_door_door], 14);
+		kernel_seq_range(seq[fx_door_door], 7, KERNEL_LAST);
+		kernel_synch(KERNEL_SERIES, seq[fx_door_door], KERNEL_SERIES, temp);
+		kernel_seq_trigger(seq[fx_door_door],
+			KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_STONE_DOOR + 1);
+		break;
 
+	case ROOM_119_STONE_DOOR + 1:
+		seq[fx_door_door] = kernel_seq_stamp(ss[fx_door_door], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_door_door], 14);
+		player.commands_allowed = false;
+		kernel_timing_trigger(6, ROOM_119_STONE_DOOR + 2);
+		break;
+
+	case ROOM_119_STONE_DOOR + 2:
+		global[no_load_walker] = true;
+		new_room = 104;
+		break;
+	}
+
+	if (global[books_status] == BOOKS_PRESENT ||
+			global[books_status] == BOOKS_PRESENT2 ||
+			global[books_status] == BOOKS_NOT_PRESENT) {
+		switch (kernel.trigger) {
+		case ROOM_119_BUTTON_ACTION:
+			sound_play(N_MagicDoorUnlocked);
+			sound_play(N_WallGrinds);
+			seq[fx_button] = kernel_seq_forward(ss[fx_button], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_button], 14);
+			kernel_seq_range(seq[fx_button], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_button],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_BUTTON_ACTION + 1);
+			break;
+
+		case ROOM_119_BUTTON_ACTION + 1:
+			seq[fx_button] = kernel_seq_stamp(ss[fx_button], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_button], 15);
+			global[books_status] = BOOKS_PULLED2;
+			if (global[wooden_door_open]) {
+				kernel_timing_trigger(1, ROOM_119_STONE_DOOR);
+			}
+			break;
+		}
+
+	} else {
+		switch (kernel.trigger) {
+		case ROOM_119_BUTTON_ACTION:
+			sound_play(N_MagicDoorUnlocked);
+			sound_play(N_WallGrinds);
+			kernel_seq_delete(seq[fx_button]);
+			seq[fx_button] = kernel_seq_backward(ss[fx_button], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_button], 14);
+			kernel_seq_range(seq[fx_button], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_button],
+				KERNEL_TRIGGER_EXPIRE, 0, ROOM_119_BUTTON_ACTION + 1);
+			break;
+
+		case ROOM_119_BUTTON_ACTION + 1:
+			seq[fx_button] = kernel_seq_stamp(ss[fx_button], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_button], 15);
+			global[books_status] = BOOKS_PRESENT2;
+			break;
+		}
+	}
+
+	if (kernel.trigger == ROOM_119_TEXT) {
+		text_show(11907);
+	}
+
+	if (kernel.trigger == ROOM_119_TEXT + 1) {
+		text_show(11903);
+	}
+}
+
+static void process_conversation_king() {
+	int you_trig_flag = false;
+	int me_trig_flag = false;
+
+	if (player_verb == conv035_exit_b_b) {
+		me_trig_flag = true;
+		you_trig_flag = true;
+		if (!kernel.trigger) {
+			conv_me_trigger(ROOM_119_LEAVE_ROOM);
+		}
+	}
+
+	if (kernel.trigger == ROOM_119_LEAVE_ROOM) {
+		if (local->invoked_ring) {
+			new_room = 110;
+		} else {
+			local->pid_action = PID_DOWN_EXIT;
+		}
+	}
 }
 
-void room_119_pre_parser() {
+static void room_119_pre_parser() {
 
 }
 
-void room_119_parser() {
+static void room_119_parser() {
+	if (conv_control.running == CONVERSATION_WITH_KING) {
+		process_conversation_king();
+		goto handled;
+	}
+
+	if (player_said_2(invoke_power_of, crystal_ball)) {
+
+		if (!global[king_is_in_stairwell]) {
+			text_show(11913);
+
+		} else switch (kernel.trigger) {
+
+		case 0:
+			sound_play(N_InvokeCrystalBall);
+			player.commands_allowed = false;
+			seq[fx_door_room] = kernel_seq_forward(ss[fx_door_room], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_door_room], 14);
+			kernel_seq_range(seq[fx_door_room], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_door_room],
+				KERNEL_TRIGGER_EXPIRE, 0, 1);
+			break;
+
+		case 1:
+			seq[fx_door_room] = kernel_seq_stamp(ss[fx_door_room], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_door_room], 14);
+			player.commands_allowed = false;
+			text_show(11911);
+			inter_move_object(crystal_ball, NOWHERE);
+			text_show(970);
+			local->pid_action = PID_UP_EXIT;
+			break;
+		}
+		goto handled;
+	}
+
+	if (player_said_2(invoke, signet_ring)) {
+		if (global[king_status] == KING_WITH_SOUL) {
+			conv_run(CONVERSATION_WITH_KING);
+			if (global[king_status] == KING_WITH_SOUL) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+			conv_export_value(1);
+			local->invoked_ring = true;
+			goto handled;
+
+		} else {
+			new_room = 110;
+			goto handled;
+		}
+	}
+
+	if (player.look_around) {
+		text_show(11901);
+		goto handled;
+	}
+
+	if (player_said_2(walk_down, stairs)) {
+		local->pid_action = PID_DOWN_EXIT;
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(wall_switch)) {
+			text_show(11902);
+			goto handled;
+		}
+
+		if (player_said_1(stairs)) {
+			text_show(11906);
+			goto handled;
+		}
+
+		if (player_said_1(door)) {
+			text_show(11904);
+			goto handled;
+		}
+
+		if (player_said_1(king)) {
+			text_show(11912);
+			goto handled;
+		}
+	}
+
+	if (player_said_1(wall_switch) && (player_said_1(push) || player_said_1(activate))) {
+		local->pid_action = PID_BUTTON;
+
+		if (!(global[player_score_flags] & SCORE_PUSH_BUTTON_119)) {
+			global[player_score_flags] = global[player_score_flags] | SCORE_PUSH_BUTTON_119;
+			global[player_score] += 1;
+		}
+
+		goto handled;
+	}
+
+	if ((player_said_1(push) || player_said_1(pull) ||
+		player_said_1(open) || player_said_1(walk_through)) &&
+		player_said_1(door)) {
+		text_show(11905);
+		goto handled;
+	}
+
+	if (player_said_2(wear, key_crown)) {
+		if (global[king_status] == KING_WITH_SOUL) {
+			local->pid_action = PID_CROWN;
+
+			if (!(global[player_score_flags] & SCORE_WEAR_CROWN_119)) {
+				global[player_score_flags] = global[player_score_flags] | SCORE_WEAR_CROWN_119;
+				global[player_score] += 3;
+			}
+
+		} else {
+			text_show(11908);
+		}
+		goto handled;
+	}
+
+	if (player_said_2(talk_to, king)) {
+		conv_run(CONVERSATION_WITH_KING);
+		if (global[king_status] == KING_WITH_SOUL) {
+			conv_export_value(1);
+		} else {
+			conv_export_value(0);
+		}
+		conv_export_value(0);
+		goto handled;
+	}
+
+	if (player_said_2(close, door_to_north)) {
+		text_show(42);
+		goto handled;
+	}
+
+	if (player_said_2(gaze_into, crystal_ball)) {
+		text_show(11910);
+		goto handled;
+	}
+
+	if (player_said_2(pour_contents_of, door)) {
+		text_show(11914);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
 
+done:
+	;
 }
 
 void room_119_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.pid_frame);
+	s.syncAsSint16LE(scratch.pid_action);
+	s.syncAsSint16LE(scratch.pid_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.king_frame);
+	s.syncAsSint16LE(scratch.king_action);
+	s.syncAsSint16LE(scratch.king_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.invoked_ring);
 }
 
 void room_119_preload() {




More information about the Scummvm-git-logs mailing list