Maniac Mansion Mania Forum

MMM-Werkzeugkiste => Technik => Thema gestartet von: Mulle The Maniac am 21. August 2007, 16:58:55

Titel: Gespräche im Hintergrund
Beitrag von: Mulle The Maniac am 21. August 2007, 16:58:55
Hi Leute!

Heute möchte ich folgendes wissen: Wie kann ich ein Gespräch von zwei Personen im Hintergrund laufen lassen.

Ein Beispiel: Man steuert gerade Bernard und läuft an ein paar Passanten vorbei, die gerade über Gott und die Welt sprechen.

Mit welchem Skript-Befehl funktioniert das?
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 21. August 2007, 19:05:14
ich hatte das für epi53 so gelöst

Overlay* sayNoBlockOverlay1;
Overlay* sayNoBlockOverlay2;
Overlay* sayNoBlockOverlay3;
int sayNoBlockCharID1 = -1;
int sayNoBlockCharID2 = -1;
int sayNoBlockCharID3 = -1;
int sayNoBlockCounter1 = 0;
int sayNoBlockCounter2 = 0;
int sayNoBlockCounter3 = 0;
int sayNoBlockCounter4 = 0;
int sayNoBlockCounter5 = 0;
int sayNoBlockCounter6 = 0;
int iPause = 300;

function sayNoBlock(int CharID, const string message, int number)
{
  if(number == 1)
  {
sayNoBlockOverlay1 = character[CharID].SayBackground(message);
sayNoBlockCharID1 = CharID;
  }
  else if(number == 2)
  {
sayNoBlockOverlay2 = character[CharID].SayBackground(message);
sayNoBlockCharID2 = CharID;
  }
  else if(number == 3)
  {
sayNoBlockOverlay3 = character[CharID].SayBackground(message);
sayNoBlockCharID3 = CharID;
  }
  character[CharID].LockView(character[CharID].SpeechView);
  character[CharID].Animate(character[CharID].Loop, 5, eRepeat, eNoBlock, eForwards);
}

// =======================================================================================

function removeAllSayNoBlock()
{
if(sayNoBlockCharID1 != -1)
{
character[sayNoBlockCharID1].UnlockView();
sayNoBlockCharID1 = -1;
}
if(sayNoBlockCharID2 != -1)
{
character[sayNoBlockCharID2].UnlockView();
sayNoBlockCharID2 = -1;
}
if(sayNoBlockCharID3 != -1)
{
character[sayNoBlockCharID3].UnlockView();
sayNoBlockCharID3 = -1;
}
if(sayNoBlockOverlay1 != null && sayNoBlockOverlay1.Valid == 1)
{
sayNoBlockOverlay1.Remove();
}
if(sayNoBlockOverlay2 != null && sayNoBlockOverlay2.Valid == 1)
{
sayNoBlockOverlay2.Remove();
}
if(sayNoBlockOverlay3 != null && sayNoBlockOverlay3.Valid == 1)
{
sayNoBlockOverlay3.Remove();
}
}

// =======================================================================================

function EmiliaAndWendyDialog()
{
  int iStart1 = 100;
  int iStart2 = iStart1+125+iPause;
  int iStart3 = iStart2+150+iPause;
  int iStart4 = iStart3+150+iPause;
  int iStart5 = iStart4+199+iPause;

if (IsGamePaused() == 0)
{
if(sayNoBlockCounter6 == iStart1)
sayNoBlock(cEmilia.ID, "Nun mach schon.", 1);
else if(sayNoBlockCounter6 == iStart1+125)
sayNoBlock(cWendy.ID, "Alles zu seiner Zeit.", 2);

else if(sayNoBlockCounter6 == iStart2)
sayNoBlock(cEmilia.ID, "Es ist wirklich dringend.", 1);
else if(sayNoBlockCounter6 == iStart2+150)
sayNoBlock(cWendy.ID, "Siehst du nicht, dass ich gerade beschäftigt bin?", 2);

else if(sayNoBlockCounter6 == iStart3)
sayNoBlock(cEmilia.ID, "Bist du dann mal fertig?", 1);
else if(sayNoBlockCounter6 == iStart3+150)
sayNoBlock(cWendy.ID, "Ich bin fertig, wenn ich fertig bin.", 2);

else if(sayNoBlockCounter6 == iStart4)
sayNoBlock(cEmilia.ID, "Ich muss diesen Aufsatz morgen abgeben.", 1);
else if(sayNoBlockCounter6 == iStart4+200)
sayNoBlock(cWendy.ID, "Das ist dein Problem, nicht meines.", 2);

else if(sayNoBlockCounter6 == iStart5)
sayNoBlockCounter6 = iStart1-1;

sayNoBlockCounter6++;
}
}

