[Scummvm-git-logs] scummvm master -> 721c9a846a153790ad1b7201f02615fbf077c446

dreammaster noreply at scummvm.org
Wed Mar 8 06:40:23 UTC 2023


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

Summary:
119cda49fa MM: MM1: Simplify go back message in Characters view
2cc9f8578e MM: MM1: In progress adding Create Characters view
b52ddaced0 MM: MM1: Allow mouse clicks on class/race/etc. options in Create Characters
721c9a846a MM: MM1: Add a _priorView field to FocusMessage


Commit: 119cda49fa4848667db534df79ab507aeafe922c
    https://github.com/scummvm/scummvm/commit/119cda49fa4848667db534df79ab507aeafe922c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2023-03-07T22:31:57-08:00

Commit Message:
MM: MM1: Simplify go back message in Characters view

Changed paths:
    engines/mm/mm1/views_enh/characters.cpp


diff --git a/engines/mm/mm1/views_enh/characters.cpp b/engines/mm/mm1/views_enh/characters.cpp
index 9e57f907192..7b80659a819 100644
--- a/engines/mm/mm1/views_enh/characters.cpp
+++ b/engines/mm/mm1/views_enh/characters.cpp
@@ -30,7 +30,7 @@ namespace ViewsEnh {
 Characters::Characters() : ScrollView("Characters") {
 	_bounds.setBorderSize(10);
 	_escSprite.load("esc.icn");
-	addButton(&_escSprite, Common::Point(105, 172), 0, KEYBIND_ESCAPE, true);
+	addButton(&_escSprite, Common::Point(120, 172), 0, KEYBIND_ESCAPE, true);
 }
 
 void Characters::draw() {
@@ -74,7 +74,7 @@ void Characters::draw() {
 		writeString(0, 152, STRING["enhdialogs.characters.left_click"], ALIGN_MIDDLE);
 	}
 
-	writeString(120, 174, STRING["dialogs.misc.go_back"]);
+	writeString(135, 174, STRING["enhdialogs.misc.go_back"]);
 }
 
 bool Characters::msgMouseDown(const MouseDownMessage &msg) {


Commit: 2cc9f8578e8aff6073757fb374605ed407175e35
    https://github.com/scummvm/scummvm/commit/2cc9f8578e8aff6073757fb374605ed407175e35
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2023-03-07T22:31:58-08:00

Commit Message:
MM: MM1: In progress adding Create Characters view

Changed paths:
  A engines/mm/mm1/views_enh/create_characters.cpp
  A engines/mm/mm1/views_enh/create_characters.h
    devtools/create_mm/files/mm1/strings_en.yml
    engines/mm/mm1/events.cpp
    engines/mm/mm1/views_enh/dialogs.h
    engines/mm/module.mk


diff --git a/devtools/create_mm/files/mm1/strings_en.yml b/devtools/create_mm/files/mm1/strings_en.yml
index 4e18c7b6fa3..02a88368e62 100644
--- a/devtools/create_mm/files/mm1/strings_en.yml
+++ b/devtools/create_mm/files/mm1/strings_en.yml
@@ -62,7 +62,7 @@ dialogs:
 			no_charges_left: "*** no charges left ***"
 			done: "*** done ***"
 	create_characters:
-		title: "create new characters"
+		title: "Create New Characters"
 		intellect: "intellect...="
 		might: "might.......="
 		personality: "personality.="
@@ -74,11 +74,11 @@ dialogs:
 		race: "race..="
 		alignment: "algn..="
 		sex: "sex...="
-		select_class: "select class"
-		select_race: "select a race"
-		select_alignment: "select alignment"
-		select_sex: "select a sex"
-		save_character: "save character"
+		select_class: "Select class"
+		select_race: "Select a race"
+		select_alignment: "Select alignment"
+		select_sex: "Select a sex"
+		save_character: "Save character"
 		reroll: "'ent' to re-roll"
 		start_over: "'esc' start over"
 		name: "name:"
@@ -488,6 +488,23 @@ enhdialogs:
 		title: "Select target"
 	characters:
 		left_click: "Left click portraits to view"
+	create_characters:
+		intellect: "Intellect ="
+		might: "Might ="
+		personality: "Personality ="
+		endurance: "Endurance ="
+		speed: "Speed ="
+		accuracy: "Accuracy ="
+		luck:  "Luck ="
+		roll: "\x01""37Roll"
+		class: "Class = "
+		race: "Race = "
+		alignment: "Align = "
+		sex: "Sex = "
+		name: "Name = "
+		select_portrait: "Select a portrait"
+		select: "\x01""37Select"
+		enter_name: "Enter name:"
 	inn:
 		left_click: "Left click potraits to add/remove"
 		right_click: "Right click to view"
diff --git a/engines/mm/mm1/events.cpp b/engines/mm/mm1/events.cpp
index 7939d2da669..3d85c2f119c 100644
--- a/engines/mm/mm1/events.cpp
+++ b/engines/mm/mm1/events.cpp
@@ -52,7 +52,7 @@ void Events::runGame() {
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot == -1 ||
 			g_engine->loadGameState(saveSlot).getCode() != Common::kNoError) {
-		addView("Title");
+		addView("CreateCharacters");// "Title");
 	}
 
 	Common::Event e;
diff --git a/engines/mm/mm1/views_enh/create_characters.cpp b/engines/mm/mm1/views_enh/create_characters.cpp
new file mode 100644
index 00000000000..93640d6d905
--- /dev/null
+++ b/engines/mm/mm1/views_enh/create_characters.cpp
@@ -0,0 +1,562 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "mm/mm1/views_enh/create_characters.h"
+#include "mm/mm1/globals.h"
+#include "mm/mm1/mm1.h"
+
+namespace MM {
+namespace MM1 {
+namespace ViewsEnh {
+
+#define RIGHT_X 220
+
+void CreateCharacters::NewCharacter::clear() {
+	Common::fill(_attribs1, _attribs1 + 7, 0);
+	Common::fill(_attribs2, _attribs2 + 7, 0);
+	_class = KNIGHT;
+	_race = HUMAN;
+	_alignment = GOOD;
+	_sex = MALE;
+	_name = "";
+
+	Common::fill(_classesAllowed, _classesAllowed + 7, 0);
+}
+
+void CreateCharacters::NewCharacter::reroll() {
+	clear();
+
+	// Generate attributes
+	for (int attrib = INTELLECT; attrib <= LUCK; ++attrib)
+		_attribs1[attrib] = g_engine->getRandomNumber(4, 17);
+	Common::copy(_attribs1, _attribs1 + 7, _attribs2);
+
+	// Select which classes are available
+	_classesAllowed[KNIGHT] = _attribs1[MIGHT] >= 12;
+	_classesAllowed[PALADIN] = _attribs1[MIGHT] >= 12 && _attribs1[PERSONALITY] >= 12 &&
+		_attribs1[ENDURANCE] >= 12;
+	_classesAllowed[ARCHER] = _attribs1[INTELLECT] >= 12 && _attribs1[ACCURACY] >= 12;
+	_classesAllowed[CLERIC] = _attribs1[PERSONALITY] >= 12;
+	_classesAllowed[SORCERER] = _attribs1[INTELLECT] >= 12;
+	_classesAllowed[ROBBER] = true;
+}
+
+void CreateCharacters::NewCharacter::loadPortrait() {
+	Common::String cname = Common::String::format("char%02d.fac",
+		_portrait * 2 + (_sex == MALE ? 0 : 1) + 1);
+	_portraits.load(cname);
+}
+
+void CreateCharacters::NewCharacter::save() {
+	uint i = 0;
+	while (i < ROSTER_COUNT && g_globals->_roster._towns[i])
+		++i;
+
+	g_globals->_roster._towns[i] = Maps::SORPIGAL;
+	g_globals->_currCharacter = &g_globals->_roster[i];
+	Character &re = *g_globals->_currCharacter;
+	re.clear();
+
+	Common::strcpy_s(re._name, _name.c_str());
+	re._sex = _sex;
+	re._alignment = re._alignmentInitial = _alignment;
+	re._race = _race;
+	re._class = _class;
+	re._intelligence = _attribs1[INTELLECT];
+	re._might = _attribs1[MIGHT];
+	re._personality = _attribs1[PERSONALITY];
+	re._endurance = _attribs1[ENDURANCE];
+	re._speed = _attribs1[SPEED];
+	re._accuracy = _attribs1[ACCURACY];
+	re._luck = _attribs1[LUCK];
+
+	switch (_class) {
+	case KNIGHT:
+		setHP(12);
+		break;
+	case PALADIN:
+	case ARCHER:
+		setHP(10);
+		break;
+	case CLERIC:
+		setHP(8);
+		setSP(_attribs1[PERSONALITY]);
+		break;
+	case SORCERER:
+		setHP(6);
+		setSP(_attribs1[INTELLECT]);
+		break;
+	case ROBBER:
+		setHP(8);
+		re._trapCtr = 50;
+		break;
+	default:
+		break;
+	}
+
+	switch (_race) {
+	case HUMAN:
+		re._resistances._s._fear = 70;
+		re._resistances._s._psychic = 25;
+		break;
+	case ELF:
+		re._resistances._s._fear = 70;
+		break;
+	case DWARF:
+		re._resistances._s._poison = 25;
+		break;
+	case GNOME:
+		re._resistances._s._magic = 20;
+		break;
+	case HALF_ORC:
+		re._resistances._s._psychic = 50;
+		break;
+	}
+
+	re._food = 10;
+	re._backpack[0]._id = 1;
+	const int ALIGNMENT_VALS[3] = { 0, 0x10, 0x20 };
+	re._alignmentCtr = ALIGNMENT_VALS[re._alignmentInitial];
+
+	g_globals->_roster.save();
+}
+
+void CreateCharacters::NewCharacter::setHP(int hp) {
+	Character &re = *g_globals->_currCharacter;
+
+	if (_attribs1[ENDURANCE] >= 19)
+		hp += 4;
+	else if (_attribs1[ENDURANCE] >= 17)
+		hp += 3;
+	else if (_attribs1[ENDURANCE] >= 15)
+		hp += 2;
+	else if (_attribs1[ENDURANCE] >= 13)
+		hp += 1;
+	else if (_attribs1[ENDURANCE] < 5)
+		hp -= 2;
+	else if (_attribs1[ENDURANCE] < 8)
+		hp -= 1;
+
+	re._hpCurrent = re._hp = re._hpMax = hp;
+
+	int ac = 0;
+	if (_attribs1[SPEED] >= 19)
+		ac = 4;
+	else if (_attribs1[SPEED] >= 17)
+		ac = 3;
+	else if (_attribs1[SPEED] >= 15)
+		ac = 2;
+	if (_attribs1[SPEED] >= 13)
+		ac = 1;
+
+	re._ac = ac;
+}
+
+void CreateCharacters::NewCharacter::setSP(int amount) {
+	Character &re = *g_globals->_currCharacter;
+
+	int level = 0;
+	if (amount >= 19)
+		level = 4;
+	else if (amount >= 17)
+		level = 3;
+	else if (amount >= 15)
+		level = 2;
+	else if (amount >= 13)
+		level = 1;
+
+	re._sp = level + 3;
+	re._spellLevel = 1;
+}
+
+/*------------------------------------------------------------------------*/
+
+CreateCharacters::CreateCharacters() : ScrollView("CreateCharacters") {
+	_icons.load("create.icn");
+
+	addButton(&_icons, Common::Point(120, 172), 4, KEYBIND_ESCAPE, true);
+	addButton(&_icons, Common::Point(40, 120), 0, Common::KEYCODE_r);
+	addButton(&_icons, Common::Point(190, 110), 6, Common::KEYCODE_UP);
+	addButton(&_icons, Common::Point(190, 130), 8, Common::KEYCODE_DOWN);
+	addButton(&_icons, Common::Point(220, 120), 2, KEYBIND_SELECT);
+
+	setButtonEnabled(2, false);
+	setButtonEnabled(3, false);
+	setButtonEnabled(4, false);
+}
+
+void CreateCharacters::draw() {
+	ScrollView::draw();
+	printAttributes();
+
+	if ((int)_state >= SELECT_NAME) {
+		Graphics::ManagedSurface s = getSurface();
+		_newChar._portraits.draw(&s, 0, Common::Point(10, 10));
+	}
+
+	writeString(135, 174, STRING["enhdialogs.misc.go_back"]);
+	writeString(70, 125, STRING["enhdialogs.create_characters.roll"]);
+
+	switch (_state) {
+	case SELECT_CLASS:
+		printClasses();
+		if (g_globals->_roster.full())
+			writeLine(9, STRING["dialogs.create_characters.full"], ALIGN_MIDDLE, 190);
+		break;
+
+	case SELECT_RACE:
+		printRaces();
+		break;
+
+	case SELECT_ALIGNMENT:
+		printAlignments();
+		break;
+
+	case SELECT_SEX:
+		printSexes();
+		break;
+
+	case SELECT_PORTRAIT:
+		printPortraits();
+		break;
+
+	case SELECT_NAME:
+		printSelectName();
+		break;
+
+	case SAVE_PROMPT:
+		printSummary();
+		break;
+
+	default:
+		break;
+	}
+}
+
+void CreateCharacters::printAttributes() {
+	writeLine(0, STRING["dialogs.create_characters.title"], ALIGN_MIDDLE);
+
+	writeLine(5, STRING["enhdialogs.create_characters.intellect"], ALIGN_RIGHT, 90);
+	writeLine(6, STRING["enhdialogs.create_characters.might"], ALIGN_RIGHT, 90);
+	writeLine(7, STRING["enhdialogs.create_characters.personality"], ALIGN_RIGHT, 90);
+	writeLine(8, STRING["enhdialogs.create_characters.endurance"], ALIGN_RIGHT, 90);
+	writeLine(9, STRING["enhdialogs.create_characters.speed"], ALIGN_RIGHT, 90);
+	writeLine(10, STRING["enhdialogs.create_characters.accuracy"], ALIGN_RIGHT, 90);
+	writeLine(11, STRING["enhdialogs.create_characters.luck"], ALIGN_RIGHT, 90);
+
+	for (int i = 0; i < 7; ++i, _textPos.y += 2) {
+		writeLine(5 + i,
+			Common::String::format("%u", _newChar._attribs1[i]),
+			ALIGN_RIGHT, 110);
+	}
+}
+
+void CreateCharacters::printClasses() {
+	for (int classNum = KNIGHT; classNum <= SORCERER; ++classNum) {
+		setTextColor(_newChar._classesAllowed[classNum] ? 0 : 1);
+		writeLine(4 + classNum, Common::String::format("%d) %s",
+			classNum,
+			STRING[Common::String::format("stats.classes.%d", classNum)].c_str()
+		), ALIGN_LEFT, 170);
+	}
+
+	setTextColor(0);
+	writeLine(10, Common::String::format("6) %s", STRING["stats.classes.6"].c_str()),
+		ALIGN_LEFT, 170);
+
+	writeLine(13, STRING["dialogs.create_characters.select_class"], ALIGN_MIDDLE, RIGHT_X);
+	writeLine(14, "(1-6)", ALIGN_MIDDLE, RIGHT_X);
+}
+
+void CreateCharacters::printRaces() {
+	writeLine(5, STRING["enhdialogs.create_characters.class"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.classes.%d", _newChar._class)]);
+
+	for (int i = 1; i <= 5; ++i) {
+		writeLine(6 + i, Common::String::format("%d) %s", i,
+			STRING[Common::String::format("stats.races.%d", i)].c_str()),
+			ALIGN_LEFT, 170);
+	}
+
+	writeLine(13, STRING["dialogs.create_characters.select_race"], ALIGN_MIDDLE, RIGHT_X);
+	writeLine(14, "(1-5)", ALIGN_MIDDLE, RIGHT_X);
+}
+
+void CreateCharacters::printAlignments() {
+	writeLine(5, STRING["enhdialogs.create_characters.class"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.classes.%d", _newChar._class)]);
+	writeLine(6, STRING["enhdialogs.create_characters.race"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.races.%d", _newChar._race)]);
+
+	for (int i = 1; i <= 3; ++i) {
+		writeLine(7 + i, Common::String::format("%d) %s", i,
+			STRING[Common::String::format("stats.alignments.%d", i)].c_str()),
+			ALIGN_LEFT, 170);
+	}
+
+	writeLine(13, STRING["dialogs.create_characters.select_alignment"], ALIGN_MIDDLE, RIGHT_X);
+	writeLine(14, "(1-3)", ALIGN_MIDDLE, RIGHT_X);
+}
+
+void CreateCharacters::printSexes() {
+	writeLine(5, STRING["enhdialogs.create_characters.class"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.classes.%d", _newChar._class)]);
+	writeLine(6, STRING["enhdialogs.create_characters.race"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.races.%d", _newChar._race)]);
+	writeLine(7, STRING["enhdialogs.create_characters.alignment"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.alignments.%d", _newChar._alignment)]);
+
+	writeLine(9, "1) ", ALIGN_LEFT, 170);
+	writeString(STRING["stats.sex.1"]);
+	writeLine(10, "2) ", ALIGN_LEFT, 170);
+	writeString(STRING["stats.sex.2"]);
+
+	writeLine(14, STRING["dialogs.create_characters.select_sex"], ALIGN_MIDDLE, RIGHT_X);
+	writeLine(15, "(1-2)", ALIGN_MIDDLE, RIGHT_X);
+}
+
+void CreateCharacters::printSelections() {
+	writeLine(5, STRING["enhdialogs.create_characters.class"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.classes.%d", _newChar._class)]);
+	writeLine(6, STRING["enhdialogs.create_characters.race"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.races.%d", _newChar._race)]);
+	writeLine(7, STRING["enhdialogs.create_characters.alignment"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.alignments.%d", _newChar._alignment)]);
+	writeLine(8, STRING["enhdialogs.create_characters.sex"], ALIGN_RIGHT, RIGHT_X);
+	writeString(STRING[Common::String::format("stats.sex.%d", _newChar._sex)]);
+}
+
+void CreateCharacters::printPortraits() {
+	printSelections();
+	writeLine(10, STRING["enhdialogs.create_characters.select_portrait"], ALIGN_MIDDLE, RIGHT_X);
+
+	Graphics::ManagedSurface s = getSurface();
+	_newChar._portraits.draw(&s, 0, Common::Point(160, 120));
+
+	writeString(250, 126, STRING["enhdialogs.create_characters.select"]);
+}
+
+void CreateCharacters::printSelectName() {
+	printSelections();
+	writeLine(10, STRING["enhdialogs.create_characters.enter_name"], ALIGN_MIDDLE, RIGHT_X);
+}
+
+void CreateCharacters::printSummary() {
+	printSelections();
+	writeLine(9, STRING["enhdialogs.create_characters.name"], ALIGN_RIGHT, RIGHT_X);
+	writeString(_newChar._name);
+
+	writeLine(12, STRING["dialogs.create_characters.save_character"], ALIGN_MIDDLE, RIGHT_X);
+	writeLine(14, "(Y/N)?", ALIGN_MIDDLE, RIGHT_X);
+}
+
+bool CreateCharacters::msgKeypress(const KeypressMessage &msg) {
+	if (msg.keycode == Common::KEYCODE_r && _state != SELECT_NAME) {
+		setState(SELECT_CLASS);
+		_newChar.reroll();
+		redraw();
+		return true;
+	}
+
+	switch (_state) {
+	case SELECT_CLASS:
+		if (msg.keycode >= Common::KEYCODE_1 &&
+				msg.keycode <= Common::KEYCODE_6) {
+			if (_newChar._classesAllowed[msg.keycode - Common::KEYCODE_0] &&
+					!g_globals->_roster.full()) {
+				// Selected a valid class
+				_newChar._class = (CharacterClass)(msg.keycode - Common::KEYCODE_0);
+				setState(SELECT_RACE);
+				redraw();
+			}
+		}
+		break;
+
+	case SELECT_RACE:
+		if (msg.keycode >= Common::KEYCODE_1 &&
+				msg.keycode <= Common::KEYCODE_5) {
+			// Selected a race
+			_newChar._race = (Race)(msg.keycode - Common::KEYCODE_0);
+
+			switch (_newChar._race) {
+			case ELF:
+				_newChar._attribs1[INTELLECT]++;
+				_newChar._attribs1[ACCURACY]++;
+				_newChar._attribs1[MIGHT]--;
+				_newChar._attribs1[ENDURANCE]--;
+				break;
+			case DWARF:
+				_newChar._attribs1[ENDURANCE]++;
+				_newChar._attribs1[LUCK]++;
+				_newChar._attribs1[INTELLECT]--;
+				_newChar._attribs1[SPEED]--;
+				break;
+			case GNOME:
+				_newChar._attribs1[LUCK] += 2;
+				_newChar._attribs1[SPEED]--;
+				_newChar._attribs1[ACCURACY]--;
+				break;
+			case HALF_ORC:
+				_newChar._attribs1[MIGHT]++;
+				_newChar._attribs1[ENDURANCE]++;
+				_newChar._attribs1[INTELLECT]--;
+				_newChar._attribs1[PERSONALITY]--;
+				_newChar._attribs1[LUCK]--;
+				break;
+			default:
+				break;
+			}
+
+			setState(SELECT_ALIGNMENT);
+			redraw();
+		}
+		break;
+
+	case SELECT_ALIGNMENT:
+		if (msg.keycode >= Common::KEYCODE_1 &&
+			msg.keycode <= Common::KEYCODE_3) {
+			// Selected a valid alignment
+			_newChar._alignment = (Alignment)(msg.keycode - Common::KEYCODE_0);
+			setState(SELECT_SEX);
+			redraw();
+		}
+		break;
+
+	case SELECT_SEX:
+		if (msg.keycode >= Common::KEYCODE_1 &&
+			msg.keycode <= Common::KEYCODE_2) {
+			// Selected a valid sex
+			_newChar._sex = (Sex)(msg.keycode - Common::KEYCODE_0);
+			_newChar.loadPortrait();
+			setState(SELECT_PORTRAIT);
+			redraw();
+		}
+		break;
+
+	case SELECT_PORTRAIT:
+		switch (msg.keycode) {
+		case Common::KEYCODE_UP:
+			_newChar._portrait = (_newChar._portrait == 0) ?
+				NUM_PORTRAITS - 1 : _newChar._portrait - 1;
+			_newChar.loadPortrait();
+			redraw();
+			break;
+		case Common::KEYCODE_DOWN:
+			_newChar._portrait = (_newChar._portrait + 1) % NUM_PORTRAITS;
+			_newChar.loadPortrait();
+			redraw();
+			break;
+		case Common::KEYCODE_s:
+			msgAction(ActionMessage(KEYBIND_SELECT));
+			break;
+		default:
+			break;
+		}
+
+		return true;
+
+	case SAVE_PROMPT:
+		if (msg.keycode == Common::KEYCODE_y)
+			_newChar.save();
+
+		setState(SELECT_CLASS);
+		redraw();
+		break;
+	}
+
+	return true;
+}
+
+bool CreateCharacters::msgAction(const ActionMessage &msg) {
+	switch (msg._action) {
+	case KEYBIND_ESCAPE:
+		if (_state == SELECT_CLASS) {
+			close();
+		} else {
+			setState(SELECT_CLASS);
+			_newChar.reroll();
+			redraw();
+		}
+		return true;
+
+	case KEYBIND_SELECT:
+		switch (_state) {
+		case SELECT_CLASS:
+			// Re-roll attributes
+			_newChar.reroll();
+			redraw();
+			break;
+		case SELECT_PORTRAIT:
+			setState(SELECT_NAME);
+			break;
+		case SAVE_PROMPT:
+			_newChar.save();
+
+			setState(SELECT_CLASS);
+			_newChar.reroll();
+			redraw();
+			break;
+		default:
+			break;
+		}
+		return true;
+
+	default:
+		break;
+	}
+
+	return false;
+}
+
+void CreateCharacters::setState(State state) {
+	_state = state;
+
+	setButtonEnabled(2, _state == SELECT_PORTRAIT);
+	setButtonEnabled(3, _state == SELECT_PORTRAIT);
+	setButtonEnabled(4, _state == SELECT_PORTRAIT);
+
+	if (_state == SELECT_CLASS)
+		_newChar.reroll();
+
+	if (_state == SELECT_NAME) {
+		draw();
+		_textEntry.display(160, 110, 15, false,
+			[]() {
+				CreateCharacters *view = static_cast<CreateCharacters *>(
+					g_events->focusedView());
+				view->setState(SELECT_CLASS);
+			},
+			[](const Common::String &name) {
+				CreateCharacters *view = static_cast<CreateCharacters *>(
+					g_events->focusedView());
+
+				view->_newChar._name = name;
+				view->setState(SAVE_PROMPT);
+			}
+		);
+	} else {
+		redraw();
+	}
+}
+
+} // namespace ViewsEnh
+} // namespace MM1
+} // namespace MM
diff --git a/engines/mm/mm1/views_enh/create_characters.h b/engines/mm/mm1/views_enh/create_characters.h
new file mode 100644
index 00000000000..ca48dd825da
--- /dev/null
+++ b/engines/mm/mm1/views_enh/create_characters.h
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef MM1_VIEWS_ENH_CREATE_CHARACTERS_H
+#define MM1_VIEWS_ENH_CREATE_CHARACTERS_H
+
+#include "mm/mm1/data/roster.h"
+#include "mm/mm1/views_enh/scroll_view.h"
+#include "mm/mm1/views_enh/text_entry.h"
+
+namespace MM {
+namespace MM1 {
+namespace ViewsEnh {
+
+class CreateCharacters : public ScrollView {
+	enum State {
+		SELECT_CLASS, SELECT_RACE, SELECT_ALIGNMENT,
+		SELECT_SEX, SELECT_PORTRAIT, SELECT_NAME, SAVE_PROMPT
+	};
+	enum Attribute {
+		INTELLECT, MIGHT, PERSONALITY, ENDURANCE, SPEED,
+		ACCURACY, LUCK
+	};
+	struct NewCharacter {
+	private:
+		void setHP(int hp);
+		void setSP(int sp);
+	public:
+		Shared::Xeen::SpriteResource _portraits;
+		uint8 _attribs1[LUCK + 1] = { 0 };
+		uint8 _attribs2[LUCK + 1] = { 0 };
+		CharacterClass _class = KNIGHT;
+		Race _race = HUMAN;
+		Alignment _alignment = GOOD;
+		Sex _sex = MALE;
+		Common::String _name;
+		int _portrait = 0;
+
+		bool _classesAllowed[7] = { false };
+
+		void clear();
+		void reroll();
+		void save();
+
+		void loadPortrait();
+	};
+
+private:
+	TextEntry _textEntry;
+	Shared::Xeen::SpriteResource _icons;
+	State _state = SELECT_CLASS;
+	NewCharacter _newChar;
+	int _portraitNum = 0;
+
+	/**
+	 * Displays the new character attributes
+	 */
+	void printAttributes();
+
+	/**
+	 * Display the available classes
+	 */
+	void printClasses();
+
+	/**
+	 * Display the races
+	 */
+	void printRaces();
+
+	/**
+	 * Display the alignments
+	 */
+	void printAlignments();
+
+	/**
+	 * Display the sexes
+	 */
+	void printSexes();
+
+	/**
+	 * Display the selected summaries
+	 */
+	void printSelections();
+
+	/**
+	 * Display the portrait selection
+	 */
+	void printPortraits();
+
+	/**
+	 * Display the name entry
+	 */
+	void printSelectName();
+
+	/**
+	 * Display the selection summary
+	 */
+	void printSummary();
+
+	/**
+	 * Sets a new state
+	 */
+	void setState(State state);
+
+public:
+	CreateCharacters();
+	virtual ~CreateCharacters() {}
+
+	bool msgFocus(const FocusMessage &msg) override {
+		_newChar.reroll();
+		return true;
+	}
+	void draw() override;
+	bool msgKeypress(const KeypressMessage &msg) override;
+	bool msgAction(const ActionMessage &msg) override;
+};
+
+} // namespace ViewsEnh
+} // namespace MM1
+} // namespace MM
+
+#endif
diff --git a/engines/mm/mm1/views_enh/dialogs.h b/engines/mm/mm1/views_enh/dialogs.h
index 950f90f7920..4d0bd264b60 100644
--- a/engines/mm/mm1/views_enh/dialogs.h
+++ b/engines/mm/mm1/views_enh/dialogs.h
@@ -23,7 +23,7 @@
 #define MM1_VIEWS_ENH_DIALOGS_H
 
 #include "mm/mm1/events.h"
-#include "mm/mm1/views/create_characters.h"
+#include "mm/mm1/views_enh/create_characters.h"
 #include "mm/mm1/views/locations/inn.h"
 #include "mm/mm1/views/protect.h"
 #include "mm/mm1/views/title.h"
@@ -50,7 +50,7 @@ namespace ViewsEnh {
 
 struct Dialogs {
 private:
-	Views::CreateCharacters _createCharacters;
+	ViewsEnh::CreateCharacters _createCharacters;
 	Views::Protect _protect;
 	Views::Title _title;
 	ViewsEnh::Characters _characters;
diff --git a/engines/mm/module.mk b/engines/mm/module.mk
index 38413e7c578..6bc57141fc6 100644
--- a/engines/mm/module.mk
+++ b/engines/mm/module.mk
@@ -131,6 +131,7 @@ MODULE_OBJS += \
 	mm1/views_enh/character_select.o \
 	mm1/views_enh/character_view.o \
 	mm1/views_enh/characters.o \
+	mm1/views_enh/create_characters.o \
 	mm1/views_enh/dialogs.o \
 	mm1/views_enh/game.o \
 	mm1/views_enh/game_commands.o \


Commit: b52ddaced05afd4a956eba4d89f603c756f09ecc
    https://github.com/scummvm/scummvm/commit/b52ddaced05afd4a956eba4d89f603c756f09ecc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2023-03-07T22:31:58-08:00

Commit Message:
MM: MM1: Allow mouse clicks on class/race/etc. options in Create Characters

Changed paths:
    engines/mm/mm1/views_enh/create_characters.cpp
    engines/mm/mm1/views_enh/create_characters.h
    engines/mm/mm1/views_enh/scroll_view.cpp
    engines/mm/mm1/views_enh/scroll_view.h


diff --git a/engines/mm/mm1/views_enh/create_characters.cpp b/engines/mm/mm1/views_enh/create_characters.cpp
index 93640d6d905..8cd4933cdc3 100644
--- a/engines/mm/mm1/views_enh/create_characters.cpp
+++ b/engines/mm/mm1/views_enh/create_characters.cpp
@@ -269,6 +269,13 @@ void CreateCharacters::printAttributes() {
 	}
 }
 
+void CreateCharacters::addSelection(int yStart, int num) {
+	Common::Rect r(170, 0, 320, 9);
+	r.translate(0, (yStart + num) * 9);
+
+	addButton(r, Common::KeyState((Common::KeyCode)(Common::KEYCODE_0 + num), '0' + num));
+}
+
 void CreateCharacters::printClasses() {
 	for (int classNum = KNIGHT; classNum <= SORCERER; ++classNum) {
 		setTextColor(_newChar._classesAllowed[classNum] ? 0 : 1);
@@ -276,11 +283,15 @@ void CreateCharacters::printClasses() {
 			classNum,
 			STRING[Common::String::format("stats.classes.%d", classNum)].c_str()
 		), ALIGN_LEFT, 170);
+
+		if (_newChar._classesAllowed[classNum])
+			addSelection(4, classNum);
 	}
 
 	setTextColor(0);
 	writeLine(10, Common::String::format("6) %s", STRING["stats.classes.6"].c_str()),
 		ALIGN_LEFT, 170);
+	addSelection(4, ROBBER);
 
 	writeLine(13, STRING["dialogs.create_characters.select_class"], ALIGN_MIDDLE, RIGHT_X);
 	writeLine(14, "(1-6)", ALIGN_MIDDLE, RIGHT_X);
@@ -294,6 +305,7 @@ void CreateCharacters::printRaces() {
 		writeLine(6 + i, Common::String::format("%d) %s", i,
 			STRING[Common::String::format("stats.races.%d", i)].c_str()),
 			ALIGN_LEFT, 170);
+		addSelection(6, i);
 	}
 
 	writeLine(13, STRING["dialogs.create_characters.select_race"], ALIGN_MIDDLE, RIGHT_X);
@@ -310,6 +322,7 @@ void CreateCharacters::printAlignments() {
 		writeLine(7 + i, Common::String::format("%d) %s", i,
 			STRING[Common::String::format("stats.alignments.%d", i)].c_str()),
 			ALIGN_LEFT, 170);
+		addSelection(7, i);
 	}
 
 	writeLine(13, STRING["dialogs.create_characters.select_alignment"], ALIGN_MIDDLE, RIGHT_X);
@@ -326,8 +339,10 @@ void CreateCharacters::printSexes() {
 
 	writeLine(9, "1) ", ALIGN_LEFT, 170);
 	writeString(STRING["stats.sex.1"]);
+	addSelection(8, 1);
 	writeLine(10, "2) ", ALIGN_LEFT, 170);
 	writeString(STRING["stats.sex.2"]);
+	addSelection(8, 2);
 
 	writeLine(14, STRING["dialogs.create_characters.select_sex"], ALIGN_MIDDLE, RIGHT_X);
 	writeLine(15, "(1-2)", ALIGN_MIDDLE, RIGHT_X);
@@ -532,6 +547,7 @@ void CreateCharacters::setState(State state) {
 	setButtonEnabled(2, _state == SELECT_PORTRAIT);
 	setButtonEnabled(3, _state == SELECT_PORTRAIT);
 	setButtonEnabled(4, _state == SELECT_PORTRAIT);
+	removeButtons(5, -1);
 
 	if (_state == SELECT_CLASS)
 		_newChar.reroll();
diff --git a/engines/mm/mm1/views_enh/create_characters.h b/engines/mm/mm1/views_enh/create_characters.h
index ca48dd825da..7d2b0d59d06 100644
--- a/engines/mm/mm1/views_enh/create_characters.h
+++ b/engines/mm/mm1/views_enh/create_characters.h
@@ -75,6 +75,11 @@ private:
 	 */
 	void printAttributes();
 
+	/**
+	 * Add a selection entry
+	 */
+	void addSelection(int yStart, int num);
+
 	/**
 	 * Display the available classes
 	 */
diff --git a/engines/mm/mm1/views_enh/scroll_view.cpp b/engines/mm/mm1/views_enh/scroll_view.cpp
index ebab01235f3..60ebd15f771 100644
--- a/engines/mm/mm1/views_enh/scroll_view.cpp
+++ b/engines/mm/mm1/views_enh/scroll_view.cpp
@@ -64,6 +64,16 @@ int ScrollView::addButton(const Common::Rect &r, KeybindingAction action) {
 	return _buttons.size() - 1;
 }
 
+void ScrollView::removeButtons(int start, int end) {
+	if (end == -1)
+		end = (int)_buttons.size() - 1;
+	else if (end == -2)
+		end = start;
+
+	for (; end >= start; --end)
+		_buttons.remove_at(end);
+}
+
 void ScrollView::resetSelectedButton() {
 	_selectedButton = -1;
 	redraw();
diff --git a/engines/mm/mm1/views_enh/scroll_view.h b/engines/mm/mm1/views_enh/scroll_view.h
index 29c2286fd48..42bd28d2bb7 100644
--- a/engines/mm/mm1/views_enh/scroll_view.h
+++ b/engines/mm/mm1/views_enh/scroll_view.h
@@ -142,6 +142,11 @@ public:
 		_buttons[buttonNum]._bounds.moveTo(pos);
 	}
 
+	/**
+	 * Delete buttons
+	 */
+	void removeButtons(int start, int end = -2);
+
 	/**
 	 * Reset selected button
 	 */


Commit: 721c9a846a153790ad1b7201f02615fbf077c446
    https://github.com/scummvm/scummvm/commit/721c9a846a153790ad1b7201f02615fbf077c446
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2023-03-07T22:39:51-08:00

Commit Message:
MM: MM1: Add a _priorView field to FocusMessage

Changed paths:
    engines/mm/mm1/events.cpp
    engines/mm/mm1/messages.h
    engines/mm/mm1/views_enh/create_characters.cpp
    engines/mm/mm1/views_enh/create_characters.h


diff --git a/engines/mm/mm1/events.cpp b/engines/mm/mm1/events.cpp
index 3d85c2f119c..7179df9f290 100644
--- a/engines/mm/mm1/events.cpp
+++ b/engines/mm/mm1/events.cpp
@@ -107,17 +107,19 @@ void Events::processEvent(Common::Event &ev) {
 
 void Events::replaceView(UIElement *ui, bool replaceAllViews) {
 	assert(ui);
+	UIElement *priorView = focusedView();
+
 	if (replaceAllViews) {
 		clearViews();
 
 	} else if (!_views.empty()) {
-		focusedView()->msgUnfocus(UnfocusMessage());
+		priorView->msgUnfocus(UnfocusMessage());
 		_views.pop();
 	}
 
 	_views.push(ui);
 	ui->redraw();
-	ui->msgFocus(FocusMessage());
+	ui->msgFocus(FocusMessage(priorView));
 }
 
 void Events::replaceView(const Common::String &name, bool replaceAllViews) {
@@ -126,12 +128,14 @@ void Events::replaceView(const Common::String &name, bool replaceAllViews) {
 
 void Events::addView(UIElement *ui) {
 	assert(ui);
+	UIElement *priorView = focusedView();
+
 	if (!_views.empty())
-		focusedView()->msgUnfocus(UnfocusMessage());
+		priorView->msgUnfocus(UnfocusMessage());
 
 	_views.push(ui);
 	ui->redraw();
-	ui->msgFocus(FocusMessage());
+	ui->msgFocus(FocusMessage(priorView));
 }
 
 void Events::addView(const Common::String &name) {
@@ -139,7 +143,8 @@ void Events::addView(const Common::String &name) {
 }
 
 void Events::popView() {
-	focusedView()->msgUnfocus(UnfocusMessage());
+	UIElement *priorView = focusedView();
+	priorView->msgUnfocus(UnfocusMessage());
 	_views.pop();
 
 	for (int i = 0; i < (int)_views.size() - 1; ++i) {
@@ -148,7 +153,7 @@ void Events::popView() {
 	}
 
 	if (!_views.empty()) {
-		focusedView()->msgFocus(FocusMessage());
+		focusedView()->msgFocus(FocusMessage(priorView));
 		focusedView()->redraw();
 	}
 }
diff --git a/engines/mm/mm1/messages.h b/engines/mm/mm1/messages.h
index 97860a92f51..f14f373136d 100644
--- a/engines/mm/mm1/messages.h
+++ b/engines/mm/mm1/messages.h
@@ -30,12 +30,21 @@
 namespace MM {
 namespace MM1 {
 
+class UIElement;
+
 enum TextAlign {
 	ALIGN_LEFT, ALIGN_RIGHT, ALIGN_MIDDLE
 };
 
 struct Message {};
-struct FocusMessage : public Message {};
+
+struct FocusMessage : public Message {
+	UIElement *_priorView = nullptr;
+	FocusMessage() : Message() {}
+	FocusMessage(UIElement *priorView) : Message(),
+		_priorView(priorView) {}
+};
+
 struct UnfocusMessage : public Message {};
 struct ActionMessage : public Message {
 	KeybindingAction _action;
diff --git a/engines/mm/mm1/views_enh/create_characters.cpp b/engines/mm/mm1/views_enh/create_characters.cpp
index 8cd4933cdc3..99740addc02 100644
--- a/engines/mm/mm1/views_enh/create_characters.cpp
+++ b/engines/mm/mm1/views_enh/create_characters.cpp
@@ -203,6 +203,12 @@ CreateCharacters::CreateCharacters() : ScrollView("CreateCharacters") {
 	setButtonEnabled(4, false);
 }
 
+bool CreateCharacters::msgFocus(const FocusMessage &msg) {
+	if (dynamic_cast<TextEntry *>(msg._priorView) == nullptr)
+		_newChar.reroll();
+	return true;
+}
+
 void CreateCharacters::draw() {
 	ScrollView::draw();
 	printAttributes();
diff --git a/engines/mm/mm1/views_enh/create_characters.h b/engines/mm/mm1/views_enh/create_characters.h
index 7d2b0d59d06..a7faf5c1158 100644
--- a/engines/mm/mm1/views_enh/create_characters.h
+++ b/engines/mm/mm1/views_enh/create_characters.h
@@ -129,10 +129,7 @@ public:
 	CreateCharacters();
 	virtual ~CreateCharacters() {}
 
-	bool msgFocus(const FocusMessage &msg) override {
-		_newChar.reroll();
-		return true;
-	}
+	bool msgFocus(const FocusMessage &msg) override;
 	void draw() override;
 	bool msgKeypress(const KeypressMessage &msg) override;
 	bool msgAction(const ActionMessage &msg) override;




More information about the Scummvm-git-logs mailing list