[Scummvm-git-logs] scummvm master -> 5f34a083fa1bc6522015175158c1d922aa73e24d

mduggan mgithub at guarana.org
Mon Jul 6 07:28:31 UTC 2020


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

Summary:
e2d33860fa ULTIMA8: Show item pickups in Crusader
51ee9991bd ULTIMA8: Display crusader item data from ini file
5f34a083fa ULTIMA8: Fix null check that was backwards


Commit: e2d33860fa0b3ac7e8d1ae45f874b9fbb70985df
    https://github.com/scummvm/scummvm/commit/e2d33860fa0b3ac7e8d1ae45f874b9fbb70985df
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-06T16:23:27+09:00

Commit Message:
ULTIMA8: Show item pickups in Crusader

Changed paths:
  A engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
  A engines/ultima/ultima8/gumps/cru_pickup_area_gump.h
  A engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
  A engines/ultima/ultima8/gumps/cru_pickup_gump.h
  A engines/ultima/ultima8/gumps/translucent_gump.cpp
  A engines/ultima/ultima8/gumps/translucent_gump.h
    engines/ultima/module.mk
    engines/ultima/ultima8/games/start_crusader_process.cpp
    engines/ultima/ultima8/graphics/type_flags.cpp
    engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
    engines/ultima/ultima8/gumps/cru_ammo_gump.h
    engines/ultima/ultima8/gumps/cru_energy_gump.cpp
    engines/ultima/ultima8/gumps/cru_health_gump.cpp
    engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
    engines/ultima/ultima8/gumps/cru_inventory_gump.h
    engines/ultima/ultima8/gumps/cru_stat_gump.cpp
    engines/ultima/ultima8/gumps/cru_stat_gump.h
    engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
    engines/ultima/ultima8/gumps/gump.h
    engines/ultima/ultima8/gumps/widgets/text_widget.h
    engines/ultima/ultima8/world/actors/main_actor.cpp
    engines/ultima/ultima8/world/weapon_info.h


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index f539f12dab..2c3f017992 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -464,6 +464,8 @@ MODULE_OBJS := \
 	ultima8/gumps/cru_energy_gump.o \
 	ultima8/gumps/cru_health_gump.o \
 	ultima8/gumps/cru_inventory_gump.o \
+	ultima8/gumps/cru_pickup_area_gump.o \
+	ultima8/gumps/cru_pickup_gump.o \
 	ultima8/gumps/cru_stat_gump.o \
 	ultima8/gumps/cru_status_gump.o \
 	ultima8/gumps/cru_weapon_gump.o \
@@ -493,6 +495,7 @@ MODULE_OBJS := \
 	ultima8/gumps/shape_viewer_gump.o \
 	ultima8/gumps/slider_gump.o \
 	ultima8/gumps/target_gump.o \
+	ultima8/gumps/translucent_gump.o \
 	ultima8/gumps/u8_save_gump.o \
 	ultima8/gumps/widgets/button_widget.o \
 	ultima8/gumps/widgets/edit_widget.o \
diff --git a/engines/ultima/ultima8/games/start_crusader_process.cpp b/engines/ultima/ultima8/games/start_crusader_process.cpp
index bcc943e1d8..2fecf30af3 100644
--- a/engines/ultima/ultima8/games/start_crusader_process.cpp
+++ b/engines/ultima/ultima8/games/start_crusader_process.cpp
@@ -36,6 +36,7 @@
 #include "ultima/ultima8/kernel/kernel.h"
 #include "ultima/ultima8/gumps/menu_gump.h"
 #include "ultima/ultima8/gumps/cru_status_gump.h"
+#include "ultima/ultima8/gumps/cru_pickup_area_gump.h"
 #include "ultima/ultima8/conf/setting_manager.h"
 #include "ultima/ultima8/world/get_object.h"
 #include "ultima/ultima8/world/item_factory.h"
@@ -75,7 +76,10 @@ void StartCrusaderProcess::run() {
 	}
 
 	Gump *statusGump = new CruStatusGump();
