|
- using System;
- using System.Runtime.CompilerServices;
-
- using RobocraftX.Character;
- using RobocraftX.Character.Movement;
- using RobocraftX.Common.Players;
- using RobocraftX.Common.Input;
- using RobocraftX.CR.MachineEditing.BoxSelect;
- using RobocraftX.Physics;
- using RobocraftX.Blocks.Ghost;
- using Gamecraft.GUI.HUDFeedbackBlocks;
- using RobocraftX.Blocks;
- using RobocraftX.Multiplayer;
- using RobocraftX.PilotSeat;
- using RobocraftX.SimulationModeState;
- using Svelto.ECS;
- using Techblox.Camera;
- using Unity.Mathematics;
- using Svelto.ECS.DataStructures;
- using Svelto.ECS.EntityStructs;
- using Techblox.BuildingDrone;
-
- using TechbloxModdingAPI.Engines;
- using TechbloxModdingAPI.Input;
- using TechbloxModdingAPI.Utility;
-
- namespace TechbloxModdingAPI.Players
- {
- internal class PlayerEngine : IFunEngine
- {
- public string Name { get; } = "TechbloxModdingAPIPlayerGameEngine";
-
- public EntitiesDB entitiesDB { set; private get; }
-
- public bool isRemovable => false;
-
- public IEntityFunctions Functions { get; set; }
-
- private bool isReady = false;
-
- public void Dispose()
- {
- isReady = false;
- }
-
- public void Ready()
- {
- isReady = true;
- }
-
- public uint GetLocalPlayer()
- {
- if (!isReady) return uint.MaxValue;
- var localPlayers = entitiesDB.QueryEntities<PlayerIDStruct>(PlayersExclusiveGroups.LocalPlayers).ToBuffer();
- if (localPlayers.count > 0)
- {
- return localPlayers.buffer[0].ID.entityID;
- }
- return uint.MaxValue;
- }
-
- public uint GetRemotePlayer()
- {
- if (!isReady) return uint.MaxValue;
- var localPlayers = entitiesDB.QueryEntities<PlayerIDStruct>(PlayersExclusiveGroups.RemotePlayers).ToBuffer();
- if (localPlayers.count > 0)
- {
- return localPlayers.buffer[0].ID.entityID;
- }
- return uint.MaxValue;
- }
-
- public long GetAllPlayerCount()
- {
- if (entitiesDB == null) return 0;
- long count = 0;
- foreach (ExclusiveGroupStruct eg in PlayersExclusiveGroups.AllPlayers)
- {
- count += entitiesDB.Count<PlayerIDStruct>(eg);
- }
- return count;
- }
-
- public long GetLocalPlayerCount()
- {
- if (entitiesDB == null) return 0;
- return entitiesDB.Count<PlayerIDStruct>(PlayersExclusiveGroups.LocalPlayers);
- }
-
- public long GetRemotePlayerCount()
- {
- if (entitiesDB == null) return 0;
- return entitiesDB.Count<PlayerIDStruct>(PlayersExclusiveGroups.RemotePlayers);
- }
-
- public bool ExistsById(uint playerId)
- {
- if (entitiesDB == null) return false;
- return entitiesDB.Exists<PlayerIDStruct>(playerId, PlayersExclusiveGroups.LocalPlayers)
- || entitiesDB.Exists<PlayerIDStruct>(playerId, PlayersExclusiveGroups.RemotePlayers);
- }
-
- public bool SetLocation(uint playerId, float3 location, bool exitSeat = true)
- {
- if (entitiesDB == null) return false;
- var rbesOpt = GetCharacterStruct<RigidBodyEntityStruct>(playerId, out var group);
- if (!rbesOpt)
- return false;
- if (group == CharacterExclusiveGroups.InPilotSeatGroup && exitSeat)
- {
- ExitSeat(playerId);
- }
- rbesOpt.Get().position = location;
- return true;
- }
-
- public bool GetGameOverScreen(uint playerId)
- {
- if (entitiesDB == null) return false;
- ref HudActivatedBlocksEntityStruct habes = ref entitiesDB.QueryEntity<HudActivatedBlocksEntityStruct>(HUDFeedbackBlocksGUIExclusiveGroups.GameOverHudEgid);
- NativeDynamicArrayCast<EGID> nativeDynamicArrayCast = new NativeDynamicArrayCast<EGID>(habes.activatedBlocksOrdered);
- return nativeDynamicArrayCast.count > 0;
- }
-
- public bool IsDead(uint playerId)
- {
- if (entitiesDB == null) return true;
- return entitiesDB.Exists<RigidBodyEntityStruct>(playerId, CharacterExclusiveGroups.DeadCharacters);
- }
-
- // reusable methods
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public OptionalRef<T> GetCharacterStruct<T>(uint playerId) where T : unmanaged, IEntityComponent =>
- GetCharacterStruct<T>(playerId, out _);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public OptionalRef<T> GetCharacterStruct<T>(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent
- {
- group = default;
- if (GameState.IsBuildMode())
- return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, LocalBuildingDrone.BuildGroup));
-
- var characterGroups = CharacterExclusiveGroups.AllCharacters;
- for (int i = 0; i < characterGroups.count; i++)
- {
- EGID egid = new EGID(playerId, characterGroups[i]);
- var opt = entitiesDB.QueryEntityOptional<T>(egid);
- if (opt.Exists)
- {
- group = characterGroups[i];
- return opt;
- }
- }
-
- return new OptionalRef<T>();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public OptionalRef<T> GetPlayerStruct<T>(uint playerId, PlayerType type) where T : unmanaged, IEntityComponent
- {
- var playerGroup = type == PlayerType.Local ? PlayersExclusiveGroups.LocalPlayers : PlayersExclusiveGroups.RemotePlayers;
- EGID egid = new EGID(playerId, playerGroup);
- return entitiesDB.QueryEntityOptional<T>(egid);
- }
-
- public OptionalRef<T> GetCameraStruct<T>(uint playerId) where T : unmanaged, IEntityComponent
- {
- return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, CameraExclusiveGroups.PhysicCameraGroup));
- }
-
- public EGID GetThingLookedAt(uint playerId, float maxDistance = -1f)
- {
- var opt = GetCameraStruct<PhysicCameraRayCastEntityStruct>(playerId);
- if (!opt) return default;
- PhysicCameraRayCastEntityStruct rayCast = opt;
- float distance = maxDistance < 0
- ? GhostBlockUtils.GetBuildInteractionDistance(entitiesDB, rayCast,
- GhostBlockUtils.GhostCastMethod.GhostCastProportionalToBlockSize)
- : maxDistance;
- if (rayCast.hit && rayCast.distance <= distance)
- return rayCast.hitEgid; //May be EGID.Empty (default)
-
- return default;
- }
-
- public unsafe Block[] GetSelectedBlocks(uint playerid)
- {
- if (!entitiesDB.Exists<BoxSelectStateEntityStruct>(playerid,
- BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup))
- return Array.Empty<Block>();
- var state = entitiesDB.QueryEntity<BoxSelectStateEntityStruct>(playerid,
- BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup);
- var blocks = entitiesDB.QueryEntity<SelectedBlocksStruct>(playerid,
- BoxSelectExclusiveGroups.BoxSelectVolumeExclusiveGroup);
- if (!state.active) return Array.Empty<Block>();
- var pointer = (EGID*) blocks.selectedBlocks.ToPointer();
- var ret = new Block[blocks.count];
- for (int j = 0; j < blocks.count; j++)
- {
- var egid = pointer[j];
- ret[j] = Block.New(egid);
- }
-
- return ret;
- }
-
- public void EnterSeat(uint playerId, EGID seatId)
- {
- if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
- return;
- PilotSeatGroupUtils.SwapTagTo<OCCUPIED_TAG>(Functions, seatId);
- var opt = GetCharacterStruct<CharacterPilotSeatEntityStruct>(playerId, out var group);
- if (!opt) return;
- ref CharacterPilotSeatEntityStruct charSeat = ref opt.Get();
- var charId = new EGID(playerId, group);
- charSeat.pilotSeatEntity = entitiesDB.GetEntityReference(seatId);
- charSeat.entryPositionOffset =
- entitiesDB.QueryEntity<PositionEntityStruct>(charId).position -
- entitiesDB.QueryEntity<PositionEntityStruct>(seatId).position;
- ref var seat = ref entitiesDB.QueryEntity<PilotSeatEntityStruct>(seatId);
- seat.occupyingCharacter = entitiesDB.GetEntityReference(charId);
- charSeat.followCam = entitiesDB.QueryEntity<SeatFollowCamComponent>(seatId).followCam;
- Functions.SwapEntityGroup<CharacterEntityDescriptor>(charId, CharacterExclusiveGroups.InPilotSeatGroup);
- }
-
- public void ExitSeat(uint playerId)
- {
- if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
- return;
- EGID egid = new EGID(playerId, CharacterExclusiveGroups.InPilotSeatGroup);
- var opt = entitiesDB.QueryEntityOptional<CharacterPilotSeatEntityStruct>(egid);
- if (!opt) return;
- opt.Get().instantExit = true;
- entitiesDB.PublishEntityChange<CharacterPilotSeatEntityStruct>(egid);
- }
-
- public bool SpawnMachine(uint playerId)
- {
- if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
- return false;
- EGID egid = new EGID(playerId, CharacterExclusiveGroups.MachineSpawningGroup);
- if (!entitiesDB.Exists<CharacterTagEntityStruct>(egid))
- return false;
- //Functions.SwapEntityGroup<CharacterEntityDescriptor>(egid, CharacterExclusiveGroups.OnFootGroup);
- FakeInput.ActionInput(playerId, primary: true);
- return true;
- }
-
- public bool DespawnMachine(uint playerId)
- {
- if (!TimeRunningModeUtil.IsTimeRunningMode(entitiesDB))
- return false;
- GetCharacterStruct<CharacterTagEntityStruct>(playerId, out var group);
- if (group.isInvalid)
- return false;
- EGID egid = new EGID(playerId, group);
- if (!entitiesDB.Exists<CharacterTagEntityStruct>(egid))
- return false;
- Functions.SwapEntityGroup<CharacterEntityDescriptor>(egid, CharacterExclusiveGroups.MachineSpawningGroup);
- return true;
- }
-
- public uint GetPing()
- {
- return entitiesDB
- .QueryUniqueEntity<NetworkStatsEntityStruct>(MultiplayerExclusiveGroups.MultiplayerStateGroup)
- .networkStats.PingMs;
- }
- }
- }
|