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.

307 lines
7.5 KiB

using System;
using System.Collections.Generic;
using Photon.Pun;
using UnityEngine;
using UnityEngine.EventSystems;
public class Circuit : MonoBehaviour {
//General information
public int id;
public bool IsMine {
get => actorNumber == PhotonNetwork.LocalPlayer.ActorNumber;
}
private int actorNumber;
public int ActorNumber {
get => actorNumber;
set {
if (value == -1)
actorNumber = 0;
else
actorNumber = value;
UpdatePlayerMaterial();
}
}
public bool IsInSelection;
//Input information
public bool IsMouseOver {
get => isMouseOver;
}
private bool isMouseOver;
public bool IsSelected {
get => isSelected;
set => isSelected = value;
}
private bool isSelected;
//Behaviour information
private bool isOnOtherObject;
public bool IsOnOtherObject {
get => isOnOtherObject;
set {
isOnOtherObject = value;
IsNeedingReplace = isOnOtherObject || isOutOfGamePlane;
}
}
private bool isOutOfGamePlane;
public bool IsOutOfGamePlane {
get => isOutOfGamePlane;
set {
isOutOfGamePlane = value;
IsNeedingReplace = isOnOtherObject || isOutOfGamePlane;
}
}
public bool IsNeedingReplace {
get => isNeedingReplace;
private set {
if (isNeedingReplace != value)
SetShaderDissolved(value);
isNeedingReplace = value;
}
}
private bool isNeedingReplace;
public bool isDragged;
public bool IsFull {
get => Charge == Values.capacity;
}
public bool IsFullWith(List<Charge> charges) {
return Charge + charges.Count >= Values.capacity;
}
public bool CanSend {
get => Charge >= 1;
}
public bool IsAttacked {
get => Attackers.Count > 0;
}
public List<Circuit> Attackers {
get {
List<Circuit> attackers = new List<Circuit>();
foreach (Connection connection in GoingInConnections.FindAll(c => c.ReceiverIsEnemy))
attackers.Add(connection.Sender);
return attackers;
}
}
//Temporary reference to dragged count
public UICircuitCount uICircuitCount;
//Called by Unity
void Start() {
if (IsInSelection)
ActorNumber = PhotonNetwork.LocalPlayer.ActorNumber;
}
void Update() {
if (EventSystem.current) {
if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject()) {
if (IsMouseOver)
OnLeftPressed();
else if (isSelected)
Deselect();
}
}
if (Input.GetMouseButton(0)) {
if (IsMouseOver)
OnLeftHold();
}
if (Input.GetMouseButtonUp(0)) {
OnLeftReleased();
}
}
//Gameplay
public CircuitType type;
public int level;
public CircuitValues Values {
get => ValuesByLevel(level);
}
public CircuitValues ValuesByLevel(int level) {
return CircuitManager.Instance.GetLevelsByType(type).GetValuesByLevel(level);
}
public List<Connection> GoingOutConnections {
get {
return Game.Instance.Connections.FindAll(c => c.Sender.id == id);
}
}
public List<Connection> GoingInConnections {
get {
return Game.Instance.Connections.FindAll(c => c.Receiver.id == id);
}
}
public float holdTimeForCharging;
private float currentHoldTimeForCharging;
private float upgradeCharge;
private bool upgradeChargeAllowed;
public float UpgradeCharge {
get => upgradeCharge;
set {
upgradeCharge = value;
if (upgradeCharge >= Values.upgradeCost) {
upgradeCharge = Values.upgradeCost;
Game.Instance.UpgradeCircuit(this);
}
GameGUI.Instance.UpdateMenuStats();
}
}
public float Charge {
get => charge;
set {
charge = value;
if (charge > Values.capacity)
charge = Values.capacity;
if (charge < 0) {
Debug.LogWarningFormat("Circuit {0} Charge was negative ({1})", id, charge.ToString("0.00"));
charge = 0;
}
SetDisplayNumber((int)Math.Round(charge));
}
}
private float charge;
private void GrowCharge() {
Charge += Values.chargeRate;
Game.Instance.SendCircuitCharge(id, Charge);
}
private float chargeTime;
public void UpdateCircuit(float tickRate) {
//Grow Charge per tick
chargeTime += Time.deltaTime;
if (chargeTime >= 1 / tickRate) {
GrowCharge();
chargeTime = 0;
}
}
//Events
public void OnBeingAttacked() {
}
public void OnCollisionEnter() {
IsOnOtherObject = true;
}
public void OnCollisionExit() {
IsOnOtherObject = false;
}
public void OnMouseEnter() {
isMouseOver = true;
SetShaderOutlined(true);
}
public void OnMouseExit() {
isMouseOver = false;
SetShaderOutlined(false || IsSelected);
upgradeChargeAllowed = false;
}
private void OnLeftPressed() {
Select();
if (IsMine && Game.Instance.IsPlaying) {
currentHoldTimeForCharging = 0;
upgradeChargeAllowed = true;
if (GoingOutConnections.Count < Values.connections)
Game.Instance.SpawnDraggableConnection(transform.position, this);
}
}
private readonly int framesPerSend = 10;
private float currentFrameCount;
private void OnLeftHold() {
if (upgradeChargeAllowed && Game.Instance.IsPlaying) {
currentFrameCount++;
currentHoldTimeForCharging += Time.deltaTime;
if (currentHoldTimeForCharging >= holdTimeForCharging && level != 3 && currentFrameCount >= framesPerSend) {
currentFrameCount = 0;
Game.Instance.OnDragStopped();
float amount = 2;
if (Charge > amount && UpgradeCharge < Values.upgradeCost) {
Charge -= amount;
UpgradeCharge += amount;
Game.Instance.SendUpgradeCharge(this);
}
}
}
}
private void OnLeftReleased() {
upgradeChargeAllowed = false;
}
public void Select() {
isSelected = true;
SetShaderOutlined(true);
GameGUI.Instance.OpenCircuitMenu(this);
}
public void Deselect() {
isSelected = false;
SetShaderOutlined(false);
GameGUI.Instance.CloseCircuitMenu(this);
}
//Everything Visual
private void SetShaderOutlined(bool outlined) {
int value = 0;
if (outlined) {
if (IsSelected)
value = 2;
else
value = 1;
}
baseRenderer.material.SetInt("_Outlined", value);
decoRenderer.material.SetInt("_Outlined", value);
borderRenderer.material.SetInt("_Outlined", value);
}
private void SetShaderDissolved(bool dissolved) {
float value = dissolved ? 1 : 0;
baseRenderer.material.SetFloat("_Dissolved", value);
}
private void UpdatePlayerMaterial() {
baseRenderer.material = ColorManager.GetBaseBy(ActorNumber);
decoRenderer.material = ColorManager.GetDecoBy(ActorNumber);
borderRenderer.material = ColorManager.GetDecoBy(ActorNumber);
displayRenderer.material = ColorManager.GetDisplayBy(ActorNumber);
}
public void SetDisplayNumber(int value) {
int hundred = (value % 1000) / 100;
int ten = (value % 100) / 10;
int one = value % 10;
displayRenderer.material.SetTexture("_Texture_100", numberTextures[hundred]);
displayRenderer.material.SetTexture("_Texture_10", numberTextures[ten]);
displayRenderer.material.SetTexture("_Texture_1", numberTextures[one]);
}
public Bounds GetBaseBounds() {
return transform.Find("base").GetComponent<Renderer>().bounds;
}
private Renderer baseRenderer;
private Renderer decoRenderer;
private Renderer borderRenderer;
private Renderer displayRenderer;
private readonly List<Texture2D> numberTextures = new List<Texture2D>();
void Awake() {
GameObject baseObj = transform.Find("base").gameObject;
GameObject decoObj = transform.Find("deco").gameObject;
GameObject borderObj = transform.Find("chargebar/border").gameObject;
GameObject displayObj = transform.Find("chargebar/display").gameObject;
baseRenderer = baseObj.GetComponent<Renderer>();
decoRenderer = decoObj.GetComponent<Renderer>();
borderRenderer = borderObj.GetComponent<Renderer>();
displayRenderer = displayObj.GetComponent<Renderer>();
for (int i = 0; i < 10; i++) {
numberTextures.Add(Resources.Load<Texture2D>("Textures/Circuit Digits/" + i));
}
}
}