function repeatedly_execute (){
...
// sayNoBlock global checks
if(sayNoBlockCharID1 != -1 && sayNoBlockOverlay1.Valid == 0)
{
character[sayNoBlockCharID1].UnlockView();
sayNoBlockCharID1 = -1;
}
else if(sayNoBlockCharID2 != -1 && sayNoBlockOverlay2.Valid == 0)
{
character[sayNoBlockCharID2].UnlockView();
sayNoBlockCharID2 = -1;
}
else if(sayNoBlockCharID3 != -1 && sayNoBlockOverlay3.Valid == 0)
{
character[sayNoBlockCharID3].UnlockView();
sayNoBlockCharID3 = -1;
}
  // sayNoBlock room checks
        if(player.room == 3)
{
  if(cWendy.x > 0)
  {
EmiliaAndWendyDialog();
  }
}
  }
}

geht sicher einfacher und dieser code ist auch nicht optimiert, aber er hat gefunkt  ;D
die einzelnen sayNoBlockCounter sind jeweils für einen hintergrunddialog
der code ist für 3 sprecher ausgelegt, aber jederzeit erweiterbar
die einzelnen dialoge bleiben bei einem bildwechsel genau da stehen und werden beim erneuten betreten des raumes wieder genau da fortgesetzt
Titel: Re: Gespräche im Hintergrund
Beitrag von: KhrisMUC am 21. August 2007, 19:31:02
Jessas! :D

Das ist doch bereits alles eingebaut...

qDisplaySpeech(int CharID, string message);

Also bspw.
// player enters room (after fadein)
  qDisplaySpeech(cPassant1.ID, "Na, alles klar?);
  qDisplaySpeech(cPassant2.ID, "Freilich. Bei Dir?");
  ...
(Nicht getestet!)

@Bòógieman:
Verwende das nächste Mal lieber arrays ;)
Overlay*sayNoBlockOverlay[4];
int sayNoBlockCharID[4];
...
  sayNoBlockOverlay[number] = character[CharID].SayBackground(message);
  sayNoBlockCharID[number] = CharID;
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 21. August 2007, 22:11:23
wie gesagt, der code ist nicht optimiert sondern war eigentlich nur zur einmaligen verwendung in meiner episode gedacht  ;D
solche sachen programmiere ich immer quick&dirty  ;)

wäre halt praktisch gewesen, wenn ich vorher kenntnis von der existenz von qDisplaySpeech gehabt hätte, in der AGS hilfe hab ich nix gefunden und das gesamte starterpack wollte ich nicht von a bis o durchackern  ;)
ich sollte evtl. vielleicht doch mal einen blick in die tutorials werfen  :P
wo sind denn die ganzen spannenden starterpack-funktionen beschrieben?
Titel: Re: Gespräche im Hintergrund
Beitrag von: KhrisMUC am 21. August 2007, 22:48:17
Richtig entdeckt hab ich das erst beim Ummodeln auf OO.
Aber das komplette global script mal zu überfliegen kann nicht schaden, sollte jeder Entwickler mal machen :)

Ansonsten:
http://www.adventure-treff.de/forum/viewtopic.php?t=7529
Titel: Re: Gespräche im Hintergrund
Beitrag von: Mulle The Maniac am 22. August 2007, 22:08:50
Werde ich umsetzen!

Danke Ihr Beiden! ;)
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 14. Juli 2008, 08:02:38
gibt es eigentlich eine funktion wie SayBackgroundAt?
also eine kombination von SayBackground und SayAt, die einen text an einer bestimmten position aber ohne zu blockieren anzeigt

oder muss man dafür extra overlays verwenden?

(für diese frage wollte ich nicht extra einen eigenen thread aufmachen und außerdem passt sie hier ganz gut rein  ;) )
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 21. Juli 2008, 21:59:01
ok, hab mir ein eigenes SayBackgroundAt gebastelt  ;)

gibt es für qDisplaySpeech eigentlich auch eine Verzögerungsfunktion?
qDisplaySpeech zeigt ja die texte ohne pausen am stück an
ich hätte aber gerne nach jedem satz eine kleine pause  :-\

EDIT: ok auch das ist gelöst
mit
string Delay(int time)kann man einen passenden leerstring erzeugen  :)
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 25. August 2008, 00:16:08
kann man eigentlich eine cutscene machen, die vom global script gestartet und später beendet wird?

ich würde gerne, wenn der hintergrunddialog einen bestimmten punkt erreicht hat, eine kurze cutscene machen
es wird zwar weiterhin nur der hintergrunddialog ausgeführt, aber die benutzereingaben sollen unterdrückt werden

