SupaLidlGame/Utils/World.cs

280 lines
7.2 KiB
C#
Raw Normal View History

2023-03-22 21:22:51 -07:00
using Godot;
using SupaLidlGame.Characters;
2023-07-25 03:47:31 -07:00
using SupaLidlGame.Extensions;
2023-03-26 10:53:45 -07:00
using SupaLidlGame.Scenes;
2023-03-22 21:22:51 -07:00
using System.Collections.Generic;
2023-03-26 10:53:45 -07:00
using System.Linq;
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
namespace SupaLidlGame.Utils;
public partial class World : Node2D
2023-03-22 21:22:51 -07:00
{
2023-06-03 18:21:46 -07:00
[Export]
public PackedScene StartingArea { get; set; }
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
[Export]
public Map CurrentMap { get; protected set; }
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
[Export]
public Player CurrentPlayer { get; set; }
2023-03-22 21:22:51 -07:00
2023-07-24 12:40:28 -07:00
[Export]
public Boss CurrentBoss { get; set; }
2023-07-22 20:23:48 -07:00
[Export]
2023-07-23 11:05:01 -07:00
public UI.UIController UIController { get; set; }
2023-07-22 20:23:48 -07:00
2023-07-24 00:43:21 -07:00
[Export]
public AudioStreamPlayer MusicPlayer { get; set; }
2023-07-25 03:47:31 -07:00
[Export]
public Dialogue.Balloon DialogueBalloon { get; set; }
2023-08-01 02:10:55 -07:00
public State.Global.GlobalState GlobalState { get; set; }
2023-08-01 23:49:48 -07:00
public Events.EventBus EventBus { get; set; }
2023-06-03 18:21:46 -07:00
private Dictionary<string, Map> _maps;
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
private string _currentConnector;
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
private string _currentMapResourcePath;
2023-03-26 10:53:45 -07:00
2023-06-10 22:15:28 -07:00
//private Entities.Campfire _lastCampfire = null;
public Vector2 SaveLocation { get; set; }
public string SaveMapKey { get; set; }
2023-06-06 18:39:23 -07:00
2023-06-03 18:21:46 -07:00
private const string PLAYER_PATH = "res://Characters/Player.tscn";
private PackedScene _playerScene;
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
public World()
{
_maps = new Dictionary<string, Map>();
_playerScene = ResourceLoader.Load<PackedScene>(PLAYER_PATH);
}
public override void _Ready()
{
2023-07-24 12:40:28 -07:00
// check if world already exists
2023-08-01 23:49:48 -07:00
GlobalState = this.GetGlobalState();
2023-08-01 02:10:55 -07:00
if (GlobalState.World is not null)
2023-07-24 12:40:28 -07:00
{
throw new System.InvalidOperationException();
}
2023-08-01 02:10:55 -07:00
GlobalState.World = this;
2023-07-24 12:40:28 -07:00
2023-07-19 01:25:02 -07:00
Godot.RenderingServer.SetDefaultClearColor(Godot.Colors.Black);
2023-07-24 12:40:28 -07:00
2023-06-03 18:21:46 -07:00
if (StartingArea is not null)
2023-03-22 21:22:51 -07:00
{
2023-06-03 18:21:46 -07:00
LoadScene(StartingArea);
2023-03-22 21:22:51 -07:00
}
2023-06-03 18:21:46 -07:00
// spawn the player in
CreatePlayer();
2023-03-26 10:53:45 -07:00
2023-06-06 18:39:23 -07:00
CurrentPlayer.Death += (Events.HealthChangedArgs args) =>
{
// TODO: respawn the player at the last campfire.
2023-08-01 23:49:48 -07:00
GetTree().CreateTimer(3).Timeout += () =>
2023-06-13 02:55:30 -07:00
{
SpawnPlayer();
};
2023-06-06 18:39:23 -07:00
};
2023-07-22 20:23:48 -07:00
CurrentPlayer.Hurt += (Events.HealthChangedArgs args) =>
{
2023-07-23 11:05:01 -07:00
// TODO: move this to UI controller and add a setup method
var bar = UIController.GetNode<UI.HealthBar>("Top/Margin/HealthBar");
2023-07-22 20:23:48 -07:00
bar.ProgressBar.Value = args.NewHealth;
};
2023-08-01 23:49:48 -07:00
EventBus = this.GetEventBus();
EventBus.RequestMoveToArea += (Events.RequestAreaArgs args) =>
{
GD.Print("request move to area");
MoveToArea(args.Area, args.Connector);
};
2023-06-03 18:21:46 -07:00
base._Ready();
}
2023-03-26 10:53:45 -07:00
2023-07-23 11:05:01 -07:00
public void RegisterBoss(Boss boss)
{
2023-07-24 12:40:28 -07:00
CurrentBoss = boss;
2023-07-23 11:05:01 -07:00
UIController.BossBar.Boss = boss;
2023-07-24 00:43:21 -07:00
MusicPlayer.Stream = boss.Music;
MusicPlayer.Play();
2023-07-23 11:05:01 -07:00
}
2023-07-24 12:40:28 -07:00
public void DeregisterBoss(Boss boss)
{
CurrentBoss = null;
UIController.BossBar.Boss = null;
MusicPlayer.Stop();
}
2023-06-10 22:15:28 -07:00
private void LoadMap(Map map)
2023-06-03 18:21:46 -07:00
{
2023-06-10 22:15:28 -07:00
GD.Print("Loading map " + map.Name);
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
if (CurrentMap is not null)
{
CurrentMap.Entities.RemoveChild(CurrentPlayer);
RemoveChild(CurrentMap);
CurrentMap.Active = false;
}
2023-03-26 13:03:45 -07:00
2023-06-03 18:21:46 -07:00
AddChild(map);
InitTilemap(map);
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
CurrentMap = map;
CurrentMap.Active = true;
2023-07-31 01:12:47 -07:00
CurrentMap.Load();
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
if (CurrentPlayer is not null)
2023-03-22 21:22:51 -07:00
{
2023-03-26 10:53:45 -07:00
CurrentMap.Entities.AddChild(CurrentPlayer);
2023-03-22 21:22:51 -07:00
}
2023-06-03 18:21:46 -07:00
}
2023-03-22 21:22:51 -07:00
2023-06-10 22:15:28 -07:00
public void LoadScene(PackedScene scene)
{
Map map;
if (_maps.ContainsKey(scene.ResourcePath))
{
map = _maps[scene.ResourcePath];
}
else
{
map = scene.Instantiate<Map>();
_maps.Add(scene.ResourcePath, map);
}
LoadMap(map);
}
public void LoadScene(string path)
{
Map map;
if (_maps.ContainsKey(path))
{
map = _maps[path];
}
else
{
var scene = ResourceLoader.Load<PackedScene>(path);
map = scene.Instantiate<Map>();
_maps.Add(scene.ResourcePath, map);
}
LoadMap(map);
}
2023-06-03 18:21:46 -07:00
public void CreatePlayer()
{
CurrentPlayer = _playerScene.Instantiate<Player>();
CurrentMap.Entities.AddChild(CurrentPlayer);
}
2023-03-22 21:22:51 -07:00
2023-06-03 18:21:46 -07:00
private void InitTilemap(Map map)
{
2023-08-01 23:49:48 -07:00
// this is being replaced with interaction triggers
2023-06-03 18:21:46 -07:00
var children = map.Areas.GetChildren();
foreach (Node node in children)
2023-03-26 10:53:45 -07:00
{
2023-06-03 18:21:46 -07:00
if (node is BoundingBoxes.ConnectorBox connector)
2023-03-26 10:53:45 -07:00
{
2023-06-03 18:21:46 -07:00
// this reconnects the EventHandler if it is connected
2023-08-01 23:49:48 -07:00
//connector.RequestedEnter -= _on_area_2d_requested_enter;
//connector.RequestedEnter += _on_area_2d_requested_enter;
2023-06-03 18:21:46 -07:00
}
2023-03-26 10:53:45 -07:00
}
2023-06-03 18:21:46 -07:00
}
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
private void MovePlayerToConnector(string name)
{
// find the first connector with the specified name
2023-08-01 23:49:48 -07:00
// TODO: replace this with event buses
//var connector = CurrentMap.Areas.GetChildren().First((child) =>
//{
// if (child is BoundingBoxes.ConnectorBox connector)
// {
// return connector.Identifier == name;
// }
// return false;
//}) as BoundingBoxes.ConnectorBox;
//CurrentPlayer.GlobalPosition = connector.GlobalPosition;
CurrentPlayer.GlobalPosition = Vector2.Zero;
2023-06-03 18:21:46 -07:00
}
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
public void MoveToArea(string path, string connector)
{
_currentConnector = connector;
if (path != _currentMapResourcePath)
2023-03-25 10:21:24 -07:00
{
2023-06-03 18:21:46 -07:00
var scene = ResourceLoader.Load<PackedScene>(path);
2023-08-01 23:49:48 -07:00
LoadScene(path);
2023-06-03 18:21:46 -07:00
_currentMapResourcePath = path;
2023-03-26 10:53:45 -07:00
}
2023-06-03 18:21:46 -07:00
// after finished loading, move our player to the connector
MovePlayerToConnector(connector);
}
2023-03-26 10:53:45 -07:00
2023-06-03 18:21:46 -07:00
public void _on_area_2d_requested_enter(
BoundingBoxes.ConnectorBox box,
Player player)
{
GD.Print("Requesting to enter " + box.ToConnector);
MoveToArea(box.ToArea, box.ToConnector);
}
public void SaveGame()
{
throw new System.NotImplementedException();
}
public void LoadGame()
{
throw new System.NotImplementedException();
2023-03-22 21:22:51 -07:00
}
2023-06-10 22:15:28 -07:00
/// <summary>
/// Sets the player's saved spawn position.
/// </summary>
/// <param name="position">The position to save and spawn the player in</param>
/// <param name="mapKey">
/// The map to spawn the player in. If <see langword="null" />, use the
/// <c>World</c>'s <c>CurrentMap</c>
/// </param>
public void SetSpawn(Vector2 position, string mapKey = null)
{
GD.Print("Set spawn");
if (mapKey is null)
{
mapKey = CurrentMap.SceneFilePath;
SaveLocation = position;
SaveMapKey = mapKey;
}
}
public void SpawnPlayer()
{
// TODO: add max health property
2023-06-13 02:55:30 -07:00
//CurrentPlayer.Health = 100;
//CurrentPlayer.Sprite.Visible = true;
2023-06-10 22:15:28 -07:00
if (CurrentMap.SceneFilePath != SaveMapKey)
{
LoadScene(SaveMapKey);
}
2023-06-13 02:55:30 -07:00
CurrentPlayer.GlobalPosition = SaveLocation;
CurrentPlayer.Spawn();
2023-06-10 22:15:28 -07:00
}
2023-07-25 03:47:31 -07:00
public Node FindEntity(string name) => CurrentMap.Entities.GetNode(name);
2023-03-22 21:22:51 -07:00
}