Maniac Mansion Mania Forum
MMM-Werkzeugkiste => Technik => Thema gestartet von: FrasierCrane am 14. August 2008, 00:00:26
-
Ich wollte fragen, ob es irgendeine Möglichkeit gibt, dass der Spielercharakter mit der Umgebung interagiert (z.B.: sein Inventar benützt), während er gerade geht; also dass die Maus während des Walk-Befehls verwendet werden kann. Hab leider nix dazu gefunden. Danke im vorraus.
-
player.Walk(x, y, eNoBlock)
lässt die figur nach x/y laufen, ohne das das skript blockiert wird
aber wenn du wissen willst, ob die figur auch x/y erreicht hat, solltest du folgende funktion verwenden
MovePlayer(X, Y)
diese funktion lässt das skript an dieser stelle warten bis entweder die figur X/Y erreicht hat (rückgabewert 1), oder mit der maus eine andere aktion ausgeführt wurde (rückgabewert 0)
ich weiß allerdings nicht, wie diese funktion auf GUI-interaktionen reagiert :-\
-
Ja, das hab ich auch schon probiert. Das Script läuft dabei zwar weiter, aber die Maus wird trotzdem blockiert und es sind keine Interaktionen möglich.
-
also bei mir klappt MovePlayer tadellos (mit AGS3.0.2 SP1) :-\
wird das MovePlayer aber während einer aktion wie "benutze" ausgeführt, ist das befehls-gui nicht aktiv, die standardaktionen mit der rechten maustaste gehen aber
auch mit inventory items geht es
aber dabei ist mir ein massiver bug in ALLEN starterpacks aufgefallen (wenn es nicht sogar ein AGS bug ist)
wenn man noch nie mit einem inventory interagiert hat und während einem MovePlayer (das während "benutze" objekt läuft) mit der rechten maustaste auf ein inventory item klickt, geht das spiel mit einem fatalen ags-fehler baden :o
hat man schonmal mit einem inventory item interagiert, kommt einfach die zuletzt verwendete aktion
muss mir bei gelegenheit mal ansehen, woran das genau liegt ;)
-
hab den fehler mal genauer unter die lupe genommen und festgestellt, dass StopPlayer in MovePlayerEx den fehler auslöst
function MovePlayerEx (int x, int y, int direct){
// Move the player character to x,y coords, waiting until he/she gets there,
// but allowing to cancel the action by pressing a mouse button.
if (GetGlobalInt (2) > 0)
{
int cursorspritenumber = 16,
blankcursorspritenumber = 26;
ChangeCursorGraphic (7, cursorspritenumber);
GScancelable = 0;
if (direct == 0) MoveCharacter (GetPlayerCharacter (), x, y);
else MoveCharacterDirect (GetPlayerCharacter (), x, y);
// wait for release of mouse button
while (character [GetPlayerCharacter ()].walking && ((IsButtonDown (LEFT) == 1) || (IsButtonDown (RIGHT) == 1)))
{
GScancelable = RepExec_Hunting ();
Wait (1);
RefreshMouse ();
CheckDefaultAction ();
}
// abort moving on new mouse down
while (character [GetPlayerCharacter ()].walking)
{
GScancelable = RepExec_Hunting ();
if (IsButtonDown (LEFT) == 1 && (GetGUIAt (mouse.x, mouse.y) < 0 || GetInvAt (mouse.x, mouse.y) >= 0))
{
StopMoving (GetPlayerCharacter ());
GScancelable = 1;
}
else if (IsButtonDown (RIGHT) == 1 && (GetGUIAt (mouse.x, mouse.y) < 0 || GetInvAt (mouse.x, mouse.y) >= 0))
{
StopMoving (GetPlayerCharacter ()); // <== HIER TRITT DER FEHLER AUF!!!
GScancelable = 2;
}
else
{
Wait (1);
RefreshMouse ();
CheckDefaultAction ();
}
}
ChangeCursorGraphic (7, blankcursorspritenumber);
if (GScancelable == 0) return 1;
else return 0;
}
else return 0;
}
-
Danke für deine Hilfe Boogieman, aber das mit dem MovePlayer funktioniert bei mir irgendwie auch nicht. Die Maus ist zwar da, aber im Inventory kann man immer noch nix anklicken und benutzen
-
ok, nachdem ich endlich AGS beigebracht habe, dass es im debug modus auch bei breakpoints stehen bleibt, konnte ich den fehler noch tiefer verfolgen
wie auch rulaman festgestellt hat, tritt der fehler in dieser funktion auf:
function on_mouse_click (int button){
...
else if (button == RIGHTINV)
{
if (alternative_action == A_DEFAULT)
{
SetAction (A_DEFAULT);
}
else
{
SetAction (alternative_action);
used_action = global_action;
GSagsusedmode = GetCursorMode ();
if (GetCursorMode () == 2)
{
if (isAction (A_USE) && IsInventoryInteractionAvailable (GSlocid, MODE_USE) == 1)
{
UpdateActionBar ();
SetLabelColor (ACTION, 0, ActionLabelColorHighlighted);
RunInventoryInteraction (GSlocid, MODE_USE);
SetAction (A_DEFAULT);
}
else SetActiveInventory (GSlocid);
}
else
{
UpdateActionBar ();
SetLabelColor (ACTION, 0, ActionLabelColorHighlighted);
if(game.inv_activated != 0) // <=== BUGFIX
RunInventoryInteraction (game.inv_activated, GetCursorMode ());
SetAction (A_DEFAULT);
}
}
}
}
game.inv_activated ist 0, wenn vorher noch nie ein inventory item aktiviert wurde
in diesem fall wird durch die if einfach nix gemacht anstatt abzustürzen ;)
bleibt aber immer noch das problem, dass wenn man schon vorher ein inventory item aktiviert hat, man die aktion für dieses item ausführt anstatt für das gewünschte item :-\
ist deine lösung da besser rulaman?
-
Bei mir sieht das Ganze so aus:
function on_mouse_click (int button){
// called when a mouse button is clicked. button is either LEFT or RIGHT
...
invAt = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); <-- WICHTIG!!!
...
else if (button == eMouseRightInv)
{
if (alternative_action == eActDefault)
{
SetAction (eActDefault);
}
else
{
SetAction (alternative_action);
used_action = global_action;
GSagsusedmode = Mouse.Mode;
if (Mouse.Mode == 2)
{
if (isAction (eActUse) && invAt.IsInteractionAvailable(eModeUseinv) == 1)
{
UpdateActionBar ();
gAktionText.TextColor = ActionLabelColorHighlighted;
if ( invAt ) <-- Abfrage !!!
invAt.RunInteraction(eModeUseinv);
SetAction (eActDefault);
}
else player.ActiveInventory = invAt;
}
else
{
UpdateActionBar ();
gAktionText.TextColor = ActionLabelColorHighlighted;
if ( invAt )
invAt.RunInteraction(Mouse.Mode);
SetAction (eActDefault);
}
}
}
}
-
fein fein, damit klappt das sehr gut :D