using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
///
/// 办公格子/图块对象
///
public partial class Cube : StaticBody2D, ITileDraggable
{
// 定义各种家具的占用区域
private static readonly Rect2I tableRect = new(0, 0, 3, 2);
private static readonly Rect2I table2Rect = new(0, -1, 3, 1);
private static readonly Rect2I chairRect = new(1, 1, 1, 2);
private static readonly Rect2I chair2Rect = new(1, -2, 1, 2);
private static readonly Rect2I equipRect = new(0, 0, 3, 2);
private static readonly Rect2I equip2Rect = new(0, -1, 3, 1);
// 定义桌子的主题映射
private static readonly TileMapping[] tableThemes = {
new(new Vector2I(1, 30), tableRect),
new(new Vector2I(4, 30), tableRect),
new(new Vector2I(7, 30), tableRect),
new(new Vector2I(7, 28), tableRect),
new(new Vector2I(10, 28), tableRect),
};
// 定义第二种桌子的主题映射
private static readonly TileMapping[] table2Themes = {
new(new Vector2I(1, 31), table2Rect),
new(new Vector2I(4, 31), table2Rect),
new(new Vector2I(7, 31), table2Rect),
new(new Vector2I(7, 29), table2Rect),
new(new Vector2I(10, 29), table2Rect),
};
// 定义椅子的主题映射
private static readonly TileMapping[] chairThemes = {
new(new Vector2I(-1, 7), chairRect),
new(new Vector2I(0, 7), chairRect),
new(new Vector2I(-1, 9), chairRect),
new(new Vector2I(0, 9), chairRect),
};
// 定义第二种椅子的主题映射
private static readonly TileMapping[] chair2Themes = {
new(new Vector2I(-1, 10), chair2Rect),
new(new Vector2I(0, 10), chair2Rect),
new(new Vector2I(-1, 12), chair2Rect),
new(new Vector2I(0, 12), chair2Rect),
};
// 定义设备的主题映射
private static readonly TileMapping[] equipThemes = {
// 一台笔记本电脑
new(new Vector2I(13, 26), equipRect),
// 一台笔记本电脑加一台显示器
new(new Vector2I(7, 26), equipRect),
// 一台台式机
new(new Dictionary() {
[new Vector2I(0, 0)] = new Vector2I(11, 17),
[new Vector2I(1, 0)] = new Vector2I(8, 32),
[new Vector2I(2, 0)] = new Vector2I(9, 32),
[new Vector2I(0, 1)] = new Vector2I(11, 18),
[new Vector2I(1, 1)] = new Vector2I(8, 33),
[new Vector2I(2, 1)] = new Vector2I(9, 33),
}),
// 一台台式机加一台显示器
new(new Vector2I(7, 32), equipRect),
};
// 定义第二种设备的主题映射
private static readonly TileMapping[] equip2Themes = {
// 一台笔记本电脑
new(new Vector2I(13, 31), equip2Rect),
// 一台笔记本电脑加一台显示器
new(new Dictionary() {
[new Vector2I(0, -1)] = new Vector2I(13, 32),
[new Vector2I(1, -1)] = new Vector2I(10, 7),
[new Vector2I(2, -1)] = new Vector2I(15, 32),
}),
// 一台台式机
new(new Dictionary() {
[new Vector2I(0, -1)] = new Vector2I(13, 32),
[new Vector2I(1, -1)] = new Vector2I(14, 32),
[new Vector2I(2, -1)] = new Vector2I(15, 30),
}),
// 一台台式机加一台显示器
new(new Vector2I(13, 33), equip2Rect),
};
private bool _draggable;
///
/// 是否可拖拽
///
public bool Draggable {
get => _draggable;
set {
if (value == _draggable) return;
_draggable = value;
}
}
private readonly Guid _id = Guid.NewGuid();
///
/// 唯一标识符
///
public Guid Id => _id;
///
/// 在网格中的位置
///
public Vector2I TilePosition { get; set; } = new Vector2I(5,5);
private bool _isCollided = true;
///
/// 是否处于碰撞状态(显示红色背景)
///
public bool IsCollided {
get => _isCollided;
set {
if (_isCollided == value) return;
_isCollided = value;
if (value) {
GetNode("RedBG").Show();
} else {
GetNode("RedBG").Hide();
}
}
}
private static readonly Rect2I tileRect = new(-1, -2, 4, 5);
///
/// 占用矩形区域
///
public Rect2I TileRect => tileRect;
private Vector2I _mouseOffset;
///
/// 鼠标拖拽偏移
///
public Vector2I MouseOffset => _mouseOffset;
private static readonly ITileDraggable.SpecialTile[] specialTiles = {
new(new Vector2I(1,-1), Lab.MapNodeType.SeatDown | Lab.MapNodeType.Walkable),
new(new Vector2I(1,2), Lab.MapNodeType.SeatUp | Lab.MapNodeType.Walkable),
};
///
/// 特殊图块(如座位)
///
public ITileDraggable.SpecialTile[] SpecialTiles => specialTiles;
// Called when the node enters the scene tree for the first time.
///
/// 节点进入场景树时调用
///
public override void _Ready()
{
RandomChangeTheme();
IsCollided = false;
}
///
/// 处理输入事件
///
/// 视口
/// 输入事件
/// 形状索引
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx)
{
if (@event.IsActionPressed("mouse_left_press")) {
if (Draggable) {
var parent = GetParent();
parent.Pickup(this);
var desk = GetNode("Desk");
_mouseOffset = desk.LocalToMap(GetLocalMousePosition());
GD.Print($"_mouseOffset = {_mouseOffset}");
}
} else if (@event.IsActionReleased("mouse_left_press")) {
if (_isCollided) return;
var parent = GetParent();
parent.PutDown(this);
}
base._InputEvent(viewport, @event, shapeIdx);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
///
/// 每帧处理
///
/// 时间间隔
public override void _Process(double delta)
{
GlobalPosition = TilePosition * 48;
}
private int _tableThemeIdx;
private int _table2ThemeIdx;
private int _chairThemeIdx;
private int _chair2ThemeIdx;
private int _equipThemeIdx;
private int _equip2ThemeIdx;
///
/// 随机更换主题样式
///
public void RandomChangeTheme() {
_tableThemeIdx = GD.RandRange(0, tableThemes.Length-1);
_chairThemeIdx = GD.RandRange(0, chairThemes.Length-1);
_equipThemeIdx = GD.RandRange(0, equipThemes.Length-1);
_table2ThemeIdx = GD.RandRange(0, table2Themes.Length-1);
_chair2ThemeIdx = GD.RandRange(0, chair2Themes.Length-1);
_equip2ThemeIdx = GD.RandRange(0, equip2Themes.Length-1);
tableThemes[_tableThemeIdx].Apply(GetNode("Desk"));
chairThemes[_chairThemeIdx].Apply(GetNode("Chair"));
equipThemes[_equipThemeIdx].Apply(GetNode("Equip"));
table2Themes[_table2ThemeIdx].Apply(GetNode("Desk2"));
chair2Themes[_chair2ThemeIdx].Apply(GetNode("Chair2"));
equip2Themes[_equip2ThemeIdx].Apply(GetNode("Equip2"));
}
private static readonly HashSet blockerTiles = new(new Vector2I[]{
new(0,0),
new(1,0),
new(2,0),
new(0,1),
new(1,1),
new(2,1),
});
///
/// 获取指定位置的图块类型
///
/// 相对位置
/// 图块类型
public Lab.MapNodeType GetTileType(Vector2I pos)
{
GD.Print($"query position of {pos}");
if (blockerTiles.Contains(pos)) {
return Lab.MapNodeType.Blocker;
}
if (specialTiles.Any(t => t.Position == pos)) {
return specialTiles.First(t => t.Position == pos).NodeType;
}
return Lab.MapNodeType.Walkable;
}
///
/// 设置椅子朝向(待实现)
///
/// 目标位置
/// 索引
public void ChairFaceTo(Vector2I target, int idx) {
if (idx == 0) {
var theme = chairThemes[_chairThemeIdx];
}
}
}