oder anders gefragt, gibt es eine möglichkeit um benutzereingaben zu unterbinden und später wieder zu aktivieren?
ich stelle mir da sowas vor wie
Mouse.Enabled = false
nur leider habe ich da nix passendes gefunden :(
Mouse.Visible versteckt zwar den cursor, aber klicken kann man trotzdem noch
Titel: Re: Gespräche im Hintergrund
Beitrag von: KhrisMUC am 25. August 2008, 16:45:37
DisableInterface() / EnableInterface()
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 25. August 2008, 18:38:31
aah, sehr schön  :D
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 30. Dezember 2008, 01:00:30
so, zurück zum alten thema  ;D

ich verwende qDisplaySpeech und das wiederum verwendet DisplaySpeechBackground
dummerweise ignoriert das das schwarze streifen GUI am oberen rand gänzlich und somit ist der text bei einem character der bei Y 100 steht, nicht mehr sichtbar
ich hab das jetzt soweit umgeschrieben, dass Character.SayBackground verwendet wird, damit ich auch an das Overlay des textes ran komme
nur wenn ich jetzt bei diesem Overlay die Y koordinate neu setzen will, wird der text plötzlich X/Y zentriert am bildschirm dargestellt
das ist unabhängig vom wert, sobald ich Y umsetze ist der text mittig  :'(

         olqDisplaySpeech = character[CharID].SayBackground(buf);
         if(olqDisplaySpeech.Y < gBorder.Height)
            olqDisplaySpeech.Y = gBorder.Height;

hat jemand eine idee wie ich ein hintergrundgespräch machen kann, dass auch immer sichtbar ist?
Titel: Re: Gespräche im Hintergrund
Beitrag von: KhrisMUC am 30. Dezember 2008, 01:16:47
Der schwarze Rand wird durch ein GUI namens "border" oder so ähnlich erzeugt; schalt es doch mal versuchsweise ab, während der Overlay sichtbar ist.
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 30. Dezember 2008, 01:31:45
hat sich erledigt  :D

der character der spricht, ist immer an der selben position und leerzeichen am anfang des sprachtextes werden ebenfalls dargestellt  :)
ich hab jetzt einfach statt
"Nein danke."
"                                     Nein danke."
geschrieben

jetzt sind die leerzeichen im nicht sichtbaren bereich, der automatische zeilenumbruch erledigt den rest  ;)
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 02. Januar 2009, 21:39:03
ich mal wieder zum alten thema  ;D

hab ich eigentlich irgendwie die möglichkeit auf die tatsächlichen delay-werte des characters zu kommen, die bei der speechview verwendet werden?

qDisplaySpeech verwendet ja bei AnimateCharacterEx character[CharID].animspeed als delay, was aber nix mit der speechview zu tun hat  :o
character[CharID].animspeed ist bei fast allen chars nämlich 2, was viel zu schnell für die speechview ist und scheinbar auch nur beim laufen verwendet wird
bei einem normalen char.say wird ungefähr 5 verwendet, ich weiß aber nicht woher dieser wert kommt  ???
Titel: Re: Gespräche im Hintergrund
Beitrag von: NsMn am 03. Januar 2009, 11:46:33
qDisplaySpeech verwendet den normalen Anim-Speed, weil der Charater einfach animiert wird und daher seinen alten Delay behält. Der Delay 5 beim Speechview ist Standart(und ehrlich gesagt hab ich keine Ahnung wie mans ändern könnte)
Titel: Re: Gespräche im Hintergrund
Beitrag von: Bòógieman am 03. Januar 2009, 14:27:52
naja, ich hab das jetzt mal auf fix 5 geändert und gut ist

qDisplaySpeech ist sowieso nur bedingt einsetzbar, denn sobald man zb unterschiedliche chars in unterschiedlichen räumen reden lassen will, klappt das nicht mehr so ganz  ::)

war schon einiges an arbeit, das richtig zum laufen zu bringen
Titel: Re: Gespräche im Hintergrund
Beitrag von: KhrisMUC am 03. Januar 2009, 15:34:41
5 ist die Grundeinstellung, da game.talkanim_speed diesen Wert hat.

qDisplaySpeech ist dafür gedacht, im Hintergrund ein Gespräch laufen zu lassen; dass das in verschiedenen Räumen nicht automatisch perfekt klappt, wundert mich nicht.
Titel: Re: Gespräche im Hintergrund
Beitrag von: fireorange am 06. Januar 2009, 14:37:34
Jessas! :D

Das ist doch bereits alles eingebaut...

qDisplaySpeech(int CharID, string message);

Also bspw.
// player enters room (after fadein)
  qDisplaySpeech(cPassant1.ID, "Na, alles klar?);
  qDisplaySpeech(cPassant2.ID, "Freilich. Bei Dir?");
  ...
(Nicht getestet!)


Kann man in so einen Hintergrund-Dialog auch Sounds integrieren? Gibts dafür nen Code?
Titel: Re: Gespräche im Hintergrund
Beitrag von: NsMn am 06. Januar 2009, 14:38:47
Du köntest ja die qDisplaySpeech-Funktionen entsprechendend ändern.
Titel: Re: Gespräche im Hintergrund
Beitrag von: Edison Interactive am 01. Februar 2009, 19:52:05
Gibt es eine Möglichkeit, eine bereits angefangene Unterhaltung abzubrechen? Z.B. wenn sie aufgrund einer Aktion auf einmal anders verlaufen muss oder man die Charaktere anspricht?