You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

135 lines
3.7 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements;
namespace Game {
public enum Side { Top, Bottom }
public class Player : NetworkBehaviour {
private const float BaseSpeed = 15;
private const float SpeedMultiplier = 1.5f;
// Unit distance from zero
private readonly float baseBorder = Dimensions.Singleton.PlaySize.x / 2 * 0.85f;
private readonly float borderSummand = Dimensions.Singleton.PlaySize.x / 2 * 0.15f;
private const float BaseWidth = 6;
private const float WidthMultiplier = 1.5f;
protected bool goingLeft, goingRight;
public Side Side { get; set; }
private VisualElement Panel { get; set; }
private List<ModificationProperties> Modifications { get; } = new();
private int Score { get; set; }
private float GetModified(ModEffect effect, float baseValue, float modValue, Func<float, float, float> combineFunc, Func<float, float> invertFunc) {
return Modifications.Where(m => m.effect == effect)
.Aggregate(baseValue,
(current, mod) => combineFunc(current, mod.type switch {
ModType.Buff => modValue,
ModType.Nerf => invertFunc(modValue),
_ => throw new ArgumentOutOfRangeException()
})
);
}
protected float Speed {
get {
float value = GetModified(ModEffect.Speed, BaseSpeed, SpeedMultiplier, (f, f1) => f * f1, f => 1 / f);
return value;
}
}
protected float Border {
get {
float value = GetModified(ModEffect.Border, baseBorder, borderSummand, (f, f1) => f + f1, f => -f);
return Mathf.Clamp(value, Width / 2, Dimensions.Singleton.PlaySize.x / 2);
}
}
protected float Width {
get {
float value = GetModified(ModEffect.Width, BaseWidth, WidthMultiplier, (f, f1) => f * f1, f => 1 / f);
return Mathf.Clamp(value, 0.1f, Dimensions.Singleton.PlaySize.x);
}
}
private float LeftEdge => X - Width / 2;
private float RightEdge => X + Width / 2;
protected float X => transform.position.x;
protected float Y => transform.position.y;
private void Update() {
transform.localScale = new Vector3(Width, 1, 1);
}
protected void Start() {
var y = Side switch {
Side.Bottom => -Dimensions.Singleton.PlaySizeBoards.y / 2,
Side.Top => Dimensions.Singleton.PlaySizeBoards.y / 2,
_ => throw new ArgumentOutOfRangeException()
};
transform.position = new Vector2(0, y);
if (Side == Side.Top)
transform.Rotate(transform.forward, 180);
Panel = GameUI.Singleton.PlayerPanel(Side);
UpdatePanel();
}
public void GainScore() {
Score++;
UpdatePanel();
}
private void UpdatePanel() {
Panel.Q<TextElement>("score").text = Score.ToString();
}
public IEnumerator ProcessModification(ModificationProperties properties) {
Modifications.Add(properties);
var element = GameUI.AddModification(Panel, properties);
var doNothingTime = properties.activeDuration * 0.7f;
var animateTime = properties.activeDuration * 0.3f;
yield return new WaitForSeconds(doNothingTime);
float current = 0;
while (current < animateTime) {
current += Time.deltaTime;
element.style.opacity = new StyleFloat(1 - current / animateTime);
yield return null;
}
element.RemoveFromHierarchy();
Modifications.Remove(properties);
}
protected void ClampInsideBorders() {
if (LeftEdge < -Border)
transform.Translate(Vector2.right * (-Border - LeftEdge), Space.World);
if (RightEdge > Border)
transform.Translate(Vector2.left * (RightEdge - Border), Space.World);
}
protected void TryLinearMove(float h) {
var trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0);
trans *= Speed * h;
transform.Translate(trans, Space.World);
ClampInsideBorders();
}
}
}