Browse Source

flank flip; move only to first fields

master
laurids 5 months ago
parent
commit
a71b7b40c7
7 changed files with 208 additions and 75 deletions
  1. +16
    -16
      Assets/GWConquest/Scenes/GalaxyMap.unity
  2. +21
    -5
      Assets/GWConquest/Scripts/Battle.cs
  3. +116
    -31
      Assets/GWConquest/Scripts/BattleFlank.cs
  4. +10
    -6
      Assets/GWConquest/Scripts/GWNetworkManager.cs
  5. +10
    -6
      Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs
  6. +16
    -2
      Assets/GWConquest/Scripts/UI/BattleFlankUI.cs
  7. +19
    -9
      Assets/GWConquest/Scripts/Zone.cs

+ 16
- 16
Assets/GWConquest/Scenes/GalaxyMap.unity View File

@ -28409,7 +28409,7 @@ MonoBehaviour:
BetweenTransitionLengthFactor: 60
battleTurnLength: 30
battleTurnDeviation: 10
battleBeginPhaseLength: 0
battleBeginPhaseLength: 30
battleCommandPhaseLength: 20
battleCombatPhaseLength: 20
moveToFlankCooldown: 15
@ -33393,7 +33393,7 @@ PrefabInstance:
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_SizeDelta.x
value: 13
value: 12.88861
objectReference: {fileID: 0}
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -33514,7 +33514,7 @@ PrefabInstance:
- target: {fileID: 4411086135142167815, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_AnchoredPosition.x
value: -65.8
value: -65.688614
objectReference: {fileID: 0}
- target: {fileID: 5945601791339210574, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -46408,7 +46408,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &765894939
RectTransform:
m_ObjectHideFlags: 0
@ -61805,12 +61805,12 @@ PrefabInstance:
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
propertyPath: m_AnchorMax.x
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
@ -74360,7 +74360,7 @@ PrefabInstance:
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_SizeDelta.x
value: 13
value: 12.88861
objectReference: {fileID: 0}
- target: {fileID: 4096209424460686483, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -74411,7 +74411,7 @@ PrefabInstance:
- target: {fileID: 4411086135142167815, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_AnchoredPosition.x
value: 65.87012
value: 65.75873
objectReference: {fileID: 0}
- target: {fileID: 5945601791339210574, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -119791,7 +119791,7 @@ PrefabInstance:
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_SizeDelta.x
value: 13
value: 12.88861
objectReference: {fileID: 0}
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -119917,7 +119917,7 @@ PrefabInstance:
- target: {fileID: 4411086135142167815, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_AnchoredPosition.x
value: -65.8
value: -65.688614
objectReference: {fileID: 0}
- target: {fileID: 5945601791339210574, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -124486,7 +124486,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -107.51172}
m_SizeDelta: {x: 0, y: 40.225113}
m_SizeDelta: {x: 112.77534, y: 40.225113}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1981011823
MonoBehaviour:
@ -125588,7 +125588,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &1996625630
RectTransform:
m_ObjectHideFlags: 0
@ -133026,12 +133026,12 @@ PrefabInstance:
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
propertyPath: m_AnchorMax.x
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
propertyPath: m_AnchorMax.y
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 77748483005084366, guid: f69b4b94559d7a14d99e0d870647c1f9,
type: 3}
@ -134072,7 +134072,7 @@ PrefabInstance:
- target: {fileID: 4096209424460686482, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_SizeDelta.x
value: 13
value: 12.88861
objectReference: {fileID: 0}
- target: {fileID: 4096209424460686483, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
@ -134097,7 +134097,7 @@ PrefabInstance:
- target: {fileID: 4411086135142167815, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}
propertyPath: m_AnchoredPosition.x
value: 65.87012
value: 65.75873
objectReference: {fileID: 0}
- target: {fileID: 5945601791339210574, guid: ada9ee8cb263a4e4ba2f5874cfe9098d,
type: 3}


+ 21
- 5
Assets/GWConquest/Scripts/Battle.cs View File

@ -16,6 +16,7 @@ namespace GWConquest
private NetworkVariable<int> victorID = new NetworkVariable<int>();
private NetworkVariable<float> phaseCooldown = new NetworkVariable<float>();
private NetworkVariable<BattlePhase> battlePhase = new NetworkVariable<BattlePhase>();
private NetworkVariable<int> defenderPlayerID = new();
public GameObject BattleFlankPrefab;
@ -111,7 +112,7 @@ namespace GWConquest
public Zone Zone
{
get => Zone.GetFromId(zoneID.Value);
set
private set
{
zoneID.Value = Zone.GetZoneId(value);
transform.position = value.transform.position;
@ -150,6 +151,11 @@ namespace GWConquest
get => Player.GetPlayerById(victorID.Value);
}
public Player Defender
{
get => Player.GetPlayerById(defenderPlayerID.Value);
}
private void OnZoneChanged(int oldID, int newID)
{
if (newID != -1)
@ -171,14 +177,20 @@ namespace GWConquest
go.GetComponent<NetworkObject>().Spawn();
var flank = go.GetComponent<BattleFlank>();
flank.Battle = this;
flank.MaxUnitCount = maxUnitCount;
flank.RowCount = rowCount;
flank.Init(this, maxUnitCount, rowCount, 2.5f, 2.5f);
return flank;
}
public void Init()
public void Init(Zone zone, Player defenderPlayer)
{
Zone = zone;
foreach(Formation f in zone.Formations)
{
AddFormation(f);
}
defenderPlayerID.Value = defenderPlayer.PlayerId;
Phase = BattlePhase.Begin;
PhaseCooldown = GameManager.Instance.GetBattlePhaseLength(BattlePhase.Begin);
@ -691,6 +703,10 @@ namespace GWConquest
{
Debug.LogErrorFormat("Tried to move unit {0} to flank index {1} on flank {2}, but it was already occupied by {3}", unit, flankIndex, flank, flank.GetUnit(flankIndex));
}
else if (!flank.CanPlayerMoveToField(flankIndex, unit.Player, Phase))
{
Debug.LogErrorFormat("Tried to move unit {0} to flank index {1} on flank {2}, but it is out of movement range", unit, flankIndex, flank);
}
else
{
Debug.LogFormat("Moving unit {0} to flank index {1} on flank {2}", unit, flankIndex, flank);


+ 116
- 31
Assets/GWConquest/Scripts/BattleFlank.cs View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.Netcode;
@ -14,7 +15,8 @@ namespace GWConquest
private NetworkVariable<int> rowCount = new NetworkVariable<int>();
private GWNetworkList<NullableNetworkBehaviourReference> units = new GWNetworkList<NullableNetworkBehaviourReference>();
private GWNetworkList<float> deathCooldowns = new GWNetworkList<float>();
private NetworkVariable<float> defenderStartingCols = new();
private NetworkVariable<float> attackerStartingCols = new();
public HexGrid hexGrid;
@ -27,7 +29,6 @@ namespace GWConquest
public Battle Battle
{
get => battle.Value.GetBehaviour<Battle>();
set => battle.Value = value;
}
public ushort FlankId
@ -41,13 +42,30 @@ namespace GWConquest
public int MaxUnitCount
{
get => maxUnitCount.Value;
set => maxUnitCount.Value = value;
}
public int RowCount
{
get => rowCount.Value;
set => rowCount.Value = value;
}
public float AttackerStartingCols
{
get => attackerStartingCols.Value;
}
public float DefenderStartingCols
{
get => defenderStartingCols.Value;
}
public void Init(Battle _battle, int _maxUnitCount, int _rowCount, float _attackerStartingCols, float _defenderStartingCols)
{
battle.Value = _battle;
maxUnitCount.Value = _maxUnitCount;
rowCount.Value = _rowCount;
attackerStartingCols.Value = _attackerStartingCols;
defenderStartingCols.Value = _defenderStartingCols;
}
public Unit GetUnit(int index)
@ -159,6 +177,8 @@ namespace GWConquest
private void ResetGrid(int _maxUnitCount, int _rowCount)
{
if(_maxUnitCount == 0 || _rowCount == 0) return;
units.Clear();
deathCooldowns.Clear();
@ -170,59 +190,124 @@ namespace GWConquest
deathCooldowns.Add(0f);
}
}
public bool CanPlayerMoveToField(int index, Player player, BattlePhase phase)
{
float x = hexGrid.GetPosition(index).x;
float difference;
float allowed;
if(player == Battle.Defender)
{
difference = x + 1f;
allowed = phase == BattlePhase.Begin ? AttackerStartingCols : 1.5f;
}
else {
difference = hexGrid.ColumnCount - x;
allowed = phase == BattlePhase.Begin ? DefenderStartingCols : 1.5f;
}
return difference <= allowed;
}
}
public enum HexDirection
{
Left, Right, UpLeft, UpRight, DownLeft, DownRight
}
public class HexGrid
{
public static Vector2 uBase { get => Vector2.right; }
private static Vector2 _vBase = new(-0.5f, Mathf.Sqrt(3f) / 2f);
public static Vector2 vBase { get => _vBase; }
public static Vector2Int GetDirectionVector(HexDirection direction)
{
return direction switch
{
HexDirection.Left => new Vector2Int(-1, 0),
HexDirection.Right => new Vector2Int(1, 0),
HexDirection.UpLeft => new Vector2Int(-1, -1),
HexDirection.UpRight => new Vector2Int(0, -1),
HexDirection.DownLeft => new Vector2Int(0, 1),
HexDirection.DownRight => new Vector2Int(1, 1),
_ => new Vector2Int(0, 0),
};
}
private int fieldCount;
private int rowCount;
private float columnCount;
private Vector2[] positions;
private Vector2Int[] coordinates;
private Dictionary<Vector2Int, int> indexMap;
public HexGrid(int _fieldCount, int _rowCount)
{
if(_fieldCount == 0 || _rowCount == 0 || _rowCount > _fieldCount)
{
throw new ArgumentException($"Invalid field / row count: {_fieldCount} / {_rowCount}");
}
fieldCount = _fieldCount;
rowCount = _rowCount;
int currentColumn = 0;
int currentField = 0;
coordinates = new Vector2Int[_fieldCount];
indexMap = new Dictionary<Vector2Int, int>();
float triHeight = Mathf.Sqrt(3f) / 2f;
Vector2Int vec = new(0,0);
int index = 0;
coordinates[index] = vec;
indexMap[vec] = index;
index++;
positions = new Vector2[_fieldCount];
if(_fieldCount != 0 && _rowCount != 0)
int u = 1;
while(index < fieldCount)
{
while(currentField < _fieldCount)
for(int v = rowCount-1; v >= 0; v--)
{
for(int i = 0; i < _rowCount; i++)
{
if(i % 2 == currentColumn % 2)
{
positions[currentField] = new Vector2(currentColumn*0.5f, i*triHeight);
Debug.Log($"Placing field {currentField} at position {positions[currentField]}");
currentField++;
}
if(currentField >= _fieldCount)
{
break;
}
}
if(currentField < _fieldCount)
{
currentColumn++;
}
// endless loop reeeeeeeeeeeeeee
if(index >= fieldCount) break;
vec = new Vector2Int(u,v);
coordinates[index] = vec;
indexMap[vec] = index;
index++;
}
u++;
}
columnCount = currentColumn / 2f + 1f;
columnCount = u-1;
}
public Vector2Int GetCoordinates(int index)
{
return coordinates[index];
}
public int GetIndex(Vector2Int coords)
{
return indexMap[coords];
}
public Vector2 GetPosition(int index)
{
return positions[index];
Vector2Int coords = GetCoordinates(index);
return uBase * coords.x + vBase * coords.y;
}
public bool HasCoordinates(Vector2Int coords)
{
return indexMap.ContainsKey(coords);
}
public int GetIndexInDirection(int index, HexDirection direction)
{
Vector2Int vec = GetCoordinates(index) + GetDirectionVector(direction);
return HasCoordinates(vec) ? GetIndex(vec) : -1;
}
public int RowCount => rowCount;


+ 10
- 6
Assets/GWConquest/Scripts/GWNetworkManager.cs View File

@ -94,7 +94,10 @@ namespace GWConquest
foreach (Zone z in Zone.AllZones)
{
z.CheckBattleStart();
if(z.ShouldStartBattle())
{
SpawnBattle(z);
}
}
Planet.SetupPlanetPathfinding();
@ -175,18 +178,19 @@ namespace GWConquest
return playerFormation;
}
public Battle SpawnBattle(Zone zone)
public Battle SpawnBattle(Zone zone, Player defender = null)
{
var go = Instantiate(BattlePrefab);
go.GetComponent<NetworkObject>().Spawn();
Battle battle = go.GetComponent<Battle>();
battle.Zone = zone;
foreach (Formation f in zone.Formations)
if(defender == null)
{
battle.AddFormation(f);
defender = zone.Formations.FirstOrDefault().Player;
}
battle.Init();
battle.Init(zone, defender);
Debug.LogFormat("Starting battle at zone {0}", this);


+ 10
- 6
Assets/GWConquest/Scripts/UI/BattleArmyPanel.cs View File

@ -241,25 +241,29 @@ namespace GWConquest
public void OnIconDragged(BattleUnitIcon icon, BattleUnitIcon target)
{
if (icon.Unit.BattleState == BattleUnitState.InReserve && icon.Unit.Class.IsHero)
var unit = icon.Unit;
if (unit.BattleState == BattleUnitState.InReserve && unit.Class.IsHero)
{
var fui = icon.GetComponentInParent<BattleFormationUI>();
if (fui != null && target == fui.LeaderIcon)
{
icon.Unit.Formation.AssignLeaderServerRpc(icon.Unit);
unit.Formation.AssignLeaderServerRpc(unit);
}
}
else if (icon.Unit.BattleState == BattleUnitState.InReserve && icon.Unit.CanGoToFlank)
else if (unit.BattleState == BattleUnitState.InReserve && unit.CanGoToFlank)
{
var unitTypeFits = Battle.IsSpaceBattle == (icon.Unit.Class.ZoneType == ZoneType.Space);
var unitTypeFits = Battle.IsSpaceBattle == (unit.Class.ZoneType == ZoneType.Space);
var flankUI = target.GetComponentInParent<BattleFlankUI>();
if (flankUI != null && unitTypeFits)
{
var flankIndex = System.Array.IndexOf(flankUI.Icons, target);
var flank = flankUI.BattleFlank;
if (flankUI.BattleFlank.GetUnit(flankIndex) == null)
var canMove = flank.CanPlayerMoveToField(flankIndex, unit.Player, BattleUI.Battle.Phase);
if (canMove && flank.GetUnit(flankIndex) == null)
{
Battle.MoveUnitToFlankServerRpc(icon.Unit, flankUI.BattleFlank, flankIndex);
Battle.MoveUnitToFlankServerRpc(unit, flank, flankIndex);
}


+ 16
- 2
Assets/GWConquest/Scripts/UI/BattleFlankUI.cs View File

@ -24,6 +24,8 @@ namespace GWConquest
private BattleUI battleUI;
private bool isFlipped;
public RectTransform RectTransform
{
get => GetComponent<RectTransform>();
@ -36,6 +38,8 @@ namespace GWConquest
BattleFlank = flank;
flank.CurrentUI = this;
isFlipped = flank.Battle.Defender != Player.CurrentPlayer;
var rt = RectTransform;
Icons = new BattleUnitIcon[flank.MaxUnitCount];
@ -44,11 +48,21 @@ namespace GWConquest
float iconHexSize = IconSize * triHeight;
float xOffset = (IconSize - iconHexSize) / 2f;
float xSize = flank.hexGrid.ColumnCount * iconHexSize;
for (int i = 0; i < flank.MaxUnitCount; i++)
{
Vector2 gridPos = flank.hexGrid.GetPosition(i);
float posx = iconHexSize * gridPos.x - xOffset;
float posx;
if(isFlipped)
{
posx = xSize - iconHexSize * (gridPos.x + 1) - xOffset;
}
else
{
posx = iconHexSize * gridPos.x - xOffset;
}
float posy = iconHexSize * gridPos.y;
var pos = new Vector2(posx, -posy);
@ -72,7 +86,7 @@ namespace GWConquest
Icons[i] = icon;
}
rt.sizeDelta = new Vector2(flank.hexGrid.ColumnCount * iconHexSize, flank.hexGrid.RowCount * IconSize);
rt.sizeDelta = new Vector2(xSize, flank.hexGrid.RowCount * IconSize);
}
public void UpdateIcons()


+ 19
- 9
Assets/GWConquest/Scripts/Zone.cs View File

@ -126,21 +126,31 @@ namespace GWConquest
{
if (GameManager.Instance.IsLoaded)
{
CheckBattleStart();
if (ShouldStartBattle())
{
var defenders = formations.Where(f => f != formation).Select(f => f.Player).Distinct();
var defenderCount = defenders.Count();
if(defenderCount == 0)
{
Debug.LogWarning($"[Battle] No defender found when starting battle");
GWNetworkManager.Instance.SpawnBattle(this);
}
else
{
if(defenderCount > 1)
{
Debug.LogWarning($"[Battle] More than one defender found when starting battle");
}
GWNetworkManager.Instance.SpawnBattle(this, defenders.First());
}
}
}
}
}
}
public void CheckBattleStart()
{
if (ShouldStartBattle())
{
GWNetworkManager.Instance.SpawnBattle(this);
}
}
public bool ShouldStartBattle()
{
return Formations.Select((f, i) => f.Player).Distinct().Count() > 1;


Loading…
Cancel
Save