// main global script file /////////////////////////////////////////////////////////////////////////// /////////// TEMPLATE FOR MAKING SCUMM TYPE GAMES BY PROSKRITO //////////// /////////// MODIFIED FOR AGS VERSION 3 BY RULAMAN //////////// /////////////////////////////////////////////////////////////////////////// /* legt den String der Datei fest, bzw. ermöglicht die "versteckte Debug-Option" Ist die Datei im Spieleordner vorhanden und die HIDDEN_DEBUG_ENABLED Option gesetzt, kann ein Spiel releast werden, ohne die Debug-Enabled-Option zurückzunehmen. So kann man später bei einem Fehler, oder seinen BETA-Testern die Datei zuschicken. Dann kann man auch in einem releasten Spiel noch etwaige Fehler suchen.*/ #define ONLY_FOR_TRANSLATION "\\ **** Hidden-Debug-Features-File" #define HIDDEN_DEBUG_STRING "MMM_GO" #define HIDDEN_DEBUG_ENABLED // automatisches Scrollen des Inventars, wenn zu wenige Items sichtbar sind #define SCROLL_INVENTORY bool b_PlateOpened[]; // [Game.CharacterCount]; bool b_GrammophonUsed[]; // [Game.CharacterCount]; void v_GameSettingsSet() { String seperator = String.Format("\\ **** Global-Script"); // only for translation /* Change only from here */ /* Nur ab hier ändern */ // Grabstein-Strings Game.GlobalStrings[1] = "Tribble"; Game.GlobalStrings[2] = "Mulle The Striker"; Game.GlobalStrings[3] = "ZENSIERT"; gi_Grabsteine = 2; // Wieviel Grabsteine sollen zu sehen sein? (0..3) gb_TreppenFlurErsterStock = true; // Absperrung zum ersten Stock gb_TreppenErsterStockZweiterStock = true; // Absperrung zum zweiten Stock (Treppe) gb_TreppenZweiterStockDritterStock = true; // Absperrung zum dritten Stock gb_SwimmingpoolEmpty = false; // Ist der Swimmingpool bereits leer? gb_CanEmptySwimmingpool = true; // kann man den Swimmingpool ausleeren? gb_DoorWithKobold = true; // muss man die Tür über den Kobold oder als normale Tür öffnen gb_DraehteRepariert = true; // wurden die defekten Drähte bereits repariert? gb_Fotolabor_Druckerei = true; // true=Fotolabor, false=Druckerei gb_PlantGrow = true; // kann man die Pflanze wachsen lassen? gb_PortraitIsReal = true; // Ist das Bild im Kaminzimmer real oder im Comicstil. gb_WiegeInEdsZimmer = false; // Steht in Eds Zimmer die Wiege des Nachwuchses gl_Garagentor = eDoorClosed; // eDoorOpen, eDoorClosed, eDoorLocked; // eKaminWithoutAll, eKaminWithPlant, eKaminWithDoor, eKaminWithAll gi_KaminzimmerOptions = eKaminWithDoor; // Licht im Raum ist aus=0, an=1, defekt=2 gi_LichtKeller = 0; gi_LichtDruckerei = 0; gl_LichtBibliothek = 0; gl_LichtDrahtraum = 0; gl_LichtMedizinzimmer = 0; gl_LichtTresorraum = 0; /* Change only till here */ /* Nur bis hier ändern */ if ( (gi_KaminzimmerOptions == eKaminWithAll) || (gi_KaminzimmerOptions == eKaminWithPlant) ) { gb_PlantGrow = false; } if ( !gb_SwimmingpoolEmpty ) { gb_CanEmptySwimmingpool = true; } if ( (Door[eDoorNumTeleskopzimmer].i_GlobalInt == eDoorLocked) && (gi_KaminzimmerOptions == eKaminWithAll) ) { gi_KaminzimmerOptions = eKaminWithDoor; gb_PlantGrow = false; } if ( (Door[eDoorNumTeleskopzimmer].i_GlobalInt == eDoorLocked) && (gi_KaminzimmerOptions == eKaminWithPlant) ) { gi_KaminzimmerOptions = eKaminWithoutAll; gb_PlantGrow = false; } if ( (Door[eDoorNumTeleskopzimmer].i_GlobalInt == eDoorLocked) && ((gi_KaminzimmerOptions == eKaminWithoutAll) || (gi_KaminzimmerOptions == eKaminWithDoor)) ) { gb_PlantGrow = false; } // Anzahl an möglichen Charakteren, // die die geheime Platte öffnen können b_PlateOpened = new bool[Game.CharacterCount]; b_GrammophonUsed = new bool[Game.CharacterCount]; FlashSprite = DynamicSprite.CreateFromExistingSprite(169, true); Flashlight.Transparency = 1; Flashlight.SetGUIMode(gFlashlight); Flashlight.SetBeamSprite(FlashSprite); Flashlight.SetFollowMouse(); } // Ersatz für die GlobalInts bei altem Türenschema #define DOORS_MAX 50 int i_Doors[DOORS_MAX]; #define TIMERS_MAX 40 int i_Timers[TIMERS_MAX]; File *debugfile; String GSlocname, // on_mouse_click -> unhandled_event GSinvloc, // locationname>extension SHOWNlocation; // location translated player.Say("Ist doch schon auf."); Character *GSPlayerUp; Character *GSPlayerDown; Character *BGChar; Overlay *ovChar; bool isBgSpeech = false; int GStopsaveitemRestore = 0, GStopsaveitemSave = 0, ActionLabelColorNormal = 530, // Used in action bar ActionLabelColorHighlighted = 1180, // Used in action bar invUparrowONsprite = 202, // used in repeatedly execute invUparrowOFFsprite = 213, // " " " " invDownarrowONsprite = 204, // " " " " invDownarrowOFFsprite = 214, // " " " " defaultfontheight = 8, // used in save / load guis GSlocid, // on_mouse_click -> ItemGiven, GScancelable, // MovePlayer bgscounter=0; eAction GSagsusedmode; // on_mouse_click -> unhandled_event LocationType GSloctype; // on_mouse_click -> unhandled_event int key_l_yes, key_u_yes, key_l_no, key_u_no; bool HiddenPlateFound(this Character*) { bool b_return; b_return = b_PlateOpened[this.ID]; b_PlateOpened[this.ID] = true; return b_return; } bool GrammophonUsed(this Character*) { bool b_return; b_return = b_GrammophonUsed[this.ID]; b_GrammophonUsed[this.ID] = true; return b_return; } void v_Flashlight(bool b_On) { if ( b_On ) { // Taschenlampenlichtkegel FlashSprite = DynamicSprite.CreateFromExistingSprite(169, true); Flashlight.Transparency = 1; } else { // leeres Sprite (Dunkelheit) FlashSprite = DynamicSprite.CreateFromExistingSprite(26, true); Flashlight.Transparency = 2; } Flashlight.SetGUIMode(gFlashlight); Flashlight.SetBeamSprite(FlashSprite); Flashlight.SetFollowMouse(); } // ======================================================================================= function DisplaySpeechBackgroundEx(this Character*, String message) { isBgSpeech = true; ovChar = this.SayBackground(message); BGChar = this; } #define BGS_DELAY 6 //! this is the animation delay for ??? function repeatedly_execute_always() { if ( isBgSpeech ) { if ( ovChar.Valid ) { if ( bgscounter >= BGS_DELAY * 2 ) bgscounter=0; BGChar.LockViewFrame(BGChar.SpeechView + 1, BGChar.Loop, bgscounter/BGS_DELAY); bgscounter++; } else { BGChar.UnlockView(); } isBgSpeech = false; } } // ============================= math functions =========================================== function Absolute (int value) { if (value < 0) value = - value; return value; } function Offset (int point1, int point2) { return Absolute (point1 - point2); } // ============================= action functions =========================================== eAction global_action; eAction default_action; eAction alternative_action; eAction used_action; int action_l_keycode [eActCount]; int action_u_keycode [eActCount]; eAction button_action[9]; int action_button_normal [eActCount]; int action_button_highlight [eActCount]; Button *action_Buttonb[10]; String TranslateAction (String result, eAction action, String objekt, String item) { // get translated action template if (action == eActWalkTo) result = "Gehe zu %s"; else if (action == eActLookAt) result = "Schau an %s"; else if (action == eActTalkTo) result = "Rede mit %s"; else if (action == eActGiveTo) { if (item.Length > 0) result = "Gib !s an %s"; else result = "Gib %s"; } else if (action == eActPickUp) result = "Nimm %s"; else if (action == eActUse) { if (item.Length > 0) result = "Benutze !s mit %s"; else result = "Benutze %s"; } else if (action == eActOpen) result = "Öffne %s"; else if (action == eActClose) result = "Schließe %s"; else if (action == eActPush) result = "Drücke %s"; else if (action == eActPull) result = "Ziehe %s"; else if (action == eActSwitchTo) result = "Wechsle zu %s"; // fill object and item into action template result = GetTranslation (result); int ip = result.Contains("!s"); if (ip >= 0) { int op = result.Contains("%s"); result = result.ReplaceCharAt(ip, '%'); if (ip < op) result = result.Format(result, item, objekt); else result = result.Format(result, objekt, item); } else result = result.Format(result, objekt); return result; } function isAction (eAction test_action) { return global_action == test_action; } function UsedAction (eAction test_action) { return ((used_action == test_action) && (GSagsusedmode != eModeUseinv)) || ((test_action == eActUseInventory) && (used_action == eActUse) && (GSagsusedmode == eModeUseinv)); } function SetAction (eAction new_action) { // set default action if (new_action == eActDefault) new_action = default_action; // set corresponding cursormode if (new_action == eActWalkTo) Mouse.Mode = eModeUsermode2; else if (new_action == eActLookAt) Mouse.Mode = eModeLookat; else if (new_action == eActTalkTo) Mouse.Mode = eModeTalkto; else if (new_action == eActGiveTo) Mouse.Mode = eModeInteract; else if (new_action == eActPickUp) Mouse.Mode = eModePickup; else if (new_action == eActUse) Mouse.Mode = eModeInteract; else if (new_action == eActOpen) Mouse.Mode = eModeUsermode1; else if (new_action == eActClose) Mouse.Mode = eModeUsermode1; else if (new_action == eActPush) Mouse.Mode = eModeUsermode1; else if (new_action == eActPull) Mouse.Mode = eModeUsermode1; // save action global_action = new_action; } function SetDefaultAction (eAction def_action) { default_action = def_action; SetAction (eActDefault); } // ============================= Load/Save game =========================================== function GetLucasSavegameListBox(this GUI*, ListBox *box) { String strbuf, sgdesc; int maxsavegames = 99; int counter = 0; strbuf = ""; box.Clear(); while ( counter < maxsavegames ) { strbuf = String.Format("%d. ", counter + 1); sgdesc = Game.GetSaveSlotDescription(counter + 100); if ( null == sgdesc ) sgdesc = ""; strbuf = strbuf.Append(sgdesc); box.AddItem(strbuf); counter++; } box.TopItem = 0; box.SelectedIndex = -1; } // ============================= Timer =========================================== function SetOwnTimer(int timerid, int timeout) { if ( timerid >= TIMERS_MAX ) { } else { i_Timers[timerid] = timeout + 1; } } function IsOwnTimerExpired(int timerid) { if ( timerid >= TIMERS_MAX ) { } else if ( i_Timers[timerid] == 1 ) { i_Timers[timerid] = 0; return 1; } else { return 0; } } function CheckTimers() { int timers = 0; while ( timers < TIMERS_MAX ) { if ( i_Timers[timers] > 1 ) { i_Timers[timers]--; } timers++; } } // ============================= GlobalCondition =========================================== function GlobalCondition (int parameter) { // here are some conditions that are used many times in the script int cond; InventoryItem* invItem; GUI* guiItem; GUIControl* guiControl; invItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); guiItem = GUI.GetAtScreenXY(mouse.x, mouse.y); guiControl = GUIControl.GetAtScreenXY(mouse.x, mouse.y); if (parameter == 1) { // if the mouse is in the inventory and modes Walk or pickup are selected if ( null != invItem ) { cond = ((isAction (eActWalkTo) || isAction (eActPickUp))); //( invItem.ID >= 0 ) && } } else if (parameter == 2) { // if the mode is useinv and the mouse is over the active inv (like "use knife on knife") cond = ( null != invItem && (Mouse.Mode == eModeUseinv) && (player.ActiveInventory.ID == invItem.ID )); } else if (parameter == 3) { // if the mode is talk, or "Give", and the mouse isnt over a character cond = ((isAction (eActTalkTo) || (isAction (eActGiveTo) && (Mouse.Mode == eModeUseinv))) && (GetLocationType (mouse.x, mouse.y) != eLocationCharacter)); } else if (parameter == 4) { // if its GIVE and the mouse isnt over a inv.item cond = ( ( null == invItem ) && (Mouse.Mode == eModeInteract) && isAction (eActGiveTo)); } if (parameter == 5) { // if its over the "other characters" buttons in the inventory. if ( guiItem ) { if ( guiControl ) { cond = ((guiItem == gMaingui) && ((guiControl.ID == 12) || (guiControl.ID == 13))); } } } return cond; } // ============================= Extensions =========================================== char Extension(this String*) { if ( this.Contains(">") >= 0 ) { return this.Chars[this.Length - 1]; } else if ( this.Contains("$") >= 0 ) { return this.Chars[this.Length - 1]; } return 0; } String RemoveExtension(this String*) { if ( this.Extension() ) // check Extension { return this.Truncate(this.Length - 2); // Remove Extension if any } return this; // no Extension } String AddExtension(this String*, char extension) { String temp; if ( this.Extension() ) { temp = this.RemoveExtension(); } return String.Format("%s>%c", this, extension); } // ============================= Action =========================================== function SetAlternativeAction(String location, char extension, eAction action) { if (action == eActDefault) { if (location.Extension() == extension) { alternative_action = action; } } else { int normalbuttonpic = action_button_normal [action]; int overbuttonpic = action_button_highlight [action]; // used for setting the default action given the extension. if (location.Extension() == extension) { if ( null != action_Buttonb[action] ) { action_Buttonb[action].NormalGraphic = overbuttonpic; } // 1 = normal 2 = mouse-over 3 = button pushed alternative_action = action; } else if ( null != action_Buttonb[action] ) { action_Buttonb[action].NormalGraphic = normalbuttonpic; } if ( null != action_Buttonb[action] ) { action_Buttonb[action].MouseOverGraphic = overbuttonpic; } } } String OpenCloseExtensionGraphic (Object *objekt, int openGraphic, int closeGraphic, String location) { if (objekt.Graphic == closeGraphic) return location.AddExtension('o'); else if (objekt.Graphic == openGraphic) return location.AddExtension('c'); } String OpenCloseExtensionObject (Object *objekt, String location) { if ( objekt.Visible == false ) { return location.AddExtension('o'); } else if (objekt.Visible == true ) { return location.AddExtension('c'); } } String OpenCloseExtension (int gi, String location) { if ((i_Doors[gi] == 0) || (i_Doors[gi] == 2)) return location.AddExtension('o'); else return location.AddExtension('c'); } String VariableExtensions (String location) { // put here which extension will show the things with variable extension (>v) int i = 0; bool b_Ready = false; Hotspot* hotAt = Hotspot.GetAtScreenXY(mouse.x, mouse.y); Object *objAt = Object.GetAtScreenXY(mouse.x, mouse.y); while ( i < MAX_DOORS ) { if ( ((Door[i].h_Hotspot == hotAt) && (Door[i].l_Room == player.Room)) || ((Door[i].h_NewHotspot == hotAt) && (Door[i].l_NewRoom == player.Room)) ) { if ( (Door[i].i_GlobalInt == 0) || (Door[i].i_GlobalInt == 2) ) { location = location.AddExtension('o'); } else { location = location.AddExtension('c'); } i = MAX_DOORS; // simulates a break; b_Ready = true; } i++; } if ( b_Ready == true ) { } else { // hier rein die Schemata nach altem Vorgehen if ( player.Room == 7 ) { if ( hotAt == hotspot[5] ) // Wasser in der Küche { if ( object[4].Visible ) // fließendes Wasser { location = location.AddExtension('c'); } else { location = location.AddExtension('o'); } } } } return location; } function CheckDefaultAction() { // you could want to change which extension activates which default action, or which button sprite // it changes. The extensions are characters, so remember to put them with single ', not ". String location; location = Game.GetLocationName(mouse.x, mouse.y); InventoryItem *invItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); if (location.Extension() == 0) { // Setting default modes if the thing has no extension: if ( GetLocationType(mouse.x, mouse.y) == eLocationCharacter ) { // if it is a character location = location.AddExtension ('t'); // set default action "talk to" } else if( (GetLocationType(mouse.x, mouse.y) != eLocationNothing) || null != invItem ) { // if its an inv item, a hotspot or an object location = location.AddExtension('l'); // set default action "look at" } else { location = location.AddExtension('n'); // set default action "none" } } else if (location.Extension() == 'v') { // if the default action depends on some events location = location.RemoveExtension(); location = VariableExtensions (location); } if (GlobalCondition (2) || GlobalCondition (3) || GlobalCondition (4)) { location = ">n"; //Dont send the name of the hotspt/obj/char/inv to the action bar and set default action "none" } GSinvloc = String.Format("%s", location); if ((location.Extension() == 'u') && ( null != invItem ) ) { // it's an inv item location = location.RemoveExtension(); location = location.AddExtension('l'); // set default action "look at" } SetAlternativeAction (location, 'n', eActDefault); SetAlternativeAction (location, 'g', eActGiveTo); SetAlternativeAction (location, 'p', eActPickUp); SetAlternativeAction (location, 'u', eActUse); SetAlternativeAction (location, 'o', eActOpen); SetAlternativeAction (location, 'l', eActLookAt); SetAlternativeAction (location, 's', eActPush); SetAlternativeAction (location, 'c', eActClose); SetAlternativeAction (location, 't', eActTalkTo); SetAlternativeAction (location, 'y', eActPull); location = location.RemoveExtension(); SHOWNlocation = location; } // ============================= ActionBar =========================================== function UpdateActionBar() { // set the text in the action bar String madetext; int action = global_action; String objekt; String item; GUIControl *guic; madetext = ""; objekt = SHOWNlocation; item = ""; if (GlobalCondition (5) == 1) { // write SWITCH TO CHAR action = eActSwitchTo; guic = GUIControl.GetAtScreenXY(mouse.x, mouse.y); if ( null != guic ) { if ( guic.ID == 12 ) { if ( UpperButton() == -1 ) { } else { objekt = character[UpperButton()].Name; } } else { if ( UpperButton() == -1 ) { } else { objekt = character[LowerButton()].Name; } } } } else if (Mouse.Mode == 4) { // use or give inventory item item = player.ActiveInventory.Name; item = item.RemoveExtension(); } else if (GlobalCondition (1) == 1) { // if the mouse is in the inventory and modes Walk or pickup are selected action = eActUse; } madetext = TranslateAction (madetext, action, objekt, item); // show action text gAktionText.Text = madetext; gAktionText.TextColor = ActionLabelColorNormal; } // ============================= Inventory =========================================== function GiveInvEx (int invitem, Character *charidfrom, Character *charidto) { //for passing inv items between characters int amount; amount = charidfrom.InventoryQuantity[invitem]; charidfrom.InventoryQuantity[invitem] = 0; charidto.InventoryQuantity[invitem] = amount; UpdateInventory (); } bool GiveInv(this Character*, InventoryItem *invItem, Character *charac) { return GiveInvEx(invItem.ID, player, charac); } bool ReceiveInv(this Character*, InventoryItem *invItem, Character *charac) { return GiveInvEx(invItem.ID, charac, player); } function GiveInv (int invitem, Character *charid) { //for giving an inv item to other player GiveInvEx (invitem, player, charid); } // ============================= translation =========================================== String ClearToSpace(String text) { int p = 0; // ignore white spaces at the beginning while ( ( p < text.Length ) && ( text.Chars[p] == ' ' ) ) { p++; } // write white spaces until next white space while ( ( p < text.Length ) && ( text.Chars[p] != ' ' ) ) { text = text.ReplaceCharAt(p, ' '); p++; } return text; } function TranslateNumber (String number_name) { String tr; tr = ClearToSpace(GetTranslation (number_name)); return tr.AsInt; } function SetActionButtons (eAction action, String button_definition) { // extract data from button_definition String translat; int i; if (IsTranslationAvailable()) { translat = GetTranslation(button_definition); translat = ClearToSpace (translat); } else { translat = button_definition; translat = ClearToSpace (translat); } i = translat.AsInt; translat = ClearToSpace(translat); if ( i == 4 ) { action_Buttonb[action] = gMainLookat; } //Schliesse 4 else if ( i == 2 ) { action_Buttonb[action] = gMainUse; } //Nimm 2 else if ( i == 1 ) { action_Buttonb[action] = gMainPickup; } //Benutze 1 else if ( i == 3 ) { action_Buttonb[action] = gMainOpen; } //Öffne 3 else if ( i == 6 ) { action_Buttonb[action] = gMainClose; } //Ziehe 6 else if ( i == 0 ) { action_Buttonb[action] = gMainGive; } //Schau 0 else if ( i == 8 ) { action_Buttonb[action] = gMainPull; } //Rede 8 else if ( i == 5 ) { action_Buttonb[action] = gMainPush; } //Gib 5 else if ( i == 7 ) { action_Buttonb[action] = gMainTalkto; } //Drücke 7 action_button_normal [action] = translat.AsInt; translat = ClearToSpace(translat); action_button_highlight [action] = translat.AsInt; translat = ClearToSpace(translat); int p = translat.Length - 1; while (p > 0) { action_l_keycode [action] = translat.Chars[p]; p--; action_u_keycode [action] = translat.Chars[p]; if (action_l_keycode [action] != ' ') { p = 0; } } if ( null != action_Buttonb[action] ) button_action [action_Buttonb[action].ID] = action; } function AdjustLanguage () { // --- translate yes/no-keys --- String yes_no; yes_no = GetTranslation ("JjNn"); key_u_yes = yes_no.Chars[0]; key_l_yes = yes_no.Chars[1]; key_u_no = yes_no.Chars[2]; key_l_no = yes_no.Chars[3]; // --- translate GUI action buttons --- SetActionButtons (eActGiveTo, "a_button_give 5 802 803 Dd"); SetActionButtons (eActPickUp, "a_button_pick_up 2 800 801 Ee"); SetActionButtons (eActUse, "a_button_use 1 794 795 Ww"); SetActionButtons (eActOpen, "a_button_open 3 790 791 Aa"); SetActionButtons (eActLookAt, "a_button_look_at 0 788 789 Qq"); SetActionButtons (eActPush, "a_button_push 7 798 799 Xx"); SetActionButtons (eActClose, "a_button_close 4 796 797 Ss"); SetActionButtons (eActTalkTo, "a_button_talk_to 8 804 805 Cc"); SetActionButtons (eActPull, "a_button_pull 6 792 793 Yy"); // --- load font corresponding to language and screen width --- String font_info; if (system.ViewportWidth == 320) font_info = GetTranslation ("font_320: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); else if (system.ViewportWidth == 640) font_info = GetTranslation ("font_640: 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14"); font_info = ClearToSpace(font_info); // Labeles (Strg+F Labeles springt hierher) Game.SpeechFont = font_info.AsInt; font_info = ClearToSpace(font_info); // Speech gAktionText.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Status-Line gOptionsTitel.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Save/Load-GUI Label // Fehler im Speichern-Dialog korrigiert nichts auskommentieren gOptionsSave.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Save-Button of Save/Load-GUI gOptionsLoad.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Load-Button of Save/Load-GUI gOptionsPlay.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Play-Button of Save/Load-GUI gOptionsExit.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Quit-Button of Save/Load-GUI gPausedText.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Pause-GUI Label gRestoreTitel.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Restore-GUI Label gRestoreCancel.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Cancel-Button of Load-GUI gSaveTitel.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Save-GUI Label gSaveOK.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // OK-Button of Save-GUI gSaveCancel.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Cancel-Button of Save-GUI gConfirmQuestion.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Quit-GUI Label gRestartQuestion.Font = font_info.AsInt; font_info = ClearToSpace(font_info); // Restart-GUI Label } // ============================= MovePlayer =========================================== 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. GUI *guiAt = GUI.GetAtScreenXY(mouse.x, mouse.y); InventoryItem *invAt = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); if ( g_PlayerCanMove > 0 ) { int cursorspritenumber = 16, blankcursorspritenumber = 26; GScancelable = 0; Mouse.ChangeModeGraphic(eModeWait, cursorspritenumber); if (direct == 0) player.Walk(x, y); else player.Walk(x, y, eNoBlock, eAnywhere); // wait for release of mouse button while (player.Moving && (Mouse.IsButtonDown(eMouseLeft) || Mouse.IsButtonDown(eMouseRight) )) { Wait (1); Mouse.Update(); CheckDefaultAction (); } // abort moving on new mouse down while (player.Moving) { if ( Mouse.IsButtonDown (eMouseLeft) && ( null == guiAt || null != invAt )) { player.StopMoving(); GScancelable = 1; } else if ( Mouse.IsButtonDown(eMouseRight) && (null == guiAt || null != invAt )) { player.StopMoving(); GScancelable = 2; } else { Wait (1); Mouse.Update(); CheckDefaultAction(); } } mouse.ChangeModeGraphic(eModeWait, blankcursorspritenumber); if ( GScancelable == 0 && player.x == x && player.y == y ) { return 2; } else if ( GScancelable == 0 ) { return 1; } else { return 0; } } else return 0; } //! veraltet (obsolete) function MovePlayer (int x, int y) { //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. return MovePlayerEx (x, y, 0); } // ============================= Go =========================================== // this section after MovePlayer function GoToCharacterEx (Character *charidwhogoes, Character *charid, int direction, int xoffset, int yoffset, int NPCfacesplayer, int blocking) { //Goes to a character staying at the side defined by 'direction': 1 up, 2 right, 3 down, 4 left //and it stays at xoffset or yofsset from the character. NPCfacesplayer self-explained. ;) // blocking: 0=non-blocking; 1=blocking; 2=semi-blocking int playerchar, charidx, charidy, playerx, playery; charidx = charid.x; charidy = charid.y; playerx = player.x; playery = player.y; int arrived = 1; if ((Offset (playerx, charidx) > xoffset) || (Offset (playery, charidy) > yoffset)) { if (direction == 0) { // el camino mas cercano if (Offset (charidx, playerx) >= Offset (charidy, playery)) { // dcha o izda if (playerx >= charidx) direction = 2; //right else direction = 4; //left } else { if (playery >= charidy) direction = 3; //abajo else direction = 1; } } // calculate target position if ( direction == eDirectionUp ) charidy -= yoffset; else if ( direction == eDirectionLeft ) charidx += xoffset; else if ( direction == eDirectionDown ) charidy += yoffset; else if ( direction == eDirectionRight ) charidx -= xoffset; // move character if (blocking == 0) { player.Walk(charidx, charidy); arrived = 0; } else if (blocking == 1) { charidwhogoes.Walk(charidx, charidy, eBlock); arrived = 1; } else if (blocking == 2) arrived = MovePlayer (charidx, charidy); } if (arrived > 0) { // characters only face each other after the moving character arrived at the target point if (NPCfacesplayer == 1) charid.FaceCharacter(charidwhogoes); charidwhogoes.FaceCharacter(charid); } return arrived; } function NPCGoToCharacter (Character *charidwhogoes, Character *charidtogoto, int direction, int NPCfacesplayer, int blocking){ // same as above but with default x and y offset. int defaultxoffset, defaultyoffset; defaultxoffset = 35; defaultyoffset = 20; return GoToCharacterEx (charidwhogoes, charidtogoto, direction, defaultxoffset, defaultyoffset, NPCfacesplayer, blocking); } function GoToCharacter (Character *charid, int direction, int NPCfacesplayer, int blocking){ // same as above but with default x and y offset. int defaultxoffset, defaultyoffset; defaultxoffset = 35; defaultyoffset = 20; return GoToCharacterEx (player, charid, direction, defaultxoffset, defaultyoffset, NPCfacesplayer, blocking); } function GoTo (int blocking) { // Goes to whatever the player clicked on. // blocking: 0=non-blocking; 1=blocking; 2=semi-blocking Hotspot *hotAt = Hotspot.GetAtScreenXY(mouse.x, mouse.y); Character *charAt = Character.GetAtScreenXY(mouse.x, mouse.y); Object *objAt = Object.GetAtScreenXY(mouse.x, mouse.y); int xtogo, ytogo; int locationtype = GetLocationType (mouse.x, mouse.y); int arrived = 0; if (locationtype == 2) arrived = GoToCharacter (charAt, 0, 0, blocking); else { if ( hotAt ) if (locationtype == 1 && hotAt.ID > 0) { xtogo = hotAt.WalkToX; ytogo = hotAt.WalkToY; } if (locationtype == 3) { int objekt = objAt.ID; xtogo = objAt.X; ytogo = objAt.Y; } if ( hotAt ) if (hotAt.ID == 0) { xtogo = mouse.x; ytogo = mouse.y; } else { xtogo = mouse.x; ytogo = mouse.y; } xtogo += GetViewportX (); ytogo += GetViewportY (); if (blocking == 0) player.Walk(xtogo, ytogo); else if (blocking == 1) { player.Walk(xtogo, ytogo, eBlock); arrived = 1; } else if (blocking == 2) arrived = MovePlayer (xtogo, ytogo); } return arrived; } function Go () { // Go to whatever the player clicked on. You can cancel the action, and returns 1 if the player has gone to it. return GoTo (2); } // ============================= interaction functions =========================================== // this section after MovePlayer function PlaceCharacter (this Character*, int x, int y, CharacterDirection dir) { this.x = x; this.y = y; this.FaceDirection(dir); } //! veraltet (obsolete) function PlacePC (int x, int y, CharacterDirection dir) { player.PlaceCharacter(x, y, dir); } function any_click_move (int x, int y, CharacterDirection dir) { int result = MovePlayer (x, y); if (result) { player.FaceDirection(dir); Wait (5); } return result; } int any_click_move_direct(int l_XPos, int l_YPos, CharacterDirection l_Dir) { int result = MovePlayerEx (l_XPos, l_YPos, 1); if (result) { player.FaceDirection(l_Dir); Wait (5); } return result; } function any_click_walk (int x, int y, CharacterDirection dir){ int result = 1; if (UsedAction (eActWalkTo)) any_click_move (x, y, dir); else result = 0; return result; // 0 = unhandled // 1 = handled } function any_click_walk_look (int x, int y, CharacterDirection dir, String lookat){ int result = any_click_walk (x, y, dir); if ((result == 0) && (UsedAction (eActLookAt) && (lookat.Length > 0))) { result = 1; if (any_click_move (x, y, dir)) player.Say(lookat); } return result; // 0 = unhandled // 1 = handled } function init_object(this Object*, int gi) { if ( null != this ) { this.Clickable = false; // die Türenobjekte nicht Klickbar machen if (i_Doors[gi] == 1) this.Visible = true; else this.Visible = false; } } String door_lookat; String door_islocked; String door_wrongitem; function SetDoorStrings (String lookat, String islocked, String wrongitem) { door_lookat = lookat; door_islocked = islocked; door_wrongitem = wrongitem; } function any_click_on_door_special (int gi, Object *objekt, int x, int y, CharacterDirection dir, int nr_room, int nr_x, int nr_y, CharacterDirection nr_dir, int opensound, int closesound, int key, int closevalue) { // key = -1: opens also locked doors without key // key = -2: door can't be unlocked (like rusted) InventoryItem *charInv = player.ActiveInventory; int result = 1; if (UsedAction (eActClose)) { if (i_Doors[gi] == 0) { player.Say("Das ist schon zu."); } else if (i_Doors[gi] == 1) { if (any_click_move (x, y, dir)) { PlaySound (closesound); objekt.Visible = false; i_Doors[gi] = closevalue; } } } else if (UsedAction (eActOpen)) { if ((i_Doors[gi] == 0) || ((i_Doors[gi] == 2) && (key == -1))) { if (any_click_move (x, y, dir)) { PlaySound (opensound); objekt.Visible = true; i_Doors[gi] = 1; } } else if (i_Doors[gi] == 1) { player.Say("Das ist schon offen."); } else if (i_Doors[gi] == 2) { if (any_click_move (x, y, dir)) { player.Say(door_islocked); } } } else if (UsedAction (eActWalkTo)) { if ( any_click_move (x, y, dir) == 2 ) // == 2, korrektur Door-Script, falls sich Charakter nicht bewegen kann { if (i_Doors[gi] == 1) { player.ChangeRoom (nr_room, nr_x, nr_y, nr_dir); result = 2; } } } else if (UsedAction (eActLookAt) && (door_lookat.Length > 0)) { if (any_click_move (x, y, dir)) player.Say(door_lookat); } else if (UsedAction (eActUseInventory) && (key >= 0)) { if (any_click_move (x, y, dir)) { if ( charInv ) { if (charInv.ID == key) { if (i_Doors[gi] == 2) { PlaySound (2); objekt.Visible = true; i_Doors[gi] = 1; } } else player.Say(door_wrongitem); } } } else result = 0; return result; // 0 = unhandled // 1 = handled // 2 = NewRoom } function any_click_on_door (int gi, Object *objekt, int x, int y, CharacterDirection dir, int nr_room, int nr_x, int nr_y, CharacterDirection nr_dir) { SetDoorStrings ("", "", ""); return any_click_on_door_special (gi, objekt, x, y, dir, nr_room, nr_x, nr_y, nr_dir, 2, 3, -1, 0); } function any_click_use_inv (int item, int x, int y, CharacterDirection dir) { int result = 0; InventoryItem *charInv = player.ActiveInventory; if (UsedAction (eActUseInventory)) { if ( charInv ) { if ( charInv.ID == item ) { if ( any_click_move (x, y, dir) ) result = 2; else result = 1; } } } return result; // 0 = unhandled // 1 = handled, but canceled // 2 = use this item } function any_click_walk_look_pick (int x, int y, CharacterDirection dir, string lookat, Object *objekt, InventoryItem *item, int gi, int sound) { int result = any_click_walk_look (x, y, dir, lookat); if ((result == 0) && UsedAction (eActPickUp)) { if (any_click_move (x, y, dir)) { if (sound >= 0) PlaySound (sound); if (objekt.ID >= 0) objekt.Visible = false; if (item.ID >= 0) player.AddInventory(item); if (gi >= 0) i_Doors[gi] = 0; result = 2; } } return result; // 0 = unhandled // 1 = handled, but canceled // 2 = picked up } /**********************************************************************/ /* Functions */ /**********************************************************************/ int DoorType::SetStrings(String lookat, String islocked, String wrongitemopen, String wrongitemclose, String lookAt2) { this.s_LookAt = lookat; this.s_NewLookAt = lookAt2; this.s_IsLocked = islocked; this.s_WrongItemOpen = wrongitemopen; this.s_WrongItemClose = wrongitemclose; } /********************************************************************** ***********************************************************************/ int DoorType::Open() { this.i_GlobalInt = eDoorOpen; if ( player.Room == this.l_Room ) { this.o_Objekt.Visible = true; } else if ( player.Room == this.l_NewRoom ) { this.o_NewObjekt.Visible = true; } } /********************************************************************** ***********************************************************************/ int DoorType::Close() { this.i_GlobalInt = eDoorClosed; if ( player.Room == this.l_Room ) { this.o_Objekt.Visible = false; } else if ( player.Room == this.l_NewRoom ) { this.o_NewObjekt.Visible = false; } } /********************************************************************** ***********************************************************************/ int DoorType::Lock() { this.i_GlobalInt = eDoorLocked; if ( player.Room == this.l_Room ) { this.o_Objekt.Visible = false; } else if ( player.Room == this.l_NewRoom ) { this.o_NewObjekt.Visible = false; } } /********************************************************************** ***********************************************************************/ int DoorType::ClickSpecial(int opensound, int closesound, int key, int closevalue) { // key = -1: opens also locked doors without key // key = -2: door can't be unlocked (like rusted) InventoryItem *charInv = player.ActiveInventory; int result = 1; int i_XPosition; int i_YPosition; int i_NewXPosition; int i_NewYPosition; CharacterDirection l_Direction; CharacterDirection l_NewDirection; int l_NewRoom; String s_LookAt; Object *o_Objekt; if ( player.Room == this.l_Room ) { i_XPosition = this.i_XPosition; i_YPosition = this.i_YPosition; i_NewXPosition = this.i_NewXPosition; i_NewYPosition = this.i_NewYPosition; l_Direction = this.l_Direction; l_NewDirection = this.l_NewDirection; l_NewRoom = this.l_NewRoom; s_LookAt = this.s_LookAt; o_Objekt = this.o_Objekt; if ( s_LookAt == null ) { s_LookAt = s_LookAtStandard; } } else if ( player.Room == this.l_NewRoom ) { i_XPosition = this.i_NewXPosition; i_YPosition = this.i_NewYPosition; i_NewXPosition = this.i_XPosition; i_NewYPosition = this.i_YPosition; l_Direction = this.l_NewDirection; l_NewDirection = this.l_Direction; l_NewRoom = this.l_Room; s_LookAt = this.s_NewLookAt; o_Objekt = this.o_NewObjekt; if ( s_LookAt == null ) { s_LookAt = s_NewLookAtStandard; } // Inverting the direction a character faces after moving through a door. // CharacterDirection types correspond to number. The numbering is // identical to the numbering of loops in a view. l_Direction = 3 - l_Direction; l_NewDirection = 3 - l_NewDirection; } else { result = 1; } if ( UsedAction (eActClose) ) { if ( this.i_GlobalInt == 0 ) { player.Say("Das ist schon zu."); } else if ( this.i_GlobalInt == 1 ) { if ( any_click_move(i_XPosition, i_YPosition, l_Direction) ) { PlaySound(closesound); if ( null == o_Objekt ) { } else if ( o_Objekt ) { o_Objekt.Visible = false; } this.i_GlobalInt = closevalue; } } } else if ( UsedAction(eActOpen) ) { if ( (this.i_GlobalInt == 0) || ((this.i_GlobalInt == 2) && (key == -1)) ) { if ( any_click_move(i_XPosition, i_YPosition, l_Direction) ) { PlaySound(opensound); if ( null == o_Objekt ) { } else if ( o_Objekt ) { o_Objekt.Visible = true; } this.i_GlobalInt = 1; } } else if ( this.i_GlobalInt == 1 ) { player.Say("Das ist schon offen."); } else if ( this.i_GlobalInt == 2 ) { if ( any_click_move(i_XPosition, i_YPosition, l_Direction) ) { if ( this.s_IsLocked != null ) { player.Say(this.s_IsLocked); } else { player.Say(s_IsLockedStandard); } } } } else if ( UsedAction (eActWalkTo) ) { if ( any_click_move(i_XPosition, i_YPosition, l_Direction) == 2 ) // == 2, korrektur Door-Script, falls sich Charakter nicht bewegen kann { if ( this.i_GlobalInt == 1 ) { player.ChangeRoom(l_NewRoom, i_NewXPosition, i_NewYPosition, l_NewDirection); result = 2; } } } else if ( UsedAction(eActLookAt) && (s_LookAt.Length > 0) ) { if ( any_click_move(i_XPosition, i_YPosition, l_Direction) ) { player.Say(s_LookAt); } } else if ( UsedAction(eActUseInventory) && (key >= 0) ) { if (any_click_move(i_XPosition, i_YPosition, l_Direction) ) { if ( charInv ) { if ( charInv.ID == key ) { if ( this.i_GlobalInt == 2 ) { PlaySound(2); if ( null == o_Objekt ) { } else if ( o_Objekt ) { o_Objekt.Visible = true; } this.i_GlobalInt = 1; } } else { if ( null == o_Objekt ) { if ( this.s_WrongItemOpen != null ) { player.Say(this.s_WrongItemOpen); } else { player.Say(s_WrongItemOpenStandard); } } else if ( o_Objekt.Visible ) { if ( this.s_WrongItemClose != null ) { player.Say(this.s_WrongItemClose); } else { player.Say(s_WrongItemCloseStandard); } } else { if ( this.s_WrongItemOpen != null ) { player.Say(this.s_WrongItemOpen); } else { player.Say(s_WrongItemOpenStandard); } } } } } } else result = 0; return result; // 0 = unhandled // 1 = handled // 2 = NewRoom } /********************************************************************** ***********************************************************************/ int DoorType::Click() { return this.ClickSpecial(2, 3, 0, 0); } /********************************************************************** ***********************************************************************/ int DoorType::Init(Object *o_Objekt, Hotspot *h_Hotspot) { if ( null != o_Objekt ) { o_Objekt.Clickable = false; // die Türenobjekte nicht Klickbar machen if ( this.i_GlobalInt == 1 ) o_Objekt.Visible = true; else o_Objekt.Visible = false; if ( this.l_Room == player.Room ) { this.o_Objekt = o_Objekt; } else if ( this.l_NewRoom == player.Room ) { this.o_NewObjekt = o_Objekt; } } if ( null != h_Hotspot ) { if ( this.l_Room == player.Room ) { this.h_Hotspot = h_Hotspot; } else if ( this.l_NewRoom == player.Room ) { this.h_NewHotspot = h_Hotspot; } } } /********************************************************************** ***********************************************************************/ int walk_to_x, walk_to_y; CharacterDirection walk_to_dir; function SetWalkTo(int x, int y, CharacterDirection dir) { walk_to_x = x; walk_to_y = y; walk_to_dir = dir; } function MovedTo() { return any_click_move (walk_to_x, walk_to_y, walk_to_dir); } function WalkedToLookedAt(string lookat) { return any_click_walk_look (walk_to_x, walk_to_y, walk_to_dir, lookat); } function UsedInvItem(int item) { return any_click_use_inv (item, walk_to_x, walk_to_y, walk_to_dir); } function WalkedToLookedAtPickedUp(string lookat, Object *objekt, InventoryItem *item, int GI, int sound) { return any_click_walk_look_pick (walk_to_x, walk_to_y, walk_to_dir, lookat, objekt, item, GI, sound); } /////////////////////////////////////// // Background queued talking v1.02 /////////////////////////////////////// #define BUFFER_SIZE 300 #define AGS_STRING_LENGTH 200 struct MESSAGESTRING { Character *CharID; int anim_disabled; String byte; }; MESSAGESTRING Buffer[BUFFER_SIZE]; function mod(int a, int b) { return a - (b*(a/b)); } function BufferSetString(int sID, String text) { if (sID<0 || sID>=BUFFER_SIZE) { Display("error: SetString buffer error!"); QuitGame(0); } Buffer[sID].byte = text; return text.Length; } String BufferGetString(int sID) { if (sID<0 || sID>=BUFFER_SIZE) { Display("error: GetString buffer error!"); QuitGame(0); } return Buffer[sID].byte; } int cur_str=0; int cur_say=0; int stop_talk = 0; int cur_channel = -1; Overlay *currentOverlay; Character *prev_char; function qDisplaySpeech(Character *CharID, String message) { int i = mod(cur_str, BUFFER_SIZE); BufferSetString(i, message); Buffer[i].CharID = CharID; cur_str++; if (cur_str >= BUFFER_SIZE) cur_str = 0; } function qIsTalking() { if ( null != currentOverlay ) return currentOverlay.Valid; } function GetSoundNumber(String text) //return 0 if unsuccessful { int pos = text.Contains("@"); if ( pos < 0 ) return 0; int i = pos + 1; String str_rez = ""; int Charr = text.Chars[i]; while ( Charr >= '0' && Charr <= '9' && i < text.Length ) { str_rez = String.Format("%s%c", str_rez, Charr); i++; Charr = text.Chars[i]; } while ( i <= text.Length ) { text = text.ReplaceCharAt(pos, text.Chars[i]); i++; pos++; } return str_rez.AsInt; } function GetFreeChannel() // returns a channel number { if ( IsChannelPlaying(5) == 0 ) return 5; else if ( IsChannelPlaying(4) == 0 ) return 4; else return 3; } function qStopSpeechChannel() { if ( cur_channel > 2 ) if ( IsChannelPlaying(cur_channel) ) { StopChannel(cur_channel); cur_channel = -1; } } function qStopSpeech() { if (qIsTalking()) { qStopSpeechChannel(); currentOverlay.Remove(); int i = mod(cur_say, BUFFER_SIZE); Character *CharID = Buffer[i].CharID; if ( null != CharID ) CharID.UnlockView(); if ( null != prev_char ) { prev_char.UnlockView(); prev_char = null; } stop_talk = 0; cur_say = cur_str; } } function DisplaySpeechQ_RE() { if (qIsTalking()==0) // wait for character to finish talking { if (cur_say < cur_str) // if something left to be said { int i = mod(cur_say, BUFFER_SIZE); Character *CharID = Buffer[i].CharID; String buf; buf = BufferGetString(i); qStopSpeechChannel(); int cur_sound = GetSoundNumber(buf); cur_channel = GetFreeChannel(); if ( cur_sound > 0 ) PlaySoundEx(cur_sound, cur_channel); currentOverlay = CharID.SayBackground(buf); stop_talk = 1; if ( null != prev_char ) prev_char.UnlockView(); prev_char = CharID; if ( CharID.Animating == 0 && Buffer[ i ].anim_disabled == 0 ) { int view = CharID.SpeechView + 1; if (view < 1) { Display("error: Talk view isn't assigned!"); QuitGame(0); } int loop = CharID.Loop; int delay = CharID.AnimationSpeed; CharID.LockView(view); CharID.Animate(loop, delay, eRepeat, eNoBlock, eForwards); } Buffer[i].anim_disabled = 0; cur_say++; if (cur_say >= BUFFER_SIZE) cur_say = 0; } else if (stop_talk) { //finish talk animation if ( null != prev_char ) { prev_char.UnlockView(); prev_char = null; } qStopSpeechChannel(); stop_talk = 0; } } // end of if (qIsTalking()==0) } String str_delay; String Delay(int time) { int n = time; if ( n < 1 ) n = 1; else if ( n >= AGS_STRING_LENGTH ) n = AGS_STRING_LENGTH - 1; String format; format = String.Format("%%%dc", n); str_delay = String.Format(format, ' '); Buffer[mod(cur_str, BUFFER_SIZE)].anim_disabled = 1; return str_delay; } function qSkipCurrentMessage() { if ( qIsTalking() ) currentOverlay.Remove(); } void SetChangeablePlayers() { // für Characterwechselfunktionen und mit AddChangePlayer(Character *cha) können die Mitspieler hinzugefügt werden // Inventar wird automatisch angepasst cSandy.AddPlayerToSwitch(699); cMarcy.AddPlayerToSwitch(704); cMandy.AddPlayerToSwitch(705); cAndy.AddPlayerToSwitch(708); cWendy.AddPlayerToSwitch(702); cBritney.AddPlayerToSwitch(703); cWink.AddPlayerToSwitch(701); cMichael.AddPlayerToSwitch(707); cBernard.AddPlayerToSwitch(697); cJeff.AddPlayerToSwitch(712); cMark.AddPlayerToSwitch(713); cSyd.AddPlayerToSwitch(698); cDave.AddPlayerToSwitch(700); cEd.AddPlayerToSwitch(709); cFred.AddPlayerToSwitch(710); cEdna.AddPlayerToSwitch(711); cRazor.AddPlayerToSwitch(27); } // ============================= game_start =========================================== function game_start () { int i = 0; Game.SetSaveGameDirectory("."); // called when the game starts, before the first room is loaded // --- translate GUI action buttons --- AdjustLanguage(); ovChar = null; // g_PlayerCanMove = 1; // ist im 'Global variables' Dialog bereits vorbelegt // (0=steht; 1=kann sich bewegen) while ( i < DOORS_MAX ) { i_Doors[i] = 0; i++; } InvWindow *invWin; // --- initialize game settings --- game.dialog_options_y = 1; game.dialog_options_x = 1; if ( invWin ) { invWin.ItemHeight = 40; invWin.ItemWidth = 24; } game.text_speed = 10; SetDefaultAction (eActWalkTo); gMaps.Visible = false; // Für Debug-Aktionen ohne daß die Option 'Enable Debug-Mode' weggenommen wird debugfile = File.Open(HIDDEN_DEBUG_STRING, eFileRead); // steht nur zur Verfügung, wenn die Datei MMM_GO vorhanden ist SetChangeablePlayers(); DoorSetup(); v_GameSettingsSet(); } // ============================= on_mouse_click =========================================== // this section after GoToCharacter #sectionstart on_mouse_click // DO NOT EDIT OR REMOVE THIS LINE function on_mouse_click (int button) { // called when a mouse button is clicked. button is either LEFT or RIGHT int mrx = mouse.x + GetViewportX (); int mry = mouse.y + GetViewportY (); Object *objAt; Hotspot *hotAt; Character *charAt; InventoryItem *invAt; objAt = Object.GetAtScreenXY(mouse.x, mouse.y); hotAt = Hotspot.GetAtScreenXY(mouse.x, mouse.y); charAt = Character.GetAtScreenXY(mouse.x, mouse.y); invAt = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); // get location under mouse cursor GSloctype = GetLocationType (mouse.x, mouse.y); if (GSloctype == 1) GSlocid = hotAt.ID; else if (GSloctype == 2) GSlocid = charAt.ID; else if (GSloctype == 3) GSlocid = objAt.ID; else if ( null != invAt ) GSlocid = invAt.ID; GSlocname = Game.GetLocationName (mouse.x, mouse.y); GSagsusedmode = Mouse.Mode; used_action = global_action; if (IsGamePaused () == 1) { // Game is paused, so do nothing (ie. don't allow mouse click) } else if ( gMaps.Visible ) { // if map if (button == eMouseLeft) { if (IsInteractionAvailable (mouse.x, mouse.y, eModeUseinv)) Room.ProcessClick (mouse.x, mouse.y, eModeUseinv); //MODE_USE else Room.ProcessClick (mouse.x, mouse.y, eModeWalkto); } } //end if map else if (button == eMouseLeft) { if ( GlobalCondition(2) || GlobalCondition(3) || GlobalCondition(4) ) { } else if ( GSagsusedmode == 9 ) { gAktionText.TextColor = ActionLabelColorHighlighted; if ( IsInteractionAvailable(mouse.x, mouse.y, GSagsusedmode) ) { Room.ProcessClick(mrx - GetViewportX(), mry - GetViewportY(), GSagsusedmode); } else { Room.ProcessClick(mrx - GetViewportX(), mry - GetViewportY(), eModeWalkto); } } else if ( (GSagsusedmode == eModeTalkto) && (IsInteractionAvailable(mouse.x, mouse.y, GSagsusedmode) == 1) ) { gAktionText.TextColor = ActionLabelColorHighlighted; charAt.RunInteraction(GSagsusedmode); SetAction(eActDefault); } else { UpdateActionBar(); gAktionText.TextColor = ActionLabelColorHighlighted; Room.ProcessClick(mrx - GetViewportX(), mry - GetViewportY(), GSagsusedmode); SetAction(eActDefault); } } //end if button left else if (button == eMouseRight) { if (alternative_action == eActDefault) { SetAction (eActDefault); gAktionText.TextColor = ActionLabelColorHighlighted; if (Mouse.Mode == 9) Room.ProcessClick (mrx - GetViewportX (), mry - GetViewportY (), eModeWalkto); else Room.ProcessClick (mrx - GetViewportX (), mry - GetViewportY (), Mouse.Mode ); } else { SetAction (alternative_action); used_action = global_action; UpdateActionBar (); gAktionText.TextColor = ActionLabelColorHighlighted; GSagsusedmode = Mouse.Mode; if ((GSagsusedmode == eModeTalkto) && (IsInteractionAvailable (mouse.x, mouse.y, GSagsusedmode) == 1) && (charAt.ID < 7)) { if ( null != charAt ) charAt.RunInteraction(GSagsusedmode); } else Room.ProcessClick (mrx - GetViewportX (), mry - GetViewportY (), GSagsusedmode); SetAction (eActDefault); } } else if (button == eMouseLeftInv) { //left click in inventory if (GlobalCondition (1)) { // if the mouse is in the inventory and modes Walk or pickup are selected SetAction (eActUse); if ((GSinvloc.Extension() == 'u') && ( invAt.IsInteractionAvailable(eModeInteract) == 1 )) { // use it immediately (not with anything else) used_action = global_action; if ( null != invAt ) invAt.RunInteraction(eModeInteract); SetAction (eActDefault); } else { if ( null != invAt ) player.ActiveInventory = invAt; } } else if (GlobalCondition (2) == 1) { // if the mode is useinv and the mouse is over the active inv (like "use knife on knife") } else { used_action = global_action; if ( Mouse.Mode == 2 ) { if (isAction (eActUse) && invAt.IsInteractionAvailable(eModeUseinv) == 1) { gAktionText.TextColor = ActionLabelColorHighlighted; if ( invAt ) invAt.RunInteraction(eModeUseinv); SetAction (eActDefault); } else player.ActiveInventory = invAt; } else { GSagsusedmode = Mouse.Mode; gAktionText.TextColor = ActionLabelColorHighlighted; if ( invAt ) invAt.RunInteraction(Mouse.Mode); SetAction (eActDefault); } } /* diese Zeile ist neu und verhindert, dass der Mauscursor nach Anwahl eines Inventargegenstandes springt und einen falschen Hotspotpunkt hat */ Mouse.ChangeModeHotspot(eModeUseinv, 7, 7); } 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) //IsInventoryInteractionAvailable (GSlocid, MODE_USE) == 1) { UpdateActionBar (); gAktionText.TextColor = ActionLabelColorHighlighted; if ( invAt ) invAt.RunInteraction(eModeUseinv); SetAction (eActDefault); } else player.ActiveInventory = invAt; } else { UpdateActionBar (); gAktionText.TextColor = ActionLabelColorHighlighted; if ( invAt ) invAt.RunInteraction(Mouse.Mode); SetAction (eActDefault); } } } } #sectionend on_mouse_click // DO NOT EDIT OR REMOVE THIS LINE // ============================= repeatedly_execute =========================================== // this section after on_mouse_click #sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE 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 ( null != invMain.ItemAtIndex[0] ) { if ( 0 != gMainInventory.TopItem ) { // if inventory can scroll up #ifdef SCROLL_INVENTORY int visible_items = (invMain.Width / invMain.ItemWidth) * (invMain.Height / invMain.ItemHeight); if ( invMain.ItemCount > visible_items ) // Hier wird nur nachfolgende Zeile ausgeführt, wenn das Inventar automatisch gescrollt werden soll #endif gMainInvUp.NormalGraphic = invUparrowONsprite; #ifdef SCROLL_INVENTORY InventoryItem *invItem = InventoryItem.GetAtScreenXY(180, 190); if ( null == invItem ) { gMainInventory.ScrollUp(); } #endif #ifndef SCROLL_INVENTORY InventoryItem *invItem = InventoryItem.GetAtScreenXY(180, 160); if ( null == invItem ) { } else if (invItem.ID < 0) { gMainInventory.ScrollUp(); } #endif } else { gMainInvUp.NormalGraphic = invUparrowOFFsprite; } } if ( (gMainInventory.TopItem + (gMainInventory.ItemsPerRow * gMainInventory.RowCount)) < gMainInventory.ItemCount ) { gMainInvDown.NormalGraphic = invDownarrowONsprite; } else { gMainInvDown.NormalGraphic = invDownarrowOFFsprite; } } #sectionend repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE // ============================= on_key_press =========================================== function on_key_press (int keycode) { // called when a key is pressed. keycode holds the key's ASCII code // --- PAUSE-GUI --- if (keycode == 32) { // SPACEBAR if (IsGamePaused () == 0) { gPaused.Visible = true; DisableInterface (); } else { gPaused.Visible = false; EnableInterface (); } } // --- RESTART-GUI --- else if ( gRestart.Visible ) { // if restart gui is on if ((keycode == key_u_no) || (keycode == key_l_no)) gRestart.Visible = false; // if N is pressed continue if ((keycode == key_u_yes) || (keycode == key_l_yes)) RestartGame (); // if Y is pressed restart game } // --- QUITGAME-GUI --- else if ( gConfirmexit.Visible ) { // if exit gui is on if ((keycode == key_u_no) || (keycode == key_l_no)) gConfirmexit.Visible = false; // if N is pressed continue if ((keycode == key_u_yes) || (keycode == key_l_yes)) QuitGame (0); // if Y is pressed quit game } if ( IsGamePaused () == 1 ) keycode = 0; // game paused, so don't react to keypresses // --- Switch Players --- if ( keycode == eKeyF5 ) gOptions.Visible = true; if ( keycode == eKeyF8 ) gRestart.Visible = true; if ( keycode == eKeyCtrlC ) gConfirmexit.Visible = true; if ( keycode == eKeyF12 ) SaveScreenShot ("scrnshot.bmp"); #ifdef HIDDEN_DEBUG_ENABLED // spezielles Debugverhalten if ( keycode == eKeyCtrlS && null != debugfile ) Debug(0,0); // give all inventory if ( keycode == eKeyCtrlV && null != debugfile ) Debug(1,0); // version if ( keycode == eKeyCtrlA && null != debugfile ) Debug(2,0); // show walkable areas if ( keycode == eKeyCtrlX && null != debugfile ) Debug(3,0); // teleport to room // Debug 4 ist noch möglich (fps) if ( keycode == eKey1 && null != debugfile ) Flashlight.Enabled = true; if ( keycode == eKey2 && null != debugfile ) Flashlight.Enabled = false; if ( keycode == eKey3 && null != debugfile ) v_Flashlight(true); if ( keycode == eKey4 && null != debugfile ) v_Flashlight(false); if ( keycode == eKeyUpArrow && null != debugfile ) Flashlight.Transparency++; if ( keycode == eKeyDownArrow && null != debugfile ) Flashlight.Transparency--; if ( keycode == eKey5 && null != debugfile ) Flashlight.Radius++; if ( keycode == eKey6 && null != debugfile ) Flashlight.Radius--; if ( keycode == eKey7 && null != debugfile ) gMaingui.Visible = false; if ( keycode == eKey8 && null != debugfile ) gMaingui.Visible = true; #endif #ifndef HIDDEN_DEBUG_ENABLED // normals Debugverhalten if ( keycode == eKeyCtrlS ) Debug(0,0); // give all inventory if ( keycode == eKeyCtrlV ) Debug(1,0); // version if ( keycode == eKeyCtrlA ) Debug(2,0); // show walkable areas if ( keycode == eKeyCtrlX ) Debug(3,0); // teleport to room #endif // --- triggering actions by the keys:--- int action = 0; while (action < eActCount) { if ((keycode == action_l_keycode [action]) || (keycode == action_u_keycode [action])) { SetAction (action); action = eActCount; } else { action++; } } } // gMain function gMainInvUp_OnClick(GUIControl *control, MouseButton button) { if ( gOptions.Visible || gRestore.Visible || gSave.Visible ) { // disable GUI, when other GUI is on } else if (gMainInventory.TopItem > 0) { gMainInventory.ScrollUp(); } } function gMainInvDown_OnClick(GUIControl *control, MouseButton button) { if ( gOptions.Visible || gRestore.Visible || gSave.Visible ) { // disable GUI, when other GUI is on } else if ((gMainInventory.TopItem + gMainInventory.ItemsPerRow + gMainInventory.RowCount) < gMainInventory.ItemCount) //game.top_inv_item < game.num_inv_items - game.num_inv_displayed) { gMainInventory.ScrollDown(); } } function gMainGive_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [0]); } function gMainPickup_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [1]); } function gMainUse_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [2]); } function gMainOpen_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [3]); } function gMainLookat_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [4]); } function gMainPush_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [5]); } function gMainClose_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [6]); } function gMainTalkto_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [7]); } function gMainPull_OnClick(GUIControl *control, MouseButton button) { SetAction (button_action [8]); } function gMaingui_OnClick(GUI *theGui, MouseButton button) { SetAction (button_action [button]); } // gOptions function gOptSave_OnClick(GUIControl *control, MouseButton button) { gOptions.Visible = false; gSave.GetLucasSavegameListBox(lstSave); gSave.Visible = true; } function gOptLoad_OnClick(GUIControl *control, MouseButton button) { gOptions.Visible = false; gRestore.GetLucasSavegameListBox(lstRestore); gRestore.Visible = true; } function gOptPlay_OnClick(GUIControl *control, MouseButton button) { gOptions.Visible = false; } function gOptExit_OnClick(GUIControl *control, MouseButton button) { gConfirmexit.Visible = true; } // gRestore function gRstCancel_OnClick(GUIControl *control, MouseButton button) { gRestore.Visible = false; } function lstRestore_OnSelectionChanged(GUIControl *control) { int index = lstRestore.SelectedIndex; if ( null != Game.GetSaveSlotDescription (index + 100) ) { gRestore.Visible = false; RestoreGameSlot (index + 100); } } function gRstUp_OnClick(GUIControl *control, MouseButton button) { if (GStopsaveitemRestore < 5) GStopsaveitemRestore = 0; else GStopsaveitemRestore -= 5; lstRestore.TopItem = GStopsaveitemRestore; } function gRstDown_OnClick(GUIControl *control, MouseButton button) { if ( GStopsaveitemRestore < 95 ) { GStopsaveitemRestore += 5; lstRestore.TopItem = GStopsaveitemRestore; } } // gSave function lstSave_OnSelectionChanged(GUIControl *control) { String sDescription; int stbypos; int index = lstSave.SelectedIndex; sDescription = String.Format("%d. ", index + 1); gSaveTextBoxlbl.Text = sDescription; sDescription = Game.GetSaveSlotDescription(index + 100); if ( null == sDescription ) { sDescription = ""; } gSaveTextBox.Text = sDescription; gSaveTextBox.SetPosition(GetTextWidth(gSaveTextBoxlbl.Text, gSaveTextBoxlbl.Font) - 1, - 1); int x = gSave.X + lstSave.X + gSaveTextBoxlbl.X; int y = gSave.Y + lstSave.Y + ((index - lstSave.TopItem) * gSavetextbox.Height + 1); gSavetextbox.SetPosition(x, y); gSavetextbox.Visible = true; } function gSaveSave_OnClick(GUIControl *control, MouseButton button) { String buffer; int index = lstSave.SelectedIndex; if ( index >= 0 ) { buffer = gSaveTextBox.Text; gSave.Visible = false; gSavetextbox.Visible = false; SaveGameSlot (index + 100, buffer); } } function gSaveUp_OnClick(GUIControl *control, MouseButton button) { gSavetextbox.Visible = false; if (GStopsaveitemSave < 5) { GStopsaveitemSave = 0; } else { GStopsaveitemSave -= 5; } lstSave.TopItem = GStopsaveitemSave; if ( lstSave.SelectedIndex >= lstSave.TopItem && lstSave.SelectedIndex <= lstSave.TopItem + 8 ) { lstSave_OnSelectionChanged(control); } } function gSaveDown_OnClick(GUIControl *control, MouseButton button) { gSavetextbox.Visible = false; if ( GStopsaveitemSave < 95 ) { GStopsaveitemSave += 5; lstSave.TopItem = GStopsaveitemSave; } if ( lstSave.SelectedIndex >= lstSave.TopItem && lstSave.SelectedIndex <= lstSave.TopItem + 8 ) { lstSave_OnSelectionChanged(control); } } function gSaveAbbruch_OnClick(GUIControl *control, MouseButton button) { gSave.Visible = false; gSavetextbox.Visible = false; } // gSavetextbox function gSavetextbox_OnClic(GUI *theGui, MouseButton button) { if (button == eMouseRight) gSavetextbox.Visible = false; } function gSaveTextBox_OnActivate(GUIControl *control) { int index = lstSave.SelectedIndex; gSave.Visible = false; gSavetextbox.Visible = false; SaveGameSlot (index + 100, gSaveTextBox.Text); } // gConfirm function gConfirmYes_OnClick(GUIControl *control, MouseButton button) { QuitGame (0); } function gConfirmNo_OnClick(GUIControl *control, MouseButton button) { gConfirmexit.Visible = false; } function SayIfAction(this Character*, eAction action, String message) { if ( UsedAction(action) ) this.Say(message); } bool SayIfPlayer(this Character*, String message) { if ( player == this ) { player.Say(message); return true; } return false; } #sectionstart on_event // DO NOT EDIT OR REMOVE THIS LINE function on_event (int event, int data) { if (event == eEventLeaveRoom) { qStopSpeech(); } if (event == eEventRestoreGame) { AdjustLanguage(); CallRoomScript(GAME_RESTORED); } if ((event == eEventEnterRoomBeforeFadein) || (event == eEventRestoreGame)) { player.PlaceOnWalkableArea(); } } #sectionend on_event // DO NOT EDIT OR REMOVE THIS LINE #sectionstart dialog_request // DO NOT EDIT OR REMOVE THIS LINE function dialog_request (int param) { } #sectionend dialog_request // DO NOT EDIT OR REMOVE THIS LINE #sectionstart unhandled_event // DO NOT EDIT OR REMOVE THIS LINE function unhandled_event (int xxx, int yyy) { InventoryItem* invItem; int type = GSloctype; String locationname, usedinvname; String translation; translation = Game.TranslationFilename; invItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); locationname = GSlocname.RemoveExtension(); if ( null != invItem ) if (invItem.ID >= 0) type = 4; if (GSagsusedmode == 4) { int i = 0; invItem = player.ActiveInventory; if ( null != invItem ) { i = invItem.ID; if (i >= 0) { usedinvname = invItem.Name; usedinvname = usedinvname.RemoveExtension(); if (type > 0) type += 4; } } } if (GSagsusedmode != 9 && type != 0) { //Check modes with: if(UsedAction(A_???)), check types by if(type==#). types: //1 a hotspot //2 a character //3 an object //4 an inventory item. //5 inv. item on hotspot //6 inv. item on character //7 inv. item on object //8 inv. item on inv. item // // You have the string "locationname" that is the name of // // what you clicked on, and the string "usedinvname" that is // // the name of the item that was used on where you clicked (only for types 5,6,7,8) // // REPLACE THIS SAMPLE INTERACTIONS WITH YOURS: if (type == 2 || type == 6) { Character *charAt; charAt = Character.GetAtScreenXY(mouse.x, mouse.y); if ( charAt ) { player.FaceCharacter(charAt); } } if (UsedAction (eActClose)) { player.Say("Besser nicht."); } else if (UsedAction (eActUse) && type >= 5) { //if inv on inv: player.Say("Tja, scheint nicht zu klappen."); } else if (UsedAction (eActLookAt)) { player.Say("Toll."); } else if ((UsedAction (eActPush)) || (UsedAction (eActPull))) { player.Say("Da tut sich nichts."); } else if (UsedAction (eActPickUp)) { player.Say("Da bewegt sich nichts."); } else if (UsedAction (eActOpen)) { player.Say("Es scheint nicht aufzugehen."); } else if (UsedAction (eActTalkTo)) { if (type == 2) { player.Say("Selbstgespräche zu führen kann Schizophrenie erzeugen. Also führe ich keine."); } else player.Say("Das klappt so nicht."); } else if (type == 4) { player.Say("Das klappt so nicht."); } else if (UsedAction (eActUse) || UsedAction (eActUseInventory)) { player.Say("Besser nicht."); } } } #sectionend unhandled_event // DO NOT EDIT OR REMOVE THIS LINE //////////////////////////////////////////////////////////////////////////////////// function Unhandled() { unhandled_event (0, 0); } function Unhandled_Inventory() { if (UsedAction(eActPickUp)) { Wait(5); player.Say("Das hab ich schon bei mir. Ich kann es nicht noch einmal aufnehmen."); } else if (UsedAction(eActPull)) { Wait(5); player.Say("Wozu?"); } else if (UsedAction(eActPush)) { Wait(5); player.Say("Es bewegt sich nicht."); } else if (UsedAction(eActOpen)) { Wait(5); player.Say("Das lässt sich nicht öffnen."); } else if (UsedAction(eActClose)) { Wait(5); player.Say("Das lässt sich nicht schließen."); } else Unhandled(); } function Unhandled_Character() { if (UsedAction(eActWalkTo)) { // Wait(5); } else if (UsedAction(eActLookAt)) { Wait(5); player.Say("Das ist jemand anderes."); } else if (UsedAction(eActPickUp)) { Wait(5); player.Say("Zu schwer."); } else if (UsedAction(eActPull)) { Wait(5); player.Say("Das bringt nichts."); } else if (UsedAction(eActPush)) { Wait(5); player.Say("Das bringt nichts."); } else if (UsedAction(eActClose)) { Wait(5); player.Say("Schließen? Gehts noch?"); } else if (UsedAction(eActOpen)) { Wait(5); player.Say("Öffnen? Gehts noch?"); } else if (UsedAction(eActUse)) { Wait(5); player.Say("Benutzen? Gehts noch?"); } else Unhandled(); } //Charakterköpfe function cc1_OnClick(GUIControl *control, MouseButton button) { SetChangePlayer(character[UpperButton()]); } function cc2_OnClick(GUIControl *control, MouseButton button) { SetChangePlayer(character[LowerButton()]); } export GSPlayerUp, GSPlayerDown; export debugfile; /* Inventargegenstände */ function iTaschenlampeOff_Look() { player.Say("Eine Mag-Light."); } function iTaschenlampeOff_OtherClick() { return Unhandled_Inventory(); } function iTaschenlampeOn_Look() { player.Say("Eine Mag-Light."); } function iTaschenlampeOn_OtherClick() { return Unhandled_Inventory(); } function iDuenger_Look() { player.Say("Eine Flasche Superdünger."); } function iDuenger_OtherClick() { return Unhandled_Inventory(); } /* Personen */ function cWiege_AnyClick() { if (any_click_move(292, 127, eDirectionDown)) { if (UsedAction(eActWalkTo)) { } else if (UsedAction(eActLookAt)) { Wait(5); if ( player == cEd ) { cEd.Say("Diese kleine Kröte hat mir fast mein Zimmer weggenommen."); Wait(10); cEd.Say("Aber ich habe es mir zurückerobert."); cEd.FaceDirection(eDirectionRight); Wait(60); cEd.FaceDirection(eDirectionDown); cEd.Say("Zumindest einen Teil davon."); } cFred.SayIfPlayer("Ich weiß immer noch nicht wie wir das zustande bekommen haben."); cEdna.SayIfPlayer("Es ist ja so niedlich."); if ( !player.IsEdison() ) { player.Say("Ich weiß nicht was es ist, aber es ist ziemlich ..."); Wait(40); player.FaceDirection(eDirectionLeft); Wait(40); player.FaceDirection(eDirectionDown); Wait(40); player.Say("... blau!"); } } else if (UsedAction(eActPickUp)) { Wait(5); player.Say("Ich lasse es lieber schlafen."); } else if (UsedAction(eActUseInventory)) { Wait(5); player.Say("Dann macht das Baby es kaputt."); } else Unhandled(); } } function cWiege_Talk() { if (any_click_move(292, 127, eDirectionDown)) { cEd.SayIfPlayer("Nie in meinem Leben."); cFred.SayIfPlayer("Es kann noch nicht reden."); cEdna.SayIfPlayer("Noch schreit es nur rum."); player.SayIfNotEdison("Es kann noch nicht reden."); } }