Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add melding repulsor #51

Merged
merged 2 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ insert_final_newline = false

# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = # this. and Me. preferences
dotnet_sort_system_directives_first = true
file_header_template = unset # this. and Me. preferences

dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
Expand Down
15 changes: 14 additions & 1 deletion UdpHosts/GameServer/Controllers/Character/BaseController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,4 +502,17 @@ public void NonDevDebugCommand(INetworkClient client, IPlayer player, ulong enti
break;
}
}
}

[MessageID((byte)Commands.UiQueryResponse)]
public void UiQueryResponse(INetworkClient client, IPlayer player, ulong entityId, GamePacket packet)
{
var response = packet.Unpack<UiQueryResponse>();

if (response.SelectedOptionId == 0)
{
return;
}

client.AssignedShard.EncounterMan.HandleUiQueryResponse(response, (INetworkPlayer)player);
}
}
1 change: 1 addition & 0 deletions UdpHosts/GameServer/Data/HardcodedCharacterData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ public static class HardcodedCharacterData

public static (uint, uint)[] FallbackInventoryResources =
[
(82628, 4001),
(10, 3531909),
(56, 11),
(30101, 98780),
Expand Down
7 changes: 6 additions & 1 deletion UdpHosts/GameServer/Entities/Deployable/DeployableEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,12 @@ public void SetAimDirection(Vector3 newDirection)

public override bool IsInteractable()
{
return Interaction != null ? Interaction.Type != 0 : false;
if (Encounter != null && !Encounter.Handles(EncounterComponent.Event.Interaction))
{
return false;
}

return Interaction != null && Interaction.Type != 0;
}

public override bool CanBeInteractedBy(IEntity other)
Expand Down
15 changes: 14 additions & 1 deletion UdpHosts/GameServer/Entities/EncounterComponent.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
using System;
using GameServer.Systems.Encounters;

namespace GameServer.Entities;

public class EncounterComponent
{
[Flags]
public enum Event : uint
{
Signal = 1 << 0,
Interaction = 1 << 1,
Donation = 1 << 2,
}

public ulong EncounterId { get; set; }
public IEncounter Instance { get; set; }
}
public Event Events { get; set; }
public bool Handles(Event type) => Events.HasFlag(type);
public void StartHandling(Event type) => Events |= type;
public void StopHandling(Event type) => Events &= ~type;
}
5 changes: 2 additions & 3 deletions UdpHosts/GameServer/Entities/Thumper/ThumperEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,13 @@ public void SetProgress(float newProgress)
ResourceNode_ObserverView.ProgressProp = Progress;
}

public void TransitionToState(ThumperState newState, uint? countdownOverride = null)
public void TransitionToState(ThumperState newState)
{
var countdownTime = countdownOverride ?? newState.CountdownTime();
StateInfo = new StateInfoStruct()
{
State = (byte)newState,
Time = Shard.CurrentTime,
CountdownTime = Shard.CurrentTime + countdownTime,
CountdownTime = Shard.CurrentTime + newState.CountdownTime(),
};
ResourceNode_ObserverView.StateInfoProp = StateInfo;
}
Expand Down
5 changes: 4 additions & 1 deletion UdpHosts/GameServer/StaticDB/CustomDBInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ public class CustomDBInterface
private static Dictionary<uint, Dictionary<uint, Deployable>> Deployable;
private static Dictionary<uint, Dictionary<uint, Melding>> Melding;
private static Dictionary<uint, Dictionary<uint, Outpost>> Outpost;
private static Dictionary<uint, Dictionary<uint, MeldingRepulsor>> MeldingRepulsor;

public static void Init()
{
Expand Down Expand Up @@ -308,6 +309,7 @@ public static void Init()
Deployable = loader.LoadDeployable();
Melding = loader.LoadMelding();
Outpost = loader.LoadOutpost();
MeldingRepulsor = loader.LoadMeldingRepulsor();
}

