Skip to content

Commit

Permalink
Merge branch 'master' into feature/rally-point-order-generator
Browse files Browse the repository at this point in the history
  • Loading branch information
charliefoxtwo authored Feb 2, 2024
2 parents 77651cb + 9b93648 commit 36c4e84
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 9 deletions.
61 changes: 56 additions & 5 deletions src/OpenSage.Game/Logic/Object/Behaviors/SpawnBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using OpenSage.Content;
using OpenSage.Data.Ini;

Expand All @@ -11,7 +12,8 @@ internal sealed class SpawnBehavior : BehaviorModule

private List<GameObject> _spawnedUnits;
private bool _initial;
private IProductionExit _productionExit;
private IProductionExit? _productionExit;
private OpenContainModule? _openContain;

private bool _unknownBool1;
private string _templateName;
Expand All @@ -33,8 +35,6 @@ internal SpawnBehavior(GameObject gameObject, GameContext context, SpawnBehavior

private void SpawnUnit()
{
_productionExit ??= _gameObject.FindBehavior<IProductionExit>();

var spawnedObject = _gameObject.GameContext.GameLogic.CreateObject(_moduleData.SpawnTemplate.Value, _gameObject.Owner);
_spawnedUnits.Add(spawnedObject);

Expand All @@ -44,9 +44,25 @@ private void SpawnUnit()
slavedUpdate.Master = _gameObject;
}

if (!TryTransformViaProductionExit(spawnedObject) &&
!TryTransformViaOpenContainer(spawnedObject))
{
throw new Exception("Unable to set spawn point for spawned unit");
}
}

private bool TryTransformViaProductionExit(GameObject spawnedObject)
{
_productionExit ??= _gameObject.FindBehavior<IProductionExit>();

if (_productionExit == null)
{
return false;
}

if (_productionExit != null)
{
spawnedObject.SetTranslation(_gameObject.ToWorldspace(_productionExit.GetUnitCreatePoint()));
spawnedObject.SetTranslation(_productionExit.GetUnitCreatePoint());

var rallyPoint = _productionExit.GetNaturalRallyPoint();
if (rallyPoint.HasValue)
Expand All @@ -60,6 +76,41 @@ private void SpawnUnit()
{
ProductionUpdate.HandleHarvesterUnitCreation(_gameObject, spawnedObject);
}

return true;
}

// GLATunnelNetwork has no production exit behavior - it's explicitly commented out, saying "... we don't appear to need it for the spawns because they use OpenContain instead"
private bool TryTransformViaOpenContainer(GameObject spawnedObject)
{
_openContain ??= _gameObject.FindBehavior<OpenContainModule>();

if (_openContain == null)
{
return false;
}

// spawn at container output
var (exitStart, exitEnd) = _openContain.DefaultExitPath;

if (exitStart.HasValue && exitEnd.HasValue)
{
spawnedObject.SetTranslation(_gameObject.ToWorldspace(exitStart.Value));
spawnedObject.AIUpdate.AddTargetPoint(_gameObject.ToWorldspace(exitEnd.Value));
}
else
{
spawnedObject.SetTranslation(_gameObject.Translation);
}

// move to rally point
var rallyPoint = _gameObject.RallyPoint;
if (rallyPoint.HasValue)
{
spawnedObject.AIUpdate?.AddTargetPoint(rallyPoint.Value);
}

return true;
}

public void SpawnInitial()
Expand Down
8 changes: 8 additions & 0 deletions src/OpenSage.Game/Logic/Object/Contain/OpenContain.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using FixedMath.NET;
using ImGuiNET;
using OpenSage.Audio;
Expand Down Expand Up @@ -29,6 +30,9 @@ public abstract class OpenContainModule : UpdateModule
public virtual int TotalSlots => _moduleData.ContainMax;
public int OccupiedSlots => ContainedObjectIds.Sum(id => SlotValueForUnit(GameObjectForId(id)));

protected const string ExitBoneStartName = "ExitStart";
protected const string ExitBoneEndName = "ExitEnd";

protected OpenContainModule(GameObject gameObject, OpenContainModuleData moduleData)
{
_moduleData = moduleData;
Expand Down Expand Up @@ -73,6 +77,10 @@ public void Add(GameObject unit, bool initial = false)
}
}

public (Vector3? Start, Vector3? End) DefaultExitPath => (
GameObject.Drawable.FindBone(ExitBoneStartName).bone?.Transform.Translation,
GameObject.Drawable.FindBone(ExitBoneEndName).bone?.Transform.Translation);

protected virtual BaseAudioEventInfo? GetEnterVoiceLine(UnitSpecificSounds sounds)
{
return sounds.VoiceEnter?.Value;
Expand Down
4 changes: 2 additions & 2 deletions src/OpenSage.Game/Logic/Object/Contain/TransportContain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ protected override bool TryAssignExitPath(GameObject unit)
{
if (_moduleData.NumberOfExitPaths > 0)
{
var startBoneName = "ExitStart";
var endBoneName = "ExitEnd";
var startBoneName = ExitBoneStartName;
var endBoneName = ExitBoneEndName;

// from the inis:
// Set 0 to not use ExitStart/ExitEnd, set higher than 1 to use ExitStart01-nn/ExitEnd01-nn
Expand Down
4 changes: 2 additions & 2 deletions src/OpenSage.Game/Logic/Object/Contain/TunnelContain.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Numerics;
using OpenSage.Data.Ini;
using OpenSage.Mathematics;
Expand All @@ -22,7 +22,7 @@ public TunnelContain(GameObject gameObject, TunnelContainModuleData moduleData)
gameObject.Owner.TunnelManager?.TunnelIds.Add(gameObject.ID);
}

internal override void OnDie(BehaviorUpdateContext context, DeathType deathType)
internal override void OnDie(BehaviorUpdateContext context, DeathType deathType, ObjectStatus? status)
{
// todo: if this is the last tunnel, everything inside should die?
GameObject.Owner.TunnelManager?.TunnelIds.Remove(GameObject.ID);
Expand Down

0 comments on commit 36c4e84

Please sign in to comment.