Maniac Mansion Mania Forum
MMM-Werkzeugkiste => Technik => Thema gestartet von: Cone Arex am 11. August 2014, 12:20:26
-
Wenn man gMaingui.Visible = false setzt, crasht das Spiel wenn das Inventory nach oben gescrollt werden kann, also mindestens 9 Gegenstände hat und man auf der zweiten Seite ist.
AGS verweist auf eine Nullpointer-Referenz in diesem Code in der repeatedley_execute()-Funktion des Global Scripts:
[ags]if (invItem.ID < 0)
gMainInventory.ScrollUp();[/ags]
Getestet in den Bernard- und Kevin-SPs.
Ich kenne den Code vom Global Script leider so gut wie gar nicht und kann es daher auch nicht selbst beheben.
EDIT: Ich bin ein solcher Vollspast. SEKUNDEN nach dem Post habe ich ein Fix gefunden: Den obigen Code in einen if-Block packen und abfragen, ob gMaingui sichtbar ist. Falls jemand eine bessere bzw. saubere Methode hat, immer her damit.
-
Ich hatte beim Mansion-SP (AGS 3.2.1) auch mal einen Bug der mit dem Inventar zusammen hing. Es wurden die Scrollpfeile immer angezeigt, auch wenn das Inventar vorher völlig leer geräumt wurde (weil der Character all sein Zeug verloren hat). Wenn man dann ein neues Item bekam wurde es nicht direkt angezeigt sondern man musste erst im sonst völlig leerem Inventory einmal hochscrollen. Und am Ende des Spiels stürzte AGS ab und AGS mekerte ebenfalls über eine Nullpointer-Referenz im Zusammenhang mit dem Inventar.
Gelöst habe ich es mit der freundlichen Unterstützung eines Community-Mitglieds welcher mir folgenden Code gab. Man muss einen Teil der repeatedley_execute()-Funktion durch diesen Code ersetzen.
[ags]
InvWindow *invMain = gMainInventory;
if (invMain.ItemAtIndex[0] != null)
{
if (gMainInventory.TopItem != 0)
{
// if inventory can scroll up
int visible_items = (invMain.Width / invMain.ItemWidth) * (invMain.Height / invMain.ItemHeight);
if (invMain.ItemCount > visible_items) gMainInvUp.NormalGraphic = invUparrowONsprite;
InventoryItem *invItem = InventoryItem.GetAtScreenXY(180, 190);
if (invItem == null)
gMainInventory.ScrollUp();
}
else
gMainInvUp.NormalGraphic = invUparrowOFFsprite;
}
else gMainInvUp.NormalGraphic = invUparrowOFFsprite;
[/ags]
Danach sieht die neue GESAMTE repeatedley_execute()-Funktion wie folgt aus:
[ags]
function repeatedly_execute ()
{
DisplaySpeechQ_RE(); // place it before any other script code in rep. exec.
if (IsGamePaused () != 1)
{
CheckTimers ();
InventoryItem *invAt = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
// --- for the MovePlayer function ---
if (GScancelable == 1)
{
GScancelable = 0;
if ( null == invAt ) on_mouse_click (eMouseLeft);
else on_mouse_click (eMouseLeftInv);
}
else if (GScancelable == 2)
{
GScancelable = 0;
CheckDefaultAction ();
if ( null == invAt ) on_mouse_click (eMouseRight);
else on_mouse_click (eMouseRightInv);
}
CheckDefaultAction ();
UpdateActionBar ();
}
// change the arrows in the inventory to show if you
// can scroll the inventory:
//readonly InventoryItem* InvWindow.ItemAtIndex[];
InvWindow *invMain = gMainInventory;
if (invMain.ItemAtIndex[0] != null)
{
if (gMainInventory.TopItem != 0)
{
// if inventory can scroll up
int visible_items = (invMain.Width / invMain.ItemWidth) * (invMain.Height / invMain.ItemHeight);
if (invMain.ItemCount > visible_items) gMainInvUp.NormalGraphic = invUparrowONsprite;
InventoryItem *invItem = InventoryItem.GetAtScreenXY(180, 190);
if (invItem == null)
gMainInventory.ScrollUp();
}
else
gMainInvUp.NormalGraphic = invUparrowOFFsprite;
}
else gMainInvUp.NormalGraphic = invUparrowOFFsprite;
if ((gMainInventory.TopItem + (gMainInventory.ItemsPerRow * gMainInventory.RowCount)) < gMainInventory.ItemCount)
gMainInvDown.NormalGraphic = invDownarrowONsprite;
else
gMainInvDown.NormalGraphic = invDownarrowOFFsprite;
}
[/ags]
Vor dem beenden des Spiels habe ich das Inventar mit folgendem Code zur Sicherheit nochmal komplett leer geräumt (da GUI und Inventar sowieso ausgeblendet waren merkt es keiner):
[ags]
int i = 1;
while (i <= Game.InventoryItemCount) {
player.InventoryQuantity = 0;
i++;
}
UpdateInventory();
[/ags]
So konnte ich gut die besagten Probleme lösen. Welche Lösung nun besser ist muss jeder selber entscheiden, da bei mir noch das "Pfeilproblem" mit gelöst wurde.