// aptgss
Expand Down Expand Up @@ -459,4 +461,5 @@ public static void Init()
public static Dictionary<uint, Deployable> GetZoneDeployables(uint zoneId) => Deployable.GetValueOrDefault(zoneId);
public static Dictionary<uint, Melding> GetZoneMeldings(uint zoneId) => Melding.GetValueOrDefault(zoneId);
public static Dictionary<uint, Outpost> GetZoneOutposts(uint zoneId) => Outpost.GetValueOrDefault(zoneId);
}
public static Dictionary<uint, MeldingRepulsor> GetZoneMeldingRepulsors(uint zoneId) => MeldingRepulsor.GetValueOrDefault(zoneId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8995,11 +8995,15 @@
},
{
"id": 1111837,
"comment": "Triggered by Effect 9487 "
"comment": "Triggered by Effect 9487 ",
"effect_id": 9524,
"remove_from_self": true
},
{
"id": 1111838,
"comment": "Triggered by Effect 9487 "
"comment": "Triggered by Effect 9487 ",
"effect_id": 9518,
"remove_from_self": true
},
{
"id": 1111939,
Expand Down
45 changes: 45 additions & 0 deletions UdpHosts/GameServer/StaticDB/CustomData/meldingRepulsor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"id": 1,
"zone_id": 448,
"perimiter_set_name": "Hydro_Core_Melding_02",
"repulsor": {
"type": 3695,
"orientation": {
"IsIdentity": false,
"W": -0.96569586,
"X": 0,
"Y": 0,
"Z": 0.25967574
},
"position": {
"X": -901.675,
"Y": 828.024,
"Z": 401.654
}
},
"terminal": {
"type": 1142,
"orientation": {
"IsIdentity": false,
"W": -0.96569586,
"X": 0,
"Y": 0,
"Z": 0.25967574
},
"position": {
"X": -896.65735,
"Y": 823.70123,
"Z": 401.28564
}
},
"melding_position": {
"control_point_index": 4,
"position": {
"X": -1113.637451171875,
"Y": 908.70935,
"Z": 581.6483154296875
}
}
}
]
7 changes: 7 additions & 0 deletions UdpHosts/GameServer/StaticDB/Loaders/CustomDBLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,13 @@ public Dictionary<uint, Dictionary<uint, Outpost>> LoadOutpost()
.ToDictionary(group => group.Key, group => group.ToDictionary(row => row.Id, row => row));
}

public Dictionary<uint, Dictionary<uint, MeldingRepulsor>> LoadMeldingRepulsor()
{
return LoadJSON<MeldingRepulsor>("./StaticDB/CustomData/meldingRepulsor.json")
.GroupBy(row => row.ZoneId)
.ToDictionary(group => group.Key, group => group.ToDictionary(row => row.Id, row => row));
}

