Skip to content

Commit 4cb6aab

Browse files
committed
Implemented Attack Move by modifying Fog of War calculation.
The Fog of War now always checks all combinations of agents, not just those with changed states. Extracted some common Action functions. Fixed Building construction via GUI, it's now added to Player's model. Fixed Unit Production API check of availability within a Building. Fixed Ranged Unit attacking Buildings to not go melee attack. Fog LocationsSeenTemporary cycle changed to use current length. Default GatherResource constructor will not throw exceptions. Initialized default Unit unstuck position so it won't go to map corner. Reduced the sizes of Textures.
1 parent c0badc5 commit 4cb6aab

File tree

16 files changed

+223
-98
lines changed

16 files changed

+223
-98
lines changed

Assets/Game/Scripts/Core/Faction/Buildings/BuildingPlacement.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using XposeCraft.Core.Required;
77
using XposeCraft.Core.Resources;
88
using XposeCraft.Game;
9+
using XposeCraft.Game.Actors;
910
using XposeCraft.GameInternal;
1011
using XposeCraft.GameInternal.Helpers;
1112

@@ -156,13 +157,16 @@ public void TryPlaceBuild()
156157
}
157158
try
158159
{
159-
PlaceProgressBuilding(
160-
build,
161-
unitSelect.curSelectedS,
162-
factionIndex,
163-
new Position(loc),
164-
obj.transform.rotation,
165-
ResourceManagerPlayerOnly);
160+
Actor.Create<Game.Actors.Buildings.Building>(
161+
BuildingHelper.DetermineBuildingType(BuildingHelper.PrefabToType(build.obj)),
162+
PlaceProgressBuilding(
163+
build,
164+
unitSelect.curSelectedS,
165+
factionIndex,
166+
new Position(loc),
167+
obj.transform.rotation,
168+
ResourceManagerPlayerOnly),
169+
GameManager.Instance.GuiPlayer);
166170
}
167171
catch (InvalidOperationException)
168172
{

Assets/Game/Scripts/Core/Faction/Units/UnitController.cs

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using XposeCraft.Core.Required;
66
using XposeCraft.Core.Resources;
77
using XposeCraft.Game;
8+
using XposeCraft.Game.Actors;
89
using XposeCraft.Game.Control;
910
using XposeCraft.Game.Enums;
1011
using XposeCraft.GameInternal;
@@ -47,6 +48,8 @@ public class UnitController : MonoBehaviour
4748
public Vector3 targetPoint;
4849
public int size = 1;
4950
Health healthObj;
51+
public bool IsAttackMove { get; set; }
52+
public Actor AttackMoveTarget { get; set; }
5053
internal UnitActionQueue.ActionDequeue _actionDequeue { get; set; }
5154

5255
protected Faction Faction
@@ -268,31 +271,31 @@ void FixedUpdate()
268271
{
269272
movement.pathComplete = true;
270273
}
274+
if (tState == TargetState.Undecided)
275+
{
276+
BuildingController targetController = target.GetComponent<BuildingController>();
277+
switch (Faction.Relations[targetController.FactionIndex].state)
278+
{
279+
case 0:
280+
tState = TargetState.Ally;
281+
break;
282+
case 1:
283+
tState = TargetState.Neutral;
284+
break;
285+
case 2:
286+
tState = TargetState.Enemy;
287+
break;
288+
case 3:
289+
tState = TargetState.Self;
290+
break;
291+
}
292+
}
271293
if (movement.pathComplete)
272294
{
273295
transform.LookAt(new Vector3(
274296
target.transform.position.x,
275297
transform.position.y,
276298
target.transform.position.z));
277-
if (tState == TargetState.Undecided)
278-
{
279-
BuildingController targetController = target.GetComponent<BuildingController>();
280-
switch (Faction.Relations[targetController.FactionIndex].state)
281-
{
282-
case 0:
283-
tState = TargetState.Ally;
284-
break;
285-
case 1:
286-
tState = TargetState.Neutral;
287-
break;
288-
case 2:
289-
tState = TargetState.Enemy;
290-
break;
291-
case 3:
292-
tState = TargetState.Self;
293-
break;
294-
}
295-
}
296299
switch (tState)
297300
{
298301
case TargetState.Self:
@@ -329,6 +332,15 @@ void FixedUpdate()
329332
anim.state = "Move";
330333
anim.Animate();
331334
}
335+
if (tState == TargetState.Enemy
336+
&& weapon.fighterUnit
337+
&& weapon.InRange(target.transform.position, transform.position)
338+
|| (transform.position - target.transform.position).magnitude < 2)
339+
{
340+
movement.pathComplete = true;
341+
anim.state = "Idle";
342+
anim.Animate();
343+
}
332344
break;
333345
case Target.DropOff:
334346
if ((transform.position - target.transform.position).sqrMagnitude < build.buildDist)

Assets/Game/Scripts/Core/Faction/Units/UnitMovement.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using UnityEngine;
22
using XposeCraft.Core.Grids;
33
using XposeCraft.Core.Required;
4+
using XposeCraft.GameInternal;
45

56
namespace XposeCraft.Core.Faction.Units
67
{
@@ -30,6 +31,12 @@ private void Awake()
3031
myTransform = GetComponent<Transform>();
3132
}
3233

34+
private void Start()
35+
{
36+
// Default starting position to prevent glitch about running over the entire map to position zero
37+
lastValidLocation = GameManager.Instance.UGrid.DetermineLocation(transform.position);
38+
}
39+
3340
void FixedUpdate()
3441
{
3542
if (pathComplete || myPath == null || myPath.list.Length <= 0)

Assets/Game/Scripts/Core/Fog Of War/Fog.cs

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -118,37 +118,45 @@ public void DisplayAll()
118118
}
119119
}
120120

121+
/// <summary>
122+
/// Updates the hidden renderers based on their respective hideNextSetting.
123+
/// This triggers the visibility change events for signal agents.
124+
/// </summary>
125+
/// <param name="renderOnScreen"></param>
126+
/// <param name="fog"></param>
127+
/// <param name="signalAgents">Their LocationsSeenTemporary array will be used to check and trigger the
128+
/// visibility change event of the actor represented by the specific SignalAgent. This event will
129+
/// inform him of renderers that he sees. For the Attack Move purpose, this will be checked always.</param>
121130
public void SetRenderers(bool renderOnScreen, Fog fog, SignalAgents signalAgents)
122131
{
123132
for (int x = 0; x < hideAmount; x++)
124133
{
125134
var previousState = (VisionReceiver.VisionState) hideCurrentSetting[x];
126135
var newState = (VisionReceiver.VisionState) hideNextSetting[x];
127-
if (previousState == newState)
128-
{
129-
continue;
130-
}
131-
if (renderOnScreen)
136+
if (previousState != newState)
132137
{
133-
hiddenRend[x].SetRenderer(newState);
138+
if (renderOnScreen)
139+
{
140+
hiddenRend[x].SetRenderer(newState);
141+
}
142+
hideCurrentSetting[x] = hideNextSetting[x];
134143
}
135-
hideCurrentSetting[x] = hideNextSetting[x];
136-
// Find all agents that saw the change in state
137-
var agentIndexesSawChange = new List<int>();
144+
// Find all agents that saw the hidden agent or his change in state
145+
var signalIndexesSawHidden = new List<int>();
138146
var location = fog.DetermineLocInteger(hiddenAgentT[x].position);
139147
if (signalAgents.LocationsSeenTemporary == null)
140148
{
141149
Log.w("Fog hidden agent cannot find locations of nearby signal agents");
142150
return;
143151
}
144-
for (var agentIndex = 0; agentIndex < signalAgents.LocationsSeenTemporary.Length; agentIndex++)
152+
for (var signalIndex = 0; signalIndex < signalAgents.LocationsSeenTemporary.Length; signalIndex++)
145153
{
146154
try
147155
{
148-
var agentSeenPositions = signalAgents.LocationsSeenTemporary[agentIndex];
156+
var agentSeenPositions = signalAgents.LocationsSeenTemporary[signalIndex];
149157
if (agentSeenPositions != null && agentSeenPositions.Contains(location))
150158
{
151-
agentIndexesSawChange.Add(agentIndex);
159+
signalIndexesSawHidden.Add(signalIndex);
152160
}
153161
}
154162
catch (Exception e)
@@ -157,9 +165,21 @@ public void SetRenderers(bool renderOnScreen, Fog fog, SignalAgents signalAgents
157165
Log.w("LocationsSeenTemporary problem: " + e.Message);
158166
}
159167
}
160-
var agentActorsSawChange = new List<Actor>();
161-
agentIndexesSawChange.ForEach(agentIndex => agentActorsSawChange.Add(
162-
GameManager.Instance.ActorLookup[signalAgents.agents[agentIndex]]));
168+
169+
// Conversion to Lists of GameObjects and Actors
170+
var signalAgentsSawHidden = new List<GameObject>();
171+
signalIndexesSawHidden.ForEach(signalIndex =>
172+
{
173+
// For an unknown reason, sometimes the index would try to get accessed above the agent count
174+
if (signalIndex < signalAgents.agents.Count)
175+
{
176+
signalAgentsSawHidden.Add(signalAgents.agents[signalIndex]);
177+
}
178+
});
179+
var agentActorsSawHidden = new List<Actor>();
180+
signalAgentsSawHidden.ForEach(signalAgent => agentActorsSawHidden.Add(
181+
GameManager.Instance.ActorLookup[signalAgent]));
182+
163183
// Notifies Players about the change
164184
if (!GameManager.Instance.ActorLookup.ContainsKey(hiddenAgent[x]))
165185
{
@@ -174,7 +194,13 @@ public void SetRenderers(bool renderOnScreen, Fog fog, SignalAgents signalAgents
174194
{
175195
if (player.FactionIndex == enemyFactionIndex)
176196
{
177-
player.EnemyVisibilityChanged(actor, agentActorsSawChange, previousState, newState);
197+
player.EnemyOnSight(
198+
hiddenAgent[x],
199+
actor,
200+
signalAgentsSawHidden,
201+
agentActorsSawHidden,
202+
previousState,
203+
newState);
178204
}
179205
}
180206
}
@@ -464,7 +490,7 @@ private void ModifyFog(object obj)
464490
// NOTE: agentsAmount changes during the iteration!
465491
signalAgents.LocationsSeenTemporary = new List<int>[signalAgents.agentsAmount];
466492
var locationsSeenTemporary = signalAgents.LocationsSeenTemporary;
467-
for (var signalAgentIndex = 0; signalAgentIndex < signalAgents.agentsAmount; signalAgentIndex++)
493+
for (var signalAgentIndex = 0; signalAgentIndex < locationsSeenTemporary.Length; signalAgentIndex++)
468494
{
469495
// For an unknown reason, this didn't work if used just as a for condition
470496
if (signalAgentIndex >= _signalAgentsFactionLocations[factionIndex].Length)
@@ -749,28 +775,9 @@ public void ClosePoints(int range, Vector3 loc3d, int height)
749775

750776
public void AddRenderer(GameObject obj, VisionReceiver receiver)
751777
{
752-
int ownerFaction;
753-
var unit = obj.GetComponent<UnitController>();
754-
if (unit != null)
755-
{
756-
ownerFaction = unit.FactionIndex;
757-
}
758-
else
759-
{
760-
var building = obj.GetComponent<BuildingController>();
761-
if (building != null)
762-
{
763-
ownerFaction = building.FactionIndex;
764-
}
765-
else
766-
{
767-
throw new Exception(
768-
"Actor cannot determine its faction index for visibility exception purposes");
769-
}
770-
}
771778
for (var factionIndex = 0; factionIndex < GameManager.Instance.Factions.Length; factionIndex++)
772779
{
773-
if (factionIndex == ownerFaction)
780+
if (factionIndex == FindFactionIndex(obj))
774781
{
775782
// Player that owns the unit will not be included in its hiding
776783
continue;
@@ -823,7 +830,7 @@ private static int FindFactionIndex(GameObject obj)
823830
{
824831
return buildingController.FactionIndex;
825832
}
826-
throw new Exception("Cannot find Controller containing faction index needed for signal agent");
833+
throw new Exception("Cannot find Controller containing faction index needed for signal agent or renderer");
827834
}
828835
}
829836
}

Assets/Game/Scripts/Core/Required/ClassList.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,14 +1452,10 @@ public class SUnitBuilding
14521452

14531453
public bool StartProduction(int x, ResourceManager resourceManager, Player player)
14541454
{
1455-
var job = new ProduceUnit(units[x], player);
1456-
// If there are available resources, uses them before starting the production, otherwise returns
1457-
for (var index = 0; index < resourceManager.resourceTypes.Length; index++)
1455+
var job = TryConstructProduction(x, resourceManager, player);
1456+
if (job == null)
14581457
{
1459-
if (resourceManager.resourceTypes[index].amount < job.cost[index])
1460-
{
1461-
return false;
1462-
}
1458+
return false;
14631459
}
14641460
for (var index = 0; index < resourceManager.resourceTypes.Length; index++)
14651461
{
@@ -1473,6 +1469,20 @@ public bool StartProduction(int x, ResourceManager resourceManager, Player playe
14731469
return true;
14741470
}
14751471

1472+
public ProduceUnit TryConstructProduction(int x, ResourceManager resourceManager, Player player)
1473+
{
1474+
var job = new ProduceUnit(units[x], player);
1475+
// If there are available resources, uses them before starting the production, otherwise returns null
1476+
for (var index = 0; index < resourceManager.resourceTypes.Length; index++)
1477+
{
1478+
if (resourceManager.resourceTypes[index].amount < job.cost[index])
1479+
{
1480+
return null;
1481+
}
1482+
}
1483+
return job;
1484+
}
1485+
14761486
public void CancelProduction(int x, ResourceManager resourceManager)
14771487
{
14781488
var job = jobs[x];

Assets/Game/Scripts/Game/Actors/Actor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ internal static T Create<T>(Type type, GameObject gameObject, Player playerOwner
6565
var building = instance as Building;
6666
if (building != null)
6767
{
68-
Player.CurrentPlayer.Buildings.Add(building);
68+
playerOwner.Buildings.Add(building);
6969
}
7070
else
7171
{

Assets/Game/Scripts/Game/Actors/Buildings/Building.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ protected List<UnitType> SupportsUnitProduction
7474

7575
protected bool CanNowProduceUnit(UnitType unitType)
7676
{
77-
return SupportsUnitProduction.Contains(unitType);
77+
return SupportsUnitProduction.Contains(unitType)
78+
&& null != BuildingController.unitProduction.TryConstructProduction(
79+
UnitHelper.FindUnitIndexInUnitProduction(unitType, BuildingController.unitProduction),
80+
GameManager.Instance.ResourceManagerFaction[BuildingController.FactionIndex],
81+
BuildingController.PlayerOwner);
7882
}
7983

8084
/// <summary>

Assets/Game/Scripts/Game/Control/GameActions/Attack.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,23 @@ internal override bool Progress(IUnit unit, UnitController unitController)
3939
{
4040
return false;
4141
}
42-
var targetUnit = Target as Unit;
42+
return AttackUnitOrBuilding(Target, unitController);
43+
}
44+
45+
internal static bool AttackUnitOrBuilding(IActor target, UnitController attackerUnitController)
46+
{
47+
var targetUnit = target as Unit;
4348
if (targetUnit != null)
4449
{
45-
return targetUnit.AttackedByUnit(unitController);
50+
return targetUnit.AttackedByUnit(attackerUnitController);
4651
}
47-
var targetBuilding = Target as Building;
52+
var targetBuilding = target as Building;
4853
if (targetBuilding == null)
4954
{
5055
throw new Exception(
5156
"Fatal error, constructor hasn't properly asserted that Target is Unit or Building");
5257
}
53-
return targetBuilding.AttackedByUnit(unitController);
58+
return targetBuilding.AttackedByUnit(attackerUnitController);
5459
}
5560
}
5661
}

0 commit comments

Comments
 (0)