-	statusGump->InitGump(nullptr);
+	statusGump->InitGump(nullptr, false);
+
+	Gump *cruPickupAreaGump = new CruPickupAreaGump();
+	cruPickupAreaGump->InitGump(nullptr, false);
 
 	// Try to load the save game, if succeeded this pointer will no longer be valid
 	if (_saveSlot >= 0 &&Ultima8Engine::get_instance()->loadGameState(_saveSlot).getCode() == Common::kNoError) {
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index e485e4f961..9189e6e140 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -245,6 +245,11 @@ void TypeFlags::loadWeaponInfo() {
 		else
 			wi->_ammoType = 0;
 
+		if (config->get(k + "/ammo_shape", val))
+			wi->_ammoShape = static_cast<uint16>(val);
+		else
+			wi->_ammoShape = 0;
+
 		if (config->get(k + "/sound", val))
 			wi->_sound = static_cast<uint16>(val);
 		else
diff --git a/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
index 266818b86b..226e8b445e 100644
--- a/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
@@ -29,18 +29,17 @@
 #include "ultima/ultima8/graphics/shape_frame.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
+#include "ultima/ultima8/gumps/widgets/text_widget.h"
 #include "ultima/ultima8/world/get_object.h"
 
 namespace Ultima {
 namespace Ultima8 {
 
-static const int AMMO_GUMP_SHAPE = 4;
+static const int AMMO_GUMP_SHAPE = 2;
 
 DEFINE_RUNTIME_CLASSTYPE_CODE(CruAmmoGump)
 
-CruAmmoGump::CruAmmoGump() : CruStatGump(), _ammoShape(nullptr) {
+CruAmmoGump::CruAmmoGump() : CruStatGump() {
 
 }
 
@@ -55,31 +54,64 @@ CruAmmoGump::~CruAmmoGump() {
 void CruAmmoGump::InitGump(Gump *newparent, bool take_focus) {
 	CruStatGump::InitGump(newparent, take_focus);
 
-	GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
-	if (!gumpshapes) {
-		warning("failed to init stat gump: no gump shape archive");
-		return;
-	}
-
-	_ammoShape = gumpshapes->getShape(AMMO_GUMP_SHAPE);
-	if (!_ammoShape || !_ammoShape->getFrame(0)) {
-		warning("failed to init stat gump: no ammo shape");
-		return;
-	}
+	_bulletsText = new TextWidget();
+	_clipsText = new TextWidget();
 }
 
 void CruAmmoGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
 	CruStatGump::PaintThis(surf, lerp_factor, scaled);
 
-	const MainActor *a = getMainActor();
+	MainActor *a = getMainActor();
 	if (!a) {
 		// avatar gone??
 		return;
 	}
 
-	uint16 weapon = a->getDamageType(); // ?? TODO: Where do we store current weapon?
-	/*const ShapeFrame *frame = */_ammoShape->getFrame(weapon);
-	// TODO: Paint the current weapon
+	uint16 active = a->getActiveWeapon();
+	uint16 ammoitem = 0;
+	uint16 bullets = 0;
+	uint16 clips = 0;
+	if (!active) {
+		bullets = 0;
+	} else {
+		Item *item = getItem(active);
+		if (!item) {
+			bullets = 0;
+		} else {
+			WeaponInfo *weaponinfo = item->getShapeInfo()->_weaponInfo;
+			uint16 frameno = 0;
+			if (weaponinfo) {
+				frameno = weaponinfo->_ammoType;
+				ammoitem = weaponinfo->_ammoShape;
+			}
+
+			bullets= item->getQuality();
+		}
+	}
+
+	const Std::string bulletstr = Std::string::format("%d", bullets);
+	if (!bulletstr.equals(_bulletsText->getText())) {
+		RemoveChild(_bulletsText);
+		_bulletsText = new TextWidget(22, _dims.h / 2 - 3, bulletstr, true, 15);
+		_bulletsText->InitGump(this, false);
+	}
+
+	if (ammoitem) {
+		Item *item = a->getFirstItemWithShape(ammoitem, true);
+		if (item) {
+			clips = item->getQuality();
+		} else {
+			clips = 0;
+		}
+	}
+
+	const Std::string clipstr = Std::string::format("%d", clips);
+	if (!clipstr.equals(_clipsText->getText())) {
+		RemoveChild(_clipsText);
+		_clipsText = new TextWidget(_dims.w / 2 + 22, _dims.h / 2 - 3, clipstr, true, 15);
+		_clipsText->InitGump(this, false);
+	}
+
 }
 
 void CruAmmoGump::saveData(Common::WriteStream *ws) {
diff --git a/engines/ultima/ultima8/gumps/cru_ammo_gump.h b/engines/ultima/ultima8/gumps/cru_ammo_gump.h
index ee13a666e1..85bab3fec8 100644
--- a/engines/ultima/ultima8/gumps/cru_ammo_gump.h
+++ b/engines/ultima/ultima8/gumps/cru_ammo_gump.h
@@ -29,6 +29,8 @@
 namespace Ultima {
 namespace Ultima8 {
 
+class TextWidget;
+
 /**
  * Second box along the bottom of the screen, shows current ammo
  */
@@ -50,7 +52,10 @@ public:
 	void saveData(Common::WriteStream *ws) override;
 
 private:
-	const Shape *_ammoShape;
+	Shape *_ammoShape;
+
+	TextWidget *_bulletsText;
+	TextWidget *_clipsText;
 };
 
 } // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/gumps/cru_energy_gump.cpp b/engines/ultima/ultima8/gumps/cru_energy_gump.cpp
index f23a7762dd..342486bd8c 100644
--- a/engines/ultima/ultima8/gumps/cru_energy_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_energy_gump.cpp
@@ -29,8 +29,6 @@
 #include "ultima/ultima8/graphics/shape_frame.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
 #include "ultima/ultima8/world/get_object.h"
 
 namespace Ultima {
diff --git a/engines/ultima/ultima8/gumps/cru_health_gump.cpp b/engines/ultima/ultima8/gumps/cru_health_gump.cpp
index da4b82e745..1a457a5221 100644
--- a/engines/ultima/ultima8/gumps/cru_health_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_health_gump.cpp
@@ -30,7 +30,6 @@
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
 #include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
 #include "ultima/ultima8/world/get_object.h"
 
 namespace Ultima {
diff --git a/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
index 2c4e146915..29a7e9aead 100644
--- a/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
@@ -30,13 +30,14 @@
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
 #include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
 #include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/gumps/widgets/text_widget.h"
 
 namespace Ultima {
 namespace Ultima8 {
 
 static const int INVENTORY_GUMP_SHAPE = 5;
+static const int INVENTORY_TEXT_FONT = 12;
 
 DEFINE_RUNTIME_CLASSTYPE_CODE(CruInventoryGump)
 CruInventoryGump::CruInventoryGump() : CruStatGump(), _inventoryShape(nullptr),
@@ -69,6 +70,9 @@ void CruInventoryGump::InitGump(Gump *newparent, bool take_focus) {
 	_inventoryItemGump = new Gump();
 	_inventoryItemGump->InitGump(this, false);
 	// we'll set the shape for this gump later.
+
+	_inventoryText = new TextWidget();
+	_inventoryText->InitGump(this, false);
 }
 
 // TODO: This is a bit of a hack.. should be configured
@@ -122,7 +126,25 @@ void CruInventoryGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool sc
 			_inventoryItemGump->SetShape(_inventoryShape, frame);
 			_inventoryItemGump->UpdateDimsFromShape();
 			_inventoryItemGump->setRelativePosition(CENTER);
-			// TODO: Add text for count (from q)
+
+			uint16 q = item->getQuality();
+			if (q > 1) {
+				// This isn't the most efficient way to work out if we need to make new
+				// text, but it works..
+				const Std::string qtext = Std::string::format("%d", q);
+				const Std::string &currenttext = _inventoryText->getText();
+				if (!qtext.equals(currenttext)) {
+					RemoveChild(_inventoryText);
+					_inventoryText = new TextWidget(_dims.w / 2 + 22, _dims.h / 2 + 3, qtext, true, 12);
+					_inventoryText->InitGump(this, false);
+				}
+			} else {
+				if (_inventoryText->getText().length() > 0) {
+					RemoveChild(_inventoryText);
+					_inventoryText = new TextWidget();
+					_inventoryText->InitGump(this, false);
+				}
+			}
 		}
 	}
 
diff --git a/engines/ultima/ultima8/gumps/cru_inventory_gump.h b/engines/ultima/ultima8/gumps/cru_inventory_gump.h
index 9e64574dc5..f872273a02 100644
--- a/engines/ultima/ultima8/gumps/cru_inventory_gump.h
+++ b/engines/ultima/ultima8/gumps/cru_inventory_gump.h
@@ -29,6 +29,8 @@
 namespace Ultima {
 namespace Ultima8 {
 
+class TextWidget;
+
 /**
  * Inventory box, the 3rd box along the bottom of the screen
  */
@@ -52,6 +54,7 @@ public:
 private:
 	Shape *_inventoryShape;
 	Gump *_inventoryItemGump;
+	TextWidget *_inventoryText;
 };
 
 } // End of namespace Ultima8
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
new file mode 100644
index 0000000000..a498734f7e
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
@@ -0,0 +1,86 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_pickup_area_gump.h"
+#include "ultima/ultima8/gumps/cru_pickup_gump.h"
+
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/world/item.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const int PICKUP_GUMP_GAP = 5;
+static const int PICKUP_GUMP_HEIGHT = 30;
+
+CruPickupAreaGump *CruPickupAreaGump::_instance;
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruPickupAreaGump)
+
+CruPickupAreaGump::CruPickupAreaGump() : Gump(PICKUP_GUMP_GAP, PICKUP_GUMP_GAP, 200, 500, 0) {
+    _instance = this;
+}
+
+CruPickupAreaGump::~CruPickupAreaGump() {
+}
+
+void CruPickupAreaGump::addPickup(Item *item) {
+	if (!item)
+		return;
+
+	uint32 shapeno = item->getShape();
+
+	// TODO: This is not quite right.  We want to add the "q" values of the existing one and the new one.  Eg, if we have 5 medikits and add 2, we should show "2" in the toast.
+	Std::list<Gump *>::iterator it;
+	int32 yoff = 0;
+	uint16 qval = 0;
+	for (it = _children.begin(); it != _children.end(); it++) {
+		CruPickupGump *pug = dynamic_cast<CruPickupGump *>(*it);
+		if (!pug)
+			return;
+		int32 x;
+		pug->getLocation(x, yoff);
+		if (pug->getShapeNo() == shapeno) {
+			// Already a notification for this object, close it
+			// and make a new one in the same spot.
+			qval = pug->getQ();
+			pug->Close();
+			break;
+		}
+	}
+	if (it == _children.end()) {
+		yoff += PICKUP_GUMP_GAP;
+		if (_children.size() > 0)
+			yoff += PICKUP_GUMP_HEIGHT;
+	}
+	Gump *newgump = new CruPickupGump(item, yoff, qval);
+	newgump->InitGump(this, false);
+}
+
+CruPickupAreaGump *CruPickupAreaGump::get_instance() {
+	return _instance;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_area_gump.h b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.h
new file mode 100644
index 0000000000..9b3bc66f17
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.h
@@ -0,0 +1,56 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUPICKUPAREAGUMP_H
+#define ULTIMA8_GUMPS_CRUPICKUPAREAGUMP_H
+
+#include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class TextWidget;
+
+/**
+ * The area that manages all the "pickup" gumps (the notifications that a new
+ * item has been picked up)
+ */
+class CruPickupAreaGump : public Gump {
+public:
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	CruPickupAreaGump();
+	CruPickupAreaGump(Item *item, int y);
+	~CruPickupAreaGump() override;
+
+	void addPickup(Item *item);
+
+	static CruPickupAreaGump *get_instance();
+private:
+    static CruPickupAreaGump *_instance;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp b/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
new file mode 100644
index 0000000000..f91ae9e4bd
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
@@ -0,0 +1,146 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/cru_pickup_gump.h"
+
+#include "ultima/ultima8/gumps/translucent_gump.h"
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/gumps/widgets/text_widget.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+static const int PICKUP_GUMP_SHAPE = 2;
+static const int COUNT_TEXT_FONT = 12;
+static const int ITEM_TEXT_FONT = 13;
+static const int ITEM_AREA_WIDTH = 60;
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruPickupGump)
+CruPickupGump::CruPickupGump() : Gump(), _startFrame(0), _shapeno(0), _q(0) {
+
+}
+
+CruPickupGump::CruPickupGump(Item *item, int y, uint16 currentq) : Gump(0, y, 5, 5, 0), _startFrame(0) {
+	_shapeno = item->getShape();
+	_q = item->getQuality();
+	// TODO: should we add current q? + currentq;
+	// It seems like the items are hacked to give the right "q" for
+	// this gump from the last item, which is why the add process
+	// uses q + 1 instead of adding the new q.
+}
+
+CruPickupGump::~CruPickupGump() {
+}
+
+void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
+	Gump::InitGump(newparent, take_focus);
+
+	if (!_shapeno)
+		return;
+
+	_startFrame = Kernel::get_instance()->getFrameNum();
+
+	// TODO: Get the appropriate name, shape, and frame for the item here.
+	Std::string itemname = "MEDICAL KIT";
+	// The gump shape no for the item (not the no. of the item itself)
+	// Eg, weapons are gumpshape 3, other items are gumpshape 5, etc.
+	uint32 itemshapeno = 5;
+	// The frame within that gump shape
+	uint32 itemframeno = 0;
+
+	// Get the shapes we will need..
+	GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
+	if (!gumpshapes) {
+		warning("failed to init stat gump: no gump shape archive");
+		return;
+	}
+
+	const Shape *background = gumpshapes->getShape(PICKUP_GUMP_SHAPE);
+	if (!background || !background->getFrame(0)) {
+		warning("failed to init stat gump: no pickup background shape");
+		return;
+	}
+	const ShapeFrame *bgframe = background->getFrame(0);
+
+	Shape* itemshape = gumpshapes->getShape(itemshapeno);
+	if (!itemshape || !itemshape->getFrame(itemframeno)) {
+		warning("failed to init stat gump: no item shape");
+		return;
+	}
+
+	// Paint a semi-transparent background
+	const FrameID bfgrameid(GameData::GUMPS, PICKUP_GUMP_SHAPE, 0);
+	// TODO: The game uses a variable number of these depending on the text length
+	for (int i = 0; i < 5; i++) {
+		Gump *gump = new TranslucentGump(i * bgframe->_width, 0, bgframe->_width, bgframe->_height);
+		gump->SetShape(bfgrameid, false);
+		gump->InitGump(this, false);
+	}
+	_dims.w = bgframe->_width * 5;
+	_dims.h = bgframe->_height;
+
+	// Paint the item name text
+	TextWidget *text = new TextWidget(ITEM_AREA_WIDTH, bgframe->_height / 2, itemname, true, ITEM_TEXT_FONT);
+	text->InitGump(this, false);
+
+	// Paint the count if needed
+	if (_q > 1) {
+		Std::string qstr = Std::string::format("%d", _q);
+		TextWidget *count = new TextWidget(ITEM_AREA_WIDTH / 2 + 22, _dims.h / 2 + 3, qstr, true, COUNT_TEXT_FONT);
+		count->InitGump(this, false);
+	}
+
+	// Paint the item in the mid-left item area.
+	const ShapeFrame *itemframe = itemshape->getFrame(itemframeno);
+	Gump *itemgump = new Gump(0, _dims.h / 2 - itemframe->_height / 2, itemframe->_width, itemframe->_height, 0, 0, LAYER_ABOVE_NORMAL);
+	itemgump->SetShape(itemshape, itemframeno);
+	itemgump->InitGump(this, false);
+	itemgump->UpdateDimsFromShape();
+	itemgump->Move(ITEM_AREA_WIDTH / 2 - itemframe->_width / 2, _dims.h / 2 - itemframe->_height / 2);
+}
+
+void CruPickupGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+	uint32 frameno = Kernel::get_instance()->getFrameNum();
+	if (!_shapeno || frameno - _startFrame > 90) {
+		Close();
+		return;
+	}
+}
+
+void CruPickupGump::saveData(Common::WriteStream *ws) {
+	Gump::saveData(ws);
+}
+
+bool CruPickupGump::loadData(Common::ReadStream *rs, uint32 version) {
+	return Gump::loadData(rs, version);
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_gump.h b/engines/ultima/ultima8/gumps/cru_pickup_gump.h
new file mode 100644
index 0000000000..ead01f121b
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_pickup_gump.h
@@ -0,0 +1,73 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUPICKUPGUMP_H
+#define ULTIMA8_GUMPS_CRUPICKUPGUMP_H
+
+#include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class TextWidget;
+
+/**
+ * Pickup box, the box that appears in the top left when a new item is picked up
+ */
+class CruPickupGump : public Gump {
+public:
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	CruPickupGump();
+	//! Create a new gump for an item pickup. CurrentQ is the value of an existing gump
+	//! so they can be combined (eg, pick up one medikit then another -> show medikit 2)
+	CruPickupGump(Item *item, int y, uint16 currentq);
+	~CruPickupGump() override;
+
+	// Init the gump, call after construction
+	void InitGump(Gump *newparent, bool take_focus = true) override;
+
+	// Paint this Gump
+	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+	uint32 getShapeNo() const {
+		return _shapeno;
+	}
+
+	uint16 getQ() {
+		return _q;
+	}
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+private:
+	uint32 _startFrame;
+	uint32 _shapeno;
+	uint16 _q;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_stat_gump.cpp b/engines/ultima/ultima8/gumps/cru_stat_gump.cpp
index b61b3afed7..01557fdb1f 100644
--- a/engines/ultima/ultima8/gumps/cru_stat_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_stat_gump.cpp
@@ -27,10 +27,7 @@
 #include "ultima/ultima8/graphics/gump_shape_archive.h"
 #include "ultima/ultima8/graphics/shape.h"
 #include "ultima/ultima8/graphics/shape_frame.h"
-#include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
 #include "ultima/ultima8/world/get_object.h"
 
 namespace Ultima {
@@ -38,12 +35,12 @@ namespace Ultima8 {
 
 DEFINE_RUNTIME_CLASSTYPE_CODE(CruStatGump)
 
-CruStatGump::CruStatGump() : Gump() {
+CruStatGump::CruStatGump() : TranslucentGump() {
 
 }
 
 CruStatGump::CruStatGump(Shape *shape, int x)
-	: Gump(x, 0, 5, 5, 0) {
+	: TranslucentGump(x, 0, 5, 5, 0) {
 	_shape = shape;
 }
 
@@ -56,10 +53,6 @@ void CruStatGump::InitGump(Gump *newparent, bool take_focus) {
 	UpdateDimsFromShape();
 }
 
-void CruStatGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
-	surf->PaintTranslucent(_shape, _frameNum, 0, 0);
-}
-
 void CruStatGump::saveData(Common::WriteStream *ws) {
 	Gump::saveData(ws);
 }
diff --git a/engines/ultima/ultima8/gumps/cru_stat_gump.h b/engines/ultima/ultima8/gumps/cru_stat_gump.h
index 1a4da94ab3..b960668276 100644
--- a/engines/ultima/ultima8/gumps/cru_stat_gump.h
+++ b/engines/ultima/ultima8/gumps/cru_stat_gump.h
@@ -24,6 +24,7 @@
 #define ULTIMA8_GUMPS_CRUSTATGUMP_H
 
 #include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/gumps/translucent_gump.h"
 #include "ultima/ultima8/misc/p_dynamic_cast.h"
 
 namespace Ultima {
@@ -32,7 +33,7 @@ namespace Ultima8 {
 /**
  * Superclass for the 5 status boxes along the bottom of the screen
  */
-class CruStatGump : public Gump {
+class CruStatGump : public TranslucentGump {
 public:
 	ENABLE_RUNTIME_CLASSTYPE()
 
@@ -43,9 +44,6 @@ public:
 	// Init the gump, call after construction
 	void InitGump(Gump *newparent, bool take_focus = true) override;
 
-	// Paint this Gump
-	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
-
 	bool loadData(Common::ReadStream *rs, uint32 version);
 	void saveData(Common::WriteStream *ws) override;
 };
diff --git a/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
index a38e339309..2c229ff533 100644
--- a/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
@@ -29,8 +29,6 @@
 #include "ultima/ultima8/graphics/shape_frame.h"
 #include "ultima/ultima8/world/actors/main_actor.h"
 #include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/kernel/mouse.h"
-#include "ultima/ultima8/gumps/paperdoll_gump.h"
 #include "ultima/ultima8/world/get_object.h"
 
 namespace Ultima {
diff --git a/engines/ultima/ultima8/gumps/gump.h b/engines/ultima/ultima8/gumps/gump.h
index 2ec7d443cc..57213093cc 100644
--- a/engines/ultima/ultima8/gumps/gump.h
+++ b/engines/ultima/ultima8/gumps/gump.h
@@ -211,6 +211,11 @@ public:
 		_y += y;
 	}
 
+	void getLocation(int32 &x, int32 &y) const {
+		x = _x;
+		y = _y;
+	}
+
 	enum Position {
 		CENTER = 1,
 		TOP_LEFT = 2,
diff --git a/engines/ultima/ultima8/gumps/translucent_gump.cpp b/engines/ultima/ultima8/gumps/translucent_gump.cpp
new file mode 100644
index 0000000000..ea7d25fbc9
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/translucent_gump.cpp
@@ -0,0 +1,49 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/gumps/translucent_gump.h"
+#include "ultima/ultima8/graphics/render_surface.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+DEFINE_RUNTIME_CLASSTYPE_CODE(TranslucentGump)
+TranslucentGump::TranslucentGump() : Gump() {
+}
+
+TranslucentGump::TranslucentGump(int x, int y, int width, int height,
+								 uint16 owner, uint32 flags, int32 layer) :
+	Gump(x, y, width, height, owner, flags ,layer) {
+}
+
+TranslucentGump::~TranslucentGump() {
+}
+
+void TranslucentGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+	if (_shape) {
+		surf->PaintTranslucent(_shape, _frameNum, 0, 0);
+	}
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/translucent_gump.h b/engines/ultima/ultima8/gumps/translucent_gump.h
new file mode 100644
index 0000000000..748788ebe7
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/translucent_gump.h
@@ -0,0 +1,51 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_TRANSLUCENTGUMP_H
+#define ULTIMA8_GUMPS_TRANSLUCENTGUMP_H
+
+#include "ultima/ultima8/gumps/gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * A regular gump that paints itself translucent
+ */
+class TranslucentGump : public Gump {
+public:
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	TranslucentGump();
+	TranslucentGump(int x, int y, int width, int height, uint16 owner = 0,
+	     uint32 flags = 0, int32 layer = LAYER_NORMAL);
+	~TranslucentGump() override;
+
+	// Paint this Gump
+	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/widgets/text_widget.h b/engines/ultima/ultima8/gumps/widgets/text_widget.h
index 709e222e82..cd46c3abf0 100644
--- a/engines/ultima/ultima8/gumps/widgets/text_widget.h
+++ b/engines/ultima/ultima8/gumps/widgets/text_widget.h
@@ -93,6 +93,10 @@ public:
 	//! get the RenderedText's vlead
 	int getVlead();
 
+	const Std::string &getText() const {
+		return _text;
+	}
+
 protected:
 	void renderText();
 
diff --git a/engines/ultima/ultima8/world/actors/main_actor.cpp b/engines/ultima/ultima8/world/actors/main_actor.cpp
index dedcb097cd..f170fab4be 100644
--- a/engines/ultima/ultima8/world/actors/main_actor.cpp
+++ b/engines/ultima/ultima8/world/actors/main_actor.cpp
@@ -37,6 +37,7 @@
 #include "ultima/ultima8/games/game_data.h"
 #include "ultima/ultima8/graphics/wpn_ovlay_dat.h"
 #include "ultima/ultima8/graphics/shape_info.h"
+#include "ultima/ultima8/gumps/cru_pickup_area_gump.h"
 #include "ultima/ultima8/audio/audio_process.h"
 #include "ultima/ultima8/world/world.h"
 #include "ultima/ultima8/world/get_object.h"
@@ -130,6 +131,9 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 	int32 x, y, z;
 	getLocation(x, y, z);
 
+	CruPickupAreaGump *pickupArea = CruPickupAreaGump::get_instance();
+	assert(pickupArea);
+
 	if (shapeno == 0x4ed) {
 		Item *credits = getFirstItemWithShape(shapeno, true);
 		if (credits) {
@@ -139,18 +143,16 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 				newq = 64000;
 			credits->setQuality(newq);
 			credits->callUsecodeEvent_combine();
-			if (showtoast) {
-				warning("TODO: show toast for added credits %d", q);
-			}
+			if (showtoast)
+				pickupArea->addPickup(item);
 			item->destroy();
 		} else {
 			item->setFrame(0);
 			item->moveToContainer(this);
 			if (!_activeInvItem)
 				_activeInvItem = item->getObjId();
-			if (showtoast) {
-				warning("TODO: show toast for new credits %d", item->getQuality());
-			}
+			if (showtoast)
+				pickupArea->addPickup(item);
 		}
 		return 1;
 	}
@@ -175,7 +177,7 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 				_activeWeapon = item->getObjId();
 			warning("TODO: Set new weapon as active weapon if there is none");
 			if (showtoast)
-				warning("TODO: Show toast for new weapon %d", shapeno);
+				pickupArea->addPickup(item);
 		}
 		break;
 	}
@@ -187,7 +189,7 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 			item->callUsecodeEvent_combine();
 			item->moveToContainer(this);
 			if (showtoast)
-				warning("TODO: Show toast for new ammo %d", shapeno);
+				pickupArea->addPickup(item);
 			return 1;
 		} else {
 			// already have this, add some ammo.
@@ -196,7 +198,7 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 				ammo->setQuality(q + 1);
 				ammo->callUsecodeEvent_combine();
 				if (showtoast)
-					warning("TODO: Show toast for combined ammo %d (%d)", shapeno, q + 1);
+					pickupArea->addPickup(item);
 				item->destroy();
 				return 1;
 			}
@@ -208,15 +210,14 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 		if (shapeno == 0x111) {
 			addKeycard(item->getQuality() & 0xff);
 			if (showtoast) {
-				warning("TODO: show toast for added keycard %d", item->getQuality() & 0xff);
+				pickupArea->addPickup(item);
 			}
 			item->destroy();
 			return 1;
 		} else if ((shapeno == 0x3a2) || (shapeno == 0x3a3) || (shapeno == 0x3a4)) {
 			// Batteries
-			if (showtoast) {
-				warning("TODO: show toast for added battery %d", shapeno);
-			}
+			if (showtoast)
+				pickupArea->addPickup(item);
 			item->destroy();
 			int plusenergy = 0;
 			CruBatteryType oldbattery = _cruBatteryType;
@@ -256,11 +257,9 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 					item->setFrame(0);
 					item->setQuality(1);
 					item->callUsecodeEvent_combine();
-					bool added = item->moveToContainer(this);
-					if (showtoast) {
-						warning("TODO: show toast new item %d (%s)",
-								shapeno, added ? "added" : "failed");
-					}
+					item->moveToContainer(this);
+					if (showtoast)
+						pickupArea->addPickup(item);
 					if (!_activeInvItem)
 						_activeInvItem = item->getObjId();
 					return 1;
@@ -276,9 +275,8 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 					if (q < 0x14) {
 						existing->setQuality(q + 1);
 						existing->callUsecodeEvent_combine();
-						if (showtoast) {
-							warning("TODO: show toast for combined cru spider q=%d", q + 1);
-						}
+						if (showtoast)
+							pickupArea->addPickup(item);
 						item->destroy();
 						return 1;
 					}
@@ -287,9 +285,8 @@ int16 MainActor::addItemCru(Item *item, bool showtoast) {
 					if (q < 10) {
 						existing->setQuality(q + 1);
 						existing->callUsecodeEvent_combine();
-						if (showtoast) {
-							warning("TODO: show toast for combined other item %d q=%d", shapeno, q + 1);
-						}
+						if (showtoast)
+							pickupArea->addPickup(item);
 						item->destroy();
 						return 1;
 					}
diff --git a/engines/ultima/ultima8/world/weapon_info.h b/engines/ultima/ultima8/world/weapon_info.h
index b4c69aed42..8431bd7806 100644
--- a/engines/ultima/ultima8/world/weapon_info.h
+++ b/engines/ultima/ultima8/world/weapon_info.h
@@ -43,7 +43,8 @@ struct WeaponInfo {
 
 	// Crusader-specific fields:
 	uint16 _sound;		//!< The sound this weapon makes when fired
-	uint16 _ammoType;	//!< The type of ammo it uses
+	uint16 _ammoType;	//!< The inventory frame for the ammo used
+	uint16 _ammoShape;	//!< The shape number for the ammo used
 	uint16 _displayFrame;	//!< The frame to use in the inventory gump
 
 	enum DmgType {


Commit: 51ee9991bdc0f41197a358d9d897a413cea9caff
    https://github.com/scummvm/scummvm/commit/51ee9991bdc0f41197a358d9d897a413cea9caff
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-06T16:27:16+09:00

Commit Message:
ULTIMA8: Display crusader item data from ini file

Changed paths:
  A engines/ultima/ultima8/gumps/cru_display_shapes.h
    devtools/create_ultima/files/ultima8/remorse.ini
    devtools/create_ultima/files/ultima8/remorseweapons.ini
    engines/ultima/ultima8/conf/ini_file.cpp
    engines/ultima/ultima8/conf/ini_file.h
    engines/ultima/ultima8/games/game_data.cpp
    engines/ultima/ultima8/graphics/type_flags.cpp
    engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
    engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
    engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
    engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
    engines/ultima/ultima8/gumps/cru_pickup_gump.h
    engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
    engines/ultima/ultima8/world/weapon_info.h


diff --git a/devtools/create_ultima/files/ultima8/remorse.ini b/devtools/create_ultima/files/ultima8/remorse.ini
index fa57957ac5..b2c1d09718 100644
--- a/devtools/create_ultima/files/ultima8/remorse.ini
+++ b/devtools/create_ultima/files/ultima8/remorse.ini
@@ -1,2 +1,4 @@
 [fontleads]
 6=0,3
+12=0,1
+13=-1,1
diff --git a/devtools/create_ultima/files/ultima8/remorseweapons.ini b/devtools/create_ultima/files/ultima8/remorseweapons.ini
index b7464a8bb8..504ed1b04c 100644
--- a/devtools/create_ultima/files/ultima8/remorseweapons.ini
+++ b/devtools/create_ultima/files/ultima8/remorseweapons.ini
@@ -1,77 +1,239 @@
+# Actual weapons
 [BA-40]
 shape=0x032E
 sound=0x2C
 ammo_type=0
 damage_type=0x0B
+display_shape=3
+display_frame=2
 
 [BA-41]
 shape=0x032F
 sound=0x2C
 ammo_type=1
 damage_type=0x0B
+display_shape=3
+display_frame=1
 
 [PA-21]
 shape=0x0330
 sound=0x8
 ammo_type=0
 damage_type=0x05
+display_shape=3
+display_frame=7
 
 [EM-4]
 shape=0x038C
 sound=0x43
 ammo_type=0
 damage_type=0x0F
+display_shape=3
+display_frame=3
 
 [SG-A1]
 shape=0x0332
 sound=0x55
 ammo_type=2
 damage_type=0x02
+display_shape=3
+display_frame=0
 
 [RP-22]
 shape=0x0333
 sound=0x2C
 ammo_type=3
 damage_type=0x01
+display_shape=3
+display_frame=6
 
 [RP-32]
 shape=0x0334
 sound=0x2C
 ammo_type=3
 damage_type=0x01
+display_shape=3
+display_frame=5
 
 [AR-7]
 shape=0x038E
 sound=0x2C
 ammo_type=4
 damage_type=0x0A
+display_shape=3
+display_frame=0xC
 
 [GL-303]
 shape=0x0388
 sound=0x64
 ammo_type=5
 damage_type=0x03
+display_shape=3
+display_frame=8
 
 [PA-31]
 shape=0x038A
 sound=0x2
 ammo_type=0
 damage_type=0x05
+display_shape=3
+display_frame=9
 
 [PL-1]
 shape=0x038D
 sound=0x47
 ammo_type=0
 damage_type=0x06
+display_shape=3
+display_frame=0xA
 
 [AC-88]
 shape=0x038B
 sound=0x55
 ammo_type=2
 damage_type=0x0D
+display_shape=3
+display_frame=4
 
 [UV-9]
 shape=0x0386
 sound=0x89
 ammo_type=0
 damage_type=0x0E
+display_shape=3
+display_frame=0xB
+
+# Ammo
+[BA-41 CLIP]
+shape=0x033D
+display_shape=5
+display_frame=0x8
+
+[SG-A1 CLIP]
+shape=0x033E
+display_shape=5
+display_frame=0x9
+
+[RP-22 CLIP]
+shape=0x033F
+display_shape=5
+display_frame=0xA
+
+[AR-7 CLIP]
+shape=0x0340
+display_shape=5
+display_frame=0xB
+
+[GL-303 CLIP]
+shape=0x0341
+display_shape=5
+display_frame=0xC
+
+
+# Bombs, grenades, etc..
+[GRENADE]
+shape=0x0343
+display_shape=4
+display_frame=0
+
+[CONCUSSION GRENADE]
+shape=0x034E
+display_shape=4
+display_frame=1
+
+[NERVE GAS GRENADE]
+shape=0x034F
+display_shape=4
+display_frame=2
+
+[EMP GRENADE]
+shape=0x0350
+display_shape=4
+display_frame=3
+
+[SPIDER BOMB]
+shape=0x0560
+display_shape=4
+display_frame=4
+
+[LAND MINE]
+shape=0x039A
+display_shape=4
+display_frame=5
+
+[BLAST PAC]
+shape=0x039B
+display_shape=4
+display_frame=7
+
+[FUSION PAC]
+shape=0x039C
+display_shape=4
+display_frame=6
+
+
+# Other inventory items
+[MEDICAL KIT]
+shape=0x351
+display_shape=5
+display_frame=0
+
+[DATA LINK]
+shape=0x4D4
+display_shape=5
+display_frame=1
+
+[INHIBITOR]
+shape=0x52D
+display_shape=5
+display_frame=2
+
+[IONIC GENERATOR]
+shape=0x52E
+display_shape=5
+display_frame=3
+
+[ENERGY CUBE]
+shape=0x582
+display_shape=5
+display_frame=0x19
+
+[PLASMA GENERATOR]
+shape=0x52F
+display_shape=5
+display_frame=5
+
+[DET PAC]
+shape=0x55F
+display_shape=5
+display_frame=0x18
+
+[GRAVITON GENERATOR]
+shape=0x530
+display_shape=5
+display_frame=7
+
+[CHEMICAL BATTERY]
+shape=0x3A2
+display_shape=5
+display_frame=0x16
+
+[FUSION BATTERY]
+shape=0x3A3
+display_shape=5
+display_frame=0x15
+
+[FISSION BATTERY]
+shape=0x3A4
+display_shape=5
+display_frame=0x17
+
+# Other special case items
+[CREDITS]
+shape=0x4ED
+display_shape=3
+display_frame=0xC
+
+[KEYCARD]
+shape=0x111
+display_shape=5
diff --git a/engines/ultima/ultima8/conf/ini_file.cpp b/engines/ultima/ultima8/conf/ini_file.cpp
index 68387f5d50..20829f8f4b 100644
--- a/engines/ultima/ultima8/conf/ini_file.cpp
+++ b/engines/ultima/ultima8/conf/ini_file.cpp
@@ -93,7 +93,7 @@ string INIFile::Section::dump() {
 	return s;
 }
 
-bool INIFile::readConfigFile(string fname) {
+bool INIFile::readConfigFile(const string &fname) {
 	IDataSource *f = FileSystem::get_instance()->ReadFile(fname, true);
 	if (!f) return false;
 
@@ -183,7 +183,7 @@ bool INIFile::readConfigString(string config) {
 			// is, verify that it only consists of alphanumerics,
 			// dashes, underscores and colons).
 			while (p < line.size() && (Common::isAlnum(line[p]) || line[p] == '-' ||
-			                           line[p] == '_' || line[p] == ':'))
+			                           line[p] == '_' || line[p] == ':' || line[p] == ' '))
 				p++;
 
 			if (p >= line.size()) {
diff --git a/engines/ultima/ultima8/conf/ini_file.h b/engines/ultima/ultima8/conf/ini_file.h
index 1ab901078c..db2e268be3 100644
--- a/engines/ultima/ultima8/conf/ini_file.h
+++ b/engines/ultima/ultima8/conf/ini_file.h
@@ -36,7 +36,7 @@ public:
 	INIFile(Std::string fname, istring root);
 	~INIFile();
 
-	bool readConfigFile(Std::string fname);
+	bool readConfigFile(const Std::string &fname);
 
 	//! read configuration from a string s. Lines must be separated by \n
 	bool readConfigString(Std::string s);
diff --git a/engines/ultima/ultima8/games/game_data.cpp b/engines/ultima/ultima8/games/game_data.cpp
index 2e7cdbfc9f..e3e307d1e1 100644
--- a/engines/ultima/ultima8/games/game_data.cpp
+++ b/engines/ultima/ultima8/games/game_data.cpp
@@ -539,9 +539,9 @@ void GameData::loadRemorseData() {
 	                                  &CrusaderShapeFormat);
 
 	ConfigFileManager *config = ConfigFileManager::get_instance();
-#if 0
 	// Load weapon, armour info
-	config->readConfigFile("@data/u8weapons.ini", "weapons", true);
+	config->readConfigFile("@data/remorseweapons.ini", "weapons", true);
+#if 0
 	config->readConfigFile("@data/u8armour.ini", "armour", true);
 	config->readConfigFile("@data/u8monsters.ini", "monsters", true);
 #endif
diff --git a/engines/ultima/ultima8/graphics/type_flags.cpp b/engines/ultima/ultima8/graphics/type_flags.cpp
index 9189e6e140..2b3b746ba9 100644
--- a/engines/ultima/ultima8/graphics/type_flags.cpp
+++ b/engines/ultima/ultima8/graphics/type_flags.cpp
@@ -198,7 +198,8 @@ void TypeFlags::loadWeaponInfo() {
 
 		int val = 0;
 
-		wi->_name = k;
+		// Slight hack.. get the name after the the /
+		wi->_name = k.substr(k.findLastOf('/') + 1, Std::string::npos);
 
 		config->get(k + "/shape", val);
 		wi->_shape = static_cast<uint32>(val);
@@ -256,9 +257,14 @@ void TypeFlags::loadWeaponInfo() {
 			wi->_sound = 0;
 
 		if (config->get(k + "/display_frame", val))
-			wi->_displayFrame = static_cast<uint16>(val);
+			wi->_displayGumpFrame = static_cast<uint16>(val);
 		else
-			wi->_displayFrame = 0;
+			wi->_displayGumpFrame = 0;
+
+		if (config->get(k + "/display_shape", val))
+			wi->_displayGumpShape = static_cast<uint16>(val);
+		else
+			wi->_displayGumpShape = 3;
 
 		assert(wi->_shape < _shapeInfo.size());
 		_shapeInfo[wi->_shape]._weaponInfo = wi;
diff --git a/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
index 226e8b445e..0227ad7e86 100644
--- a/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_ammo_gump.cpp
@@ -35,8 +35,6 @@
 namespace Ultima {
 namespace Ultima8 {
 
-static const int AMMO_GUMP_SHAPE = 2;
-
 DEFINE_RUNTIME_CLASSTYPE_CODE(CruAmmoGump)
 
 CruAmmoGump::CruAmmoGump() : CruStatGump() {
diff --git a/engines/ultima/ultima8/gumps/cru_display_shapes.h b/engines/ultima/ultima8/gumps/cru_display_shapes.h
new file mode 100644
index 0000000000..f872273a02
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/cru_display_shapes.h
@@ -0,0 +1,63 @@
+/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_CRUINVENTORYGUMP_H
+#define ULTIMA8_GUMPS_CRUINVENTORYGUMP_H
+
+#include "ultima/ultima8/gumps/cru_stat_gump.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class TextWidget;
+
+/**
+ * Inventory box, the 3rd box along the bottom of the screen
+ */
+class CruInventoryGump : public CruStatGump {
+public:
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	CruInventoryGump();
+	CruInventoryGump(Shape *shape, int x);
+	~CruInventoryGump() override;
+
+	// Init the gump, call after construction
+	void InitGump(Gump *newparent, bool take_focus = true) override;
+
+	// Paint this Gump
+	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+private:
+	Shape *_inventoryShape;
+	Gump *_inventoryItemGump;
+	TextWidget *_inventoryText;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
index 29a7e9aead..437cfe960c 100644
--- a/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_inventory_gump.cpp
@@ -135,7 +135,7 @@ void CruInventoryGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool sc
 				const Std::string &currenttext = _inventoryText->getText();
 				if (!qtext.equals(currenttext)) {
 					RemoveChild(_inventoryText);
-					_inventoryText = new TextWidget(_dims.w / 2 + 22, _dims.h / 2 + 3, qtext, true, 12);
+					_inventoryText = new TextWidget(_dims.w / 2 + 22, _dims.h / 2 + 3, qtext, true, INVENTORY_TEXT_FONT);
 					_inventoryText->InitGump(this, false);
 				}
 			} else {
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
index a498734f7e..6b8894fcd2 100644
--- a/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_pickup_area_gump.cpp
@@ -51,7 +51,6 @@ void CruPickupAreaGump::addPickup(Item *item) {
 
 	uint32 shapeno = item->getShape();
 
-	// TODO: This is not quite right.  We want to add the "q" values of the existing one and the new one.  Eg, if we have 5 medikits and add 2, we should show "2" in the toast.
 	Std::list<Gump *>::iterator it;
 	int32 yoff = 0;
 	uint16 qval = 0;
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp b/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
index f91ae9e4bd..36fe39dab7 100644
--- a/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_pickup_gump.cpp
@@ -43,17 +43,28 @@ static const int ITEM_TEXT_FONT = 13;
 static const int ITEM_AREA_WIDTH = 60;
 
 DEFINE_RUNTIME_CLASSTYPE_CODE(CruPickupGump)
-CruPickupGump::CruPickupGump() : Gump(), _startFrame(0), _shapeno(0), _q(0) {
-
+CruPickupGump::CruPickupGump() : Gump(), _startFrame(0), _itemShapeNo(0), _q(0),
+	_gumpShapeNo(0), _gumpFrameNo(0) {
 }
 
 CruPickupGump::CruPickupGump(Item *item, int y, uint16 currentq) : Gump(0, y, 5, 5, 0), _startFrame(0) {
-	_shapeno = item->getShape();
-	_q = item->getQuality();
-	// TODO: should we add current q? + currentq;
-	// It seems like the items are hacked to give the right "q" for
-	// this gump from the last item, which is why the add process
-	// uses q + 1 instead of adding the new q.
+	const WeaponInfo *weaponInfo = item->getShapeInfo()->_weaponInfo;
+	if (weaponInfo) {
+		_itemShapeNo = item->getShape();
+		_q = item->getQuality();
+		// TODO: should we add current q? + currentq;
+		// It seems like the items are hacked to give the right "q" for
+		// this gump from the last item, which is why the add process
+		// uses q + 1 instead of adding the new q.
+		_itemName = weaponInfo->_name;
+		_gumpShapeNo = weaponInfo->_displayGumpShape;
+		_gumpFrameNo = weaponInfo->_displayGumpFrame;
+	} else {
+		_itemShapeNo = 0;
+		_q = 0;
+		_gumpShapeNo = 0;
+		_gumpFrameNo = 0;
+	}
 }
 
 CruPickupGump::~CruPickupGump() {
@@ -62,19 +73,11 @@ CruPickupGump::~CruPickupGump() {
 void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
 	Gump::InitGump(newparent, take_focus);
 
-	if (!_shapeno)
+	if (!_itemShapeNo)
 		return;
 
 	_startFrame = Kernel::get_instance()->getFrameNum();
 
-	// TODO: Get the appropriate name, shape, and frame for the item here.
-	Std::string itemname = "MEDICAL KIT";
-	// The gump shape no for the item (not the no. of the item itself)
-	// Eg, weapons are gumpshape 3, other items are gumpshape 5, etc.
-	uint32 itemshapeno = 5;
-	// The frame within that gump shape
-	uint32 itemframeno = 0;
-
 	// Get the shapes we will need..
 	GumpShapeArchive *gumpshapes = GameData::get_instance()->getGumps();
 	if (!gumpshapes) {
@@ -89,8 +92,8 @@ void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
 	}
 	const ShapeFrame *bgframe = background->getFrame(0);
 
-	Shape* itemshape = gumpshapes->getShape(itemshapeno);
-	if (!itemshape || !itemshape->getFrame(itemframeno)) {
+	Shape* itemshape = gumpshapes->getShape(_gumpShapeNo);
+	if (!itemshape || !itemshape->getFrame(_gumpFrameNo)) {
 		warning("failed to init stat gump: no item shape");
 		return;
 	}
@@ -107,7 +110,7 @@ void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
 	_dims.h = bgframe->_height;
 
 	// Paint the item name text
-	TextWidget *text = new TextWidget(ITEM_AREA_WIDTH, bgframe->_height / 2, itemname, true, ITEM_TEXT_FONT);
+	TextWidget *text = new TextWidget(ITEM_AREA_WIDTH, bgframe->_height / 2 - 5, _itemName, true, ITEM_TEXT_FONT);
 	text->InitGump(this, false);
 
 	// Paint the count if needed
@@ -118,9 +121,9 @@ void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
 	}
 
 	// Paint the item in the mid-left item area.
-	const ShapeFrame *itemframe = itemshape->getFrame(itemframeno);
+	const ShapeFrame *itemframe = itemshape->getFrame(_gumpFrameNo);
 	Gump *itemgump = new Gump(0, _dims.h / 2 - itemframe->_height / 2, itemframe->_width, itemframe->_height, 0, 0, LAYER_ABOVE_NORMAL);
-	itemgump->SetShape(itemshape, itemframeno);
+	itemgump->SetShape(itemshape, _gumpFrameNo);
 	itemgump->InitGump(this, false);
 	itemgump->UpdateDimsFromShape();
 	itemgump->Move(ITEM_AREA_WIDTH / 2 - itemframe->_width / 2, _dims.h / 2 - itemframe->_height / 2);
@@ -128,7 +131,7 @@ void CruPickupGump::InitGump(Gump *newparent, bool take_focus) {
 
 void CruPickupGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
 	uint32 frameno = Kernel::get_instance()->getFrameNum();
-	if (!_shapeno || frameno - _startFrame > 90) {
+	if (!_itemShapeNo || frameno - _startFrame > 90) {
 		Close();
 		return;
 	}
diff --git a/engines/ultima/ultima8/gumps/cru_pickup_gump.h b/engines/ultima/ultima8/gumps/cru_pickup_gump.h
index ead01f121b..c49d4120bd 100644
--- a/engines/ultima/ultima8/gumps/cru_pickup_gump.h
+++ b/engines/ultima/ultima8/gumps/cru_pickup_gump.h
@@ -51,7 +51,7 @@ public:
 	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
 
 	uint32 getShapeNo() const {
-		return _shapeno;
+		return _itemShapeNo;
 	}
 
 	uint16 getQ() {
@@ -63,7 +63,10 @@ public:
 
 private:
 	uint32 _startFrame;
-	uint32 _shapeno;
+	uint32 _itemShapeNo;
+	uint16 _gumpShapeNo;
+	uint16 _gumpFrameNo;
+	Std::string _itemName;
 	uint16 _q;
 };
 
diff --git a/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
index 2c229ff533..36002447e1 100644
--- a/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
+++ b/engines/ultima/ultima8/gumps/cru_weapon_gump.cpp
@@ -90,7 +90,9 @@ void CruWeaponGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scale
 			WeaponInfo *weaponinfo = item->getShapeInfo()->_weaponInfo;
 			uint16 frameno = 0;
 			if (weaponinfo) {
-				frameno = weaponinfo->_displayFrame;
+				// this should be a weapon, otherwise why are we here?
+				assert(WEAPON_GUMP_SHAPE == weaponinfo->_displayGumpShape);
+				frameno = weaponinfo->_displayGumpFrame;
 			}
 			_weaponGump->SetShape(_weaponShape, frameno);
 			_weaponGump->UpdateDimsFromShape();
diff --git a/engines/ultima/ultima8/world/weapon_info.h b/engines/ultima/ultima8/world/weapon_info.h
index 8431bd7806..85b2a7287d 100644
--- a/engines/ultima/ultima8/world/weapon_info.h
+++ b/engines/ultima/ultima8/world/weapon_info.h
@@ -45,7 +45,8 @@ struct WeaponInfo {
 	uint16 _sound;		//!< The sound this weapon makes when fired
 	uint16 _ammoType;	//!< The inventory frame for the ammo used
 	uint16 _ammoShape;	//!< The shape number for the ammo used
-	uint16 _displayFrame;	//!< The frame to use in the inventory gump
+	uint16 _displayGumpShape; //! The gump shape to use for inventory display (3,4,5)
+	uint16 _displayGumpFrame; //!< The frame to use in the inventory gump
 
 	enum DmgType {
 		DMG_NORMAL = 0x0001,


Commit: 5f34a083fa1bc6522015175158c1d922aa73e24d
    https://github.com/scummvm/scummvm/commit/5f34a083fa1bc6522015175158c1d922aa73e24d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-07-06T16:27:20+09:00

Commit Message:
ULTIMA8: Fix null check that was backwards

Changed paths:
    engines/ultima/ultima8/world/target_reticle_process.cpp


diff --git a/engines/ultima/ultima8/world/target_reticle_process.cpp b/engines/ultima/ultima8/world/target_reticle_process.cpp
index 4103e82760..2e1023c6ab 100644
--- a/engines/ultima/ultima8/world/target_reticle_process.cpp
+++ b/engines/ultima/ultima8/world/target_reticle_process.cpp
@@ -143,7 +143,7 @@ void TargetReticleProcess::itemMoved(Item *item) {
 	MainActor *mainactor = getMainActor();
 	int actordir = -1;
 	int dirtoitem = -2;
-	if (!mainactor) {
+	if (mainactor) {
 		actordir = mainactor->getDir();
 		dirtoitem = mainactor->getDirToItemCentre(*item);
 	}




More information about the Scummvm-git-logs mailing list