LADXHD/InGame/GameObjects/Things/ObjDoor.cs
2023-12-14 17:21:22 -05:00

251 lines
10 KiB
C#

using System;
using Microsoft.Xna.Framework;
using ProjectZ.InGame.GameObjects.Base;
using ProjectZ.InGame.GameObjects.Base.CObjects;
using ProjectZ.InGame.GameObjects.Base.Components;
using ProjectZ.InGame.GameSystems;
using ProjectZ.InGame.Map;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.Things
{
public class ObjDoor : GameObject
{
private Rectangle _collisionRectangle;
public string _entryId;
public string _nextMap;
private string _exitId;
private int _direction;
// 0: normal door
// 1: stairs
// 2: no walk in transition + fall
// 3: swim in transition
// 4: no walk in transition
// 5: final stairs transition
// 6: fall + rotate
// 7: fall
private int _mode;
private int _positionOffset;
private bool _isColliding;
private bool _wasColliding;
public bool _savePosition;
private bool _isTransitioning;
public ObjDoor() : base("editor door")
{
EditorColor = Color.Yellow * 0.65f;
}
public ObjDoor(Map.Map map, int posX, int posY, int width, int height,
string entryId, string nextMapId, string exitId, int direction, int mode, bool savePosition) : base(map)
{
EntityPosition = new CPosition(posX, posY, 0);
EntitySize = new Rectangle(0, 0, width, height);
// stairs have a smaller entry
if (Map.Is2dMap || mode != 1)
_collisionRectangle = new Rectangle(posX, posY, width, height);
else
{
_collisionRectangle = new Rectangle(posX + 6, posY + 6, width - 12, height - 12);
_positionOffset = 4;
}
if (mode == 4)
{
_collisionRectangle.Height = 10;
}
_entryId = entryId;
_direction = direction;
_mode = mode;
_savePosition = savePosition;
// has the player just entered this door?
if (_entryId != null && MapManager.ObjLink.NextMapPositionId == _entryId)
PlacePlayer();
_nextMap = nextMapId;
_exitId = exitId;
if (!string.IsNullOrEmpty(_nextMap) && !string.IsNullOrEmpty(_exitId))
{
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
AddComponent(ObjectCollisionComponent.Index,
new ObjectCollisionComponent(_collisionRectangle, OnCollision));
}
}
private void Update()
{
_wasColliding = _isColliding;
_isColliding = false;
}
private void OnCollision(GameObject gameObject)
{
// can jump over stair entries
if (_mode == 1 && !MapManager.ObjLink.IsGrounded() && !Map.Is2dMap)
return;
if (_mode == 3 && !MapManager.ObjLink.IsDiving() && !Map.Is2dMap)
return;
if (MapManager.ObjLink.IsRailJumping())
return;
_isColliding = true;
// first step on the door?
if (MapManager.ObjLink.WasHoleReset || MapManager.ObjLink.CurrentState == ObjLink.State.Dying || _wasColliding || _isTransitioning)
return;
_isTransitioning = true;
var transitionEnd = new Vector2(
_collisionRectangle.X + _collisionRectangle.Width / 2f,
_collisionRectangle.Y + _collisionRectangle.Height / 2f + MapManager.ObjLink._body.Height / 2f);
var color = Values.MapTransitionColor;
var colorMode = false;
if (_mode == 0)
{
if (_direction == 1)
transitionEnd.Y = _collisionRectangle.Y + 8;
else if (_direction == 3)
transitionEnd.Y = _collisionRectangle.Y + 16;
if (!Map.Is2dMap)
MapManager.ObjLink.Direction = (_direction + 2) % 4;
// walk on the ground
if (Map.Is2dMap && (_direction % 2) == 0)
transitionEnd.Y = _collisionRectangle.Bottom;
}
else if (_mode == 3)
{
if (Map.Is2dMap)
{
if (_direction == 0)
transitionEnd = MapManager.ObjLink.EntityPosition.Position + new Vector2(8, 0);
else if (_direction == 2)
transitionEnd = MapManager.ObjLink.EntityPosition.Position + new Vector2(-8, 0);
else if (_direction == 3)
transitionEnd = MapManager.ObjLink.EntityPosition.Position +
new Vector2(MapManager.ObjLink.GetSwimVelocity().X * 8, -8);
// look at the camera
MapManager.ObjLink.Direction = 3;
}
else
// do not move while transitioning out
transitionEnd = MapManager.ObjLink.EntityPosition.Position;
}
else if (_mode == 5)
{
transitionEnd = MapManager.ObjLink.EntityPosition.Position + MapManager.ObjLink._body.VelocityTarget * 60 * (MapTransitionSystem.ChangeMapTime / 1000f);
color = Color.White;
colorMode = true;
}
Game1.GameManager.PlaySoundEffect("D378-06-06");
MapManager.ObjLink.MapTransitionStart = MapManager.ObjLink.EntityPosition.Position;
MapManager.ObjLink.MapTransitionEnd = transitionEnd;
MapManager.ObjLink.TransitionOutWalking = MapManager.ObjLink.EntityPosition.Position != transitionEnd;
// append a map change
var transitionSystem = (MapTransitionSystem)Game1.GameManager.GameSystems[typeof(MapTransitionSystem)];
transitionSystem.AppendMapChange(_nextMap, _exitId, false, false, color, colorMode);
}
private void PlacePlayer()
{
_isColliding = true;
_wasColliding = true;
var transitionStart = new Vector2(
_collisionRectangle.X + _collisionRectangle.Width / 2f,
_collisionRectangle.Y + _collisionRectangle.Height / 2f + MapManager.ObjLink._body.Height / 2f);
var transitionEnd = transitionStart;
if (_mode == 0 || _mode == 1)
{
if (_direction == 0)
transitionEnd.X = _collisionRectangle.X - MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) - _positionOffset;
else if (_direction == 1)
transitionEnd.Y = _collisionRectangle.Y - _positionOffset;
else if (_direction == 2)
transitionEnd.X = _collisionRectangle.X + _collisionRectangle.Width + MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) + _positionOffset;
else if (_direction == 3)
transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height + _positionOffset;
// walk on the ground
if (Map.Is2dMap && (_direction % 2) == 0)
{
transitionStart.Y = _collisionRectangle.Bottom;
transitionEnd.Y = _collisionRectangle.Bottom;
}
}
else if (_mode == 2)
{
MapManager.ObjLink.NextMapFallStart = true;
}
else if (_mode == 3)
{
if (_direction == 0)
transitionEnd.X = _collisionRectangle.X - MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) - _positionOffset;
else if (_direction == 1)
transitionEnd.Y = _collisionRectangle.Y - _positionOffset;
else if (_direction == 2)
transitionEnd.X = _collisionRectangle.X + _collisionRectangle.Width + MathF.Ceiling(MapManager.ObjLink._body.Width / 2f) + _positionOffset;
else if (_direction == 3)
transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height + _positionOffset;
}
else if (_mode == 4)
{
// why was this here?
//transitionEnd.Y = _collisionRectangle.Y + _collisionRectangle.Height + MapManager.ObjLink._body.Height - _positionOffset;
}
else if (_mode == 5)
{
transitionEnd = transitionStart + new Vector2(0, -0.5f) * 60 * (MapTransitionSystem.ChangeMapTime / 1000f);
}
else if (_mode == 6)
{
MapManager.ObjLink.NextMapFallRotateStart = true;
}
if (_savePosition)
{
MapManager.ObjLink.SaveMap = Map.MapName;
MapManager.ObjLink.SavePosition = transitionEnd;
MapManager.ObjLink.SaveDirection = _direction;
// save settings?
if (GameSettings.Autosave)
{
SaveGameSaveLoad.SaveGame(Game1.GameManager);
Game1.GameManager.InGameOverlay.InGameHud.ShowSaveIcon();
}
}
MapManager.ObjLink.NextMapPositionStart = transitionStart;
MapManager.ObjLink.NextMapPositionEnd = transitionEnd;
MapManager.ObjLink.TransitionInWalking = transitionStart != transitionEnd;
MapManager.ObjLink.DirectionEntry = _direction;
// no transition (eg. fall into a 2d room)
if (_mode == 7)
{
MapManager.ObjLink.Fall2DEntry = true;
MapManager.ObjLink.NextMapPositionEnd = null;
}
}
}
}