internal virtual void SetCameraFollows(Actor actor, bool setCamera = false) { _camera.Mode = CameraMode.FollowActor; _camera.ActorToFollow = actor.Number; if (!actor.IsInCurrentRoom) { StartScene(actor.Room); _camera.Mode = CameraMode.FollowActor; _camera.CurrentPosition.X = actor.Position.X; SetCameraAt(new Point(_camera.CurrentPosition.X, 0)); } int t = actor.Position.X / 8 - _screenStartStrip; if (t < _camera.LeftTrigger || t > _camera.RightTrigger || setCamera) SetCameraAt(new Point(actor.Position.X, 0)); for (int i = 1; i < Actors.Length; i++) { if (Actors[i].IsInCurrentRoom) Actors[i].NeedRedraw = true; } RunInventoryScript(0); }
void InitActors() { int numActors; if (Game.Version == 8) { numActors = 80; } else if (Game.Version == 7 || Game.GameId == GameId.SamNMax) { numActors = 30; } else if (Game.GameId == GameId.Maniac) { numActors = 25; } else { numActors = 13; } Actors = new Actor[numActors]; for (byte i = 0; i < Actors.Length; i++) { if (Game.Version == 0) { Actors[i] = new Actor0(this, i); } else if (Game.Version <= 2) { Actors[i] = new Actor2(this, i); } else if (Game.Version == 3) { Actors[i] = new Actor3(this, i); } else { Actors[i] = new Actor(this, i); } Actors[i].Init(-1); // this is from IDB if ((_game.Version <= 1) || (Game.GameId == GameId.Maniac && (Game.Features.HasFlag(GameFeatures.Demo)))) Actors[i].SetActorCostume(i); } if (Game.GameId == GameId.Maniac && Game.Version <= 1) { ResetV1ActorTalkColor(); } }
internal override void SetCameraFollows(Actor a, bool setCamera = false) { var oldfollow = Camera.ActorToFollow; Camera.ActorToFollow = a.Number; Variables[VariableCameraFollowedActor.Value] = a.Number; if (!a.IsInCurrentRoom) { StartScene(a.Room); } var ax = Math.Abs(a.Position.X - Camera.CurrentPosition.X); var ay = Math.Abs(a.Position.Y - Camera.CurrentPosition.Y); if (ax > Variables[VariableCameraThresholdX.Value] || ay > Variables[VariableCameraThresholdY.Value] || ax > (ScreenWidth / 2) || ay > (ScreenHeight / 2)) { SetCameraAt(a.Position); } if (a.Number != oldfollow) RunInventoryScript(0); }
internal byte WalkboxFindTarget(Actor a, int destbox, Point walkdest) { var actor = (Actor0)a; byte nextBox = (byte)GetNextBox(a.Walkbox, (byte)destbox); if (nextBox != 0xFF && nextBox == destbox && AreBoxesNeighbors(a.Walkbox, nextBox)) { actor.NewWalkTo = walkdest; return nextBox; } if (nextBox != 0xFF && nextBox != a.Walkbox) { Point p; ScummMath.GetClosestPtOnBox(GetBoxCoordinates(nextBox), a.Position, out p); actor.NewWalkTo = p; } else { if (walkdest.X == -1) actor.NewWalkTo = actor.CurrentWalkTo; else actor.NewWalkTo = walkdest; } return nextBox; }
internal bool HandleNextCharsetCode(Actor a, ref int code) { int color, frme, c = 0, oldy; bool endLoop = false; var bufferPos = _charsetBufPos; while (!endLoop) { c = _charsetBuffer[bufferPos++]; if (!(c == 0xFF || (Game.Version <= 6 && c == 0xFE))) { break; } c = _charsetBuffer[bufferPos++]; if (NewLineCharacter != 0 && c == NewLineCharacter) { c = 13; break; } switch (c) { case 1: c = 13; // new line endLoop = true; break; case 2: _haveMsg = 0; _keepText = true; endLoop = true; break; case 3: _haveMsg = (_game.Version >= 7) ? 1 : 0xFF; _keepText = false; endLoop = true; break; case 8: // Ignore this code here. Occurs e.g. in MI2 when you // talk to the carpenter on scabb island. It works like // code 1 (=newline) in verb texts, but is ignored in // spoken text (i.e. here). Used for very long verb // sentences. break; case 9: frme = _charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8); bufferPos += 2; if (a != null) a.StartAnimActor(frme); break; case 10: // Note the similarity to the code in debugMessage() { var talkSound_a = (_charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8) | (_charsetBuffer[bufferPos + 4] << 16) | (_charsetBuffer[bufferPos + 5] << 24)); var talkSound_b = (_charsetBuffer[bufferPos + 8] | (_charsetBuffer[bufferPos + 9] << 8) | (_charsetBuffer[bufferPos + 12] << 16) | (_charsetBuffer[bufferPos + 13] << 24)); bufferPos += 14; Sound.TalkSound(talkSound_a, talkSound_b, 2); _haveActorSpeechMsg = false; } break; case 12: color = _charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8); bufferPos += 2; if (color == 0xFF) _charset.SetColor(_charsetColor); else _charset.SetColor((byte)color); break; case 13: //debug(0, "handleNextCharsetCode: Unknown opcode 13 %d", READ_LE_UINT16(buffer)); bufferPos += 2; break; case 14: oldy = _charset.GetFontHeight(); _charset.SetCurID(_charsetBuffer[bufferPos++]); bufferPos += 2; Array.Copy(_charsetData[_charset.GetCurId()], CharsetColorMap, 4); _nextTop -= _charset.GetFontHeight() - oldy; break; default: throw new NotSupportedException(string.Format("handleNextCharsetCode: invalid code {0}", c)); } } _charsetBufPos = bufferPos; code = c; return (c != 2 && c != 3); }
internal void StartScene(byte room, Actor a = null, int objectNr = 0) { StopTalk(); FadeOut(_switchRoomEffect2); _newEffect = _switchRoomEffect; if (CurrentScript != 0xFF) { if (_slots[CurrentScript].Where == WhereIsObject.Room || _slots[CurrentScript].Where == WhereIsObject.FLObject) { //nukeArrays(CurrentScript); CurrentScript = 0xFF; } else if (_slots[CurrentScript].Where == WhereIsObject.Local) { //if (slots[CurrentScript].cutsceneOverride && _game.version >= 5) // error("Script %d stopped with active cutscene/override in exit", slots[CurrentScript].number); //nukeArrays(CurrentScript); CurrentScript = 0xFF; } } if (VariableNewRoom.HasValue) _variables[VariableNewRoom.Value] = room; RunExitScript(); KillScriptsAndResources(); if (_game.Version >= 4) { StopCycle(0); } for (var i = 1; i < Actors.Length; i++) { Actors[i].Hide(); } if (Game.Version >= 7) { // Set the shadow palette(s) to all black. This fixes // bug #795940, and actually makes some sense (after all, // shadows tend to be rather black, don't they? ;-) Array.Clear(_shadowPalette, 0, _shadowPalette.Length); } else { for (var i = 0; i < 256; i++) { Gdi.RoomPalette[i] = (byte)i; if (_shadowPalette != null) _shadowPalette[i] = (byte)i; } if (Game.Version < 5) { SetDirtyColors(0, 255); } } Variables[VariableRoom.Value] = room; _fullRedraw = true; _currentRoom = room; if (room >= 0x80 && Game.Version < 7) _roomResource = _resourceMapper[room & 0x7F]; else _roomResource = room; if (VariableRoomResource.HasValue) Variables[VariableRoomResource.Value] = _roomResource; if (room != 0) ResourceManager.LoadRoom(room); if (room != 0 && _game.Version == 5 && room == _roomResource) Variables[VariableRoomFlag.Value] = 1; ClearRoomObjects(); if (_currentRoom == 0) { if (roomData != null) { _ignoreEntryExitScript = true; roomData.ExitScript.Data = new byte[0]; //roomData.Objects.Clear(); } return; } roomData = _resManager.GetRoom(_roomResource); _ignoreEntryExitScript = false; if (roomData.HasPalette) { SetCurrentPalette(0); } Gdi.NumZBuffer = GetNumZBuffers(); Gdi.TransparentColor = roomData.TransparentColor; ResetRoomSubBlocks(); ResetRoomObjects(); _drawingObjects.Clear(); if (Game.Version >= 7) { // Resize main virtual screen in V7 games. This is necessary // because in V7, rooms may be higher than one screen, so we have // to accomodate for that. _mainVirtScreen = new VirtScreen(MainVirtScreen.TopLine, ScreenWidth, roomData.Header.Height - MainVirtScreen.TopLine, MainVirtScreen.PixelFormat, 2, true); } Gdi.SetMaskHeight(roomData.Header.Height); if (VariableRoomWidth.HasValue && VariableRoomHeight.HasValue) { Variables[VariableRoomWidth.Value] = roomData.Header.Width; Variables[VariableRoomHeight.Value] = roomData.Header.Height; } if (VariableCameraMinX.HasValue) { _variables[VariableCameraMinX.Value] = ScreenWidth / 2; } if (VariableCameraMaxX.HasValue) { _variables[VariableCameraMaxX.Value] = roomData.Header.Width - (ScreenWidth / 2); } if (Game.Version >= 7) { Variables[VariableCameraMinY.Value] = ScreenHeight / 2; Variables[VariableCameraMaxY.Value] = roomData.Header.Height - (ScreenHeight / 2); SetCameraAt(new Point((ScreenWidth / 2), (ScreenHeight / 2))); } else { _camera.Mode = CameraMode.Normal; _camera.CurrentPosition.X = _camera.DestinationPosition.X = (ScreenWidth / 2); _camera.CurrentPosition.Y = _camera.DestinationPosition.Y = (ScreenHeight / 2); } if (_roomResource == 0) return; Gdi.ClearGfxUsageBits(); if (_game.Version >= 5 && a != null) { var where = GetWhereIsObject(objectNr); if (where != WhereIsObject.Room && where != WhereIsObject.FLObject) throw new NotSupportedException(string.Format("StartScene: Object {0} is not in room {1}", objectNr, _currentRoom)); Point pos; int dir; GetObjectXYPos(objectNr, out pos, out dir); a.PutActor(pos, _currentRoom); a.SetDirection(dir + 180); a.StopActorMoving(); if (Game.GameId == Scumm.IO.GameId.SamNMax) { Camera.CurrentPosition.X = Camera.DestinationPosition.X = a.Position.X; SetCameraAt(a.Position); } } ShowActors(); EgoPositioned = false; TownsResetPalCycleFields(); RunEntryScript(); if (Game.Version >= 1 && Game.Version <= 2) { RunScript(5, false, false, new int[0]); } else if ((Game.Version >= 5) && (Game.Version <= 6)) { if (a != null && !EgoPositioned) { var pos = GetObjectXYPos(objectNr); a.PutActor(pos, _currentRoom); a.Moving = 0; } } else if (_game.Version >= 7) { if (Camera.ActorToFollow != 0) { a = Actors[Camera.ActorToFollow]; SetCameraAt(a.Position); } } _doEffect = true; // Hint the backend about the virtual keyboard during copy protection screens if (_game.GameId == GameId.Monkey2) { if (room == 108) _inputManager.ShowVirtualKeyboard(); else _inputManager.HideVirtualKeyboard(); } else if (_game.GameId == GameId.Monkey1 && _game.Variant == "ega") { // this is my estimation that the room code is 90 (untested) if (room == 90) _inputManager.ShowVirtualKeyboard(); else _inputManager.HideVirtualKeyboard(); } }