private T[] LoadJSON<T>(string fileName)
{
string jsonString = File.ReadAllText(fileName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Numerics;

namespace GameServer.Data.SDB.Records.customdata;

public record MeldingRepulsor
{
public uint Id { get; set; }
public uint ZoneId { get; set; }
public string PerimiterSetName { get; set; }
public Deployable Terminal { get; set; }
public Deployable Repulsor { get; set; }
public MeldingPosition MeldingPosition { get; set; }
}

public record MeldingPosition
{
public uint ControlPointIndex { get; set; }
public Vector3 Position;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GameServer.Data.SDB.Records.customdata;
using GameServer.Entities;

namespace GameServer.Aptitude;

Expand All @@ -14,6 +15,13 @@ public EncounterSignalCommand(EncounterSignalCommandDef par)

public bool Execute(Context context)
{
var self = (BaseEntity)context.Self;

if (self.Encounter != null && self.Encounter.Handles(EncounterComponent.Event.Signal))
{
self.Encounter.Instance.OnSignal();
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public bool Execute(Context context)

if (hack.Encounter is { Instance: IInteractionHandler encounter })
{
encounter.OnInteraction(hack);
encounter.OnInteraction((BaseEntity)actingEntity, hack);

return true;
}
Expand Down
92 changes: 91 additions & 1 deletion UdpHosts/GameServer/Systems/Encounters/EncounterManager.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Numerics;
using System.Threading;
using AeroMessages.Common;
using AeroMessages.GSS.V66.Character.Command;
using AeroMessages.GSS.V66.Character.Event;
using AeroMessages.GSS.V66.Generic;
using GameServer.Data.SDB;
using GameServer.Data.SDB.Records.aptfs;
using GameServer.Entities;
using GameServer.Entities.Character;
Expand All @@ -13,15 +18,40 @@ namespace GameServer.Systems.Encounters;
public class EncounterManager
{
private const ulong _updateFlushIntervalMs = 20;
private const ulong _lifetimeCheckIntervalMs = 1000;

private readonly Shard Shard;
private ulong _lastUpdateFlush = 0;
private ulong _lastLifetimeCheck = 0;
private bool _hasSpawnedZoneEncounters = false;

private Dictionary<ulong, IEncounter> UiQueries = new Dictionary<ulong, IEncounter>();
private HashSet<IEncounter> EncountersToUpdate = new HashSet<IEncounter>();
private ConcurrentDictionary<ulong, Lifetime> LifetimeByEncounter = new ConcurrentDictionary<ulong, Lifetime>();

public EncounterManager(Shard shard)
{
Shard = shard;
}

public void SendUiQuery(NewUiQuery uiQuery, INetworkPlayer target, IEncounter encounter)
{
UiQueries.Add(uiQuery.QueryGuid, encounter);

target.NetChannels[ChannelType.ReliableGss].SendMessage(uiQuery, target.CharacterEntity.EntityId);
}

public void HandleUiQueryResponse(UiQueryResponse uiQueryResponse, INetworkPlayer player)
{
if (UiQueries.TryGetValue(uiQueryResponse.QueryGuid, out var encounter)
&& encounter is IDonationHandler donationHandler)
{
donationHandler.OnDonation(uiQueryResponse, player);

UiQueries.Remove(uiQueryResponse.QueryGuid);
}
}

public Thumper CreateThumper(
uint nodeType,
Vector3 position,
Expand All @@ -46,20 +76,75 @@ public Thumper CreateThumper(
return thumper;
}

public void SpawnZoneEncounters(uint zoneId)
{
foreach (var entry in CustomDBInterface.GetZoneMeldingRepulsors(zoneId))
{
var guid = Shard.GetNextGuid((byte)Controller.Encounter);
Shard.Encounters.Add(guid, new MeldingRepulsor(Shard, guid, new HashSet<INetworkPlayer>(), entry.Value));
}
}

public void SetRemainingLifetime(ICanTimeout encounter, uint timeMs)
{
var tracker = LifetimeByEncounter.TryGetValue(encounter.EntityId, out var value) ? value : new Lifetime();

tracker.ExpireAt = Shard.CurrentTimeLong + timeMs;
LifetimeByEncounter[encounter.EntityId] = tracker;
}

public void StartUpdatingEncounter(IEncounter encounter)
{
EncountersToUpdate.Add(encounter);
}

public void StopUpdatingEncounter(IEncounter encounter)
{
EncountersToUpdate.Remove(encounter);
}

public void Tick(double deltaTime, ulong currentTime, CancellationToken ct)
{
if (!_hasSpawnedZoneEncounters && currentTime != 0)
{
_hasSpawnedZoneEncounters = true;

if (Shard.Settings.LoadZoneEntities)
{
SpawnZoneEncounters(Shard.ZoneId);
}
}

if (currentTime > _lastUpdateFlush + _updateFlushIntervalMs)
{
_lastUpdateFlush = currentTime;

foreach (var encounter in Shard.Encounters.Values)
foreach (var encounter in EncountersToUpdate)
{
// todo add update queue
encounter.OnUpdate(currentTime);

// FlushChanges(encounter);
}
}

if (currentTime > _lastLifetimeCheck + _lifetimeCheckIntervalMs)
{
_lastLifetimeCheck = currentTime;

foreach ((ulong entityId, Lifetime tracker) in LifetimeByEncounter)
{
if (currentTime > tracker.ExpireAt)
{
if (Shard.Encounters.TryGetValue(entityId, out var e) && e is ICanTimeout encounter)
{
encounter.OnTimeOut();

LifetimeByEncounter.Remove(encounter.EntityId, out _);
}
}
}
}
}

public void Add(ulong guid, IEncounter encounter)
Expand Down Expand Up @@ -146,4 +231,9 @@ private void ScopeOut(IEncounter encounter)
player.NetChannels[ChannelType.ReliableGss].SendMessage(msg, player.CharacterEntity.EntityId);
}
}

private class Lifetime
{
public ulong ExpireAt;
}
}
Loading
Loading