Files
EndlessHostRoles/Modules/TargetArrow.cs
T

150 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace TOHE;
static class TargetArrow
{
class ArrowInfo(byte from, byte to)
{
public byte From = from;
public byte To = to;
public bool Equals(ArrowInfo obj)
{
return From == obj.From && To == obj.To;
}
public override string ToString()
{
return $"(From:{From} To:{To})";
}
}
static readonly Dictionary<ArrowInfo, string> TargetArrows = [];
static readonly string[] Arrows = [
"↑",
"↗",
"→",
"↘",
"↓",
"↙",
"←",
"↖",
"・"
];
public static void Init()
{
TargetArrows.Clear();
}
/// <summary>
/// 新たにターゲット矢印対象を登録
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
/// <param name="coloredArrow"></param>
public static void Add(byte seer, byte target)
{
var arrowInfo = new ArrowInfo(seer, target);
if (!TargetArrows.Any(a => a.Key.Equals(arrowInfo)))
TargetArrows[arrowInfo] = "・";
}
/// <summary>
/// ターゲットの削除
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
public static void Remove(byte seer, byte target)
{
var arrowInfo = new ArrowInfo(seer, target);
var removeList = new List<ArrowInfo>(TargetArrows.Keys.Where(k => k.Equals(arrowInfo)));
foreach (ArrowInfo a in removeList.ToArray())
{
TargetArrows.Remove(a);
}
}
/// <summary>
/// タイプの同じターゲットの全削除
/// </summary>
/// <param name="seer"></param>
public static void RemoveAllTarget(byte seer)
{
var removeList = new List<ArrowInfo>(TargetArrows.Keys.Where(k => k.From == seer));
foreach (ArrowInfo arrowInfo in removeList.ToArray())
{
TargetArrows.Remove(arrowInfo);
}
}
/// <summary>
/// 見ることのできるすべてのターゲット矢印を取得
/// </summary>
/// <param name="seer"></param>
/// <returns></returns>
public static string GetArrows(PlayerControl seer, params byte[] targets)
{
var arrows = string.Empty;
foreach (var arrowInfo in TargetArrows.Keys.Where(ai => ai.From == seer.PlayerId && targets.Contains(ai.To)))
{
arrows += TargetArrows[arrowInfo];
}
return arrows;
}
/// <summary>
/// FixedUpdate毎にターゲット矢印を確認
/// 更新があったらNotifyRolesを発行
/// </summary>
/// <param name="seer"></param>
public static void OnFixedUpdate(PlayerControl seer)
{
if (!GameStates.IsInTask) return;
var seerId = seer.PlayerId;
var seerIsDead = !seer.IsAlive();
var arrowList = new List<ArrowInfo>(TargetArrows.Keys.Where(a => a.From == seer.PlayerId));
if (!arrowList.Any()) return;
var update = false;
foreach (ArrowInfo arrowInfo in arrowList.ToArray())
{
var targetId = arrowInfo.To;
var target = Utils.GetPlayerById(targetId);
if (seerIsDead || !target.IsAlive() && !seer.Is(CustomRoles.Spiritualist))
{
TargetArrows.Remove(arrowInfo);
update = true;
continue;
}
//対象の方角ベクトルを取る
var dir = target.transform.position - seer.transform.position;
int index;
if (dir.magnitude < 2)
{
//近い時はドット表示
index = 8;
}
else
{
//-22.5~22.5度を0とするindexに変換
// 下が0度、左側が+180まで右側が-180まで
// 180度足すことで上が0度の時計回り
// 45度単位のindexにするため45/2を加算
var angle = Vector3.SignedAngle(Vector3.down, dir, Vector3.back) + 180 + 22.5;
index = ((int)(angle / 45)) % 8;
}
var arrow = Arrows[index];
if (TargetArrows[arrowInfo] != arrow)
{
TargetArrows[arrowInfo] = arrow;
update = true;
}
}
if (update)
{
Utils.NotifyRoles(SpecifySeer: seer, ForceLoop: false, SpecifyTarget: seer);
}
}
}