mirror of
https://github.com/ncblakely/GiantsTools
synced 2024-12-22 15:27:22 +01:00
Update SDK for 1.5.1.103.
This commit is contained in:
parent
71b675f5cb
commit
6a455cb09c
@ -1,179 +0,0 @@
|
||||
#include "AI/Public/Behaviors/DodgeBehavior.h"
|
||||
#include "AI/Public/Components/Senses.h"
|
||||
#include "AI/Public/Components/MoveEnactor.h"
|
||||
#include "AI/Public/Components/PhysicsView.h"
|
||||
#include "GameObject/Public/Core.h"
|
||||
#include "Navigation/Public/Core.h"
|
||||
#include "projectile.h"
|
||||
|
||||
namespace AI
|
||||
{
|
||||
using namespace beehive;
|
||||
using namespace ECS;
|
||||
using namespace GameObj;
|
||||
using namespace Nav;
|
||||
|
||||
// TODO: Parameterize
|
||||
const float DodgeStartTime = 5.0f;
|
||||
const float DodgeSafeRadius = 10.0f;
|
||||
|
||||
static bool DodgeTargetValid(const std::optional<DodgeTarget>& target)
|
||||
{
|
||||
return target && !target->Projectile.expired();
|
||||
}
|
||||
|
||||
static float GetTimeToImpact(const P3D& avoidLocation, const PhysicsView& projectilePhysics)
|
||||
{
|
||||
float timeToImpact = avoidLocation.Distance3D(projectilePhysics.Location) / projectilePhysics.Velocity.Length();
|
||||
return timeToImpact;
|
||||
}
|
||||
|
||||
static void AbortDodge(DodgeBehaviorState& state, BehaviorTreeContext& context)
|
||||
{
|
||||
state.DodgeTarget = std::nullopt;
|
||||
context.ResetResumeIndex();
|
||||
}
|
||||
|
||||
static std::optional<DodgeTarget> ChooseDodgeTarget(Entity* entity, Senses& senses, const PhysicsView& objectPhysics)
|
||||
{
|
||||
Object* aiObject = entity->GetComponent<ObjectRef>().GetObj();
|
||||
|
||||
std::sort(senses.KnownEnemyProjectiles.begin(), senses.KnownEnemyProjectiles.end(), [&objectPhysics](const auto& e1, const auto& e2)
|
||||
{
|
||||
const PhysicsView& entity1Physics = e1->GetComponent<PhysicsView>();
|
||||
const PhysicsView& entity2Physics = e2->GetComponent<PhysicsView>();
|
||||
|
||||
return entity1Physics.Location.DistanceSquared3D(objectPhysics.Location) < entity2Physics.Location.DistanceSquared3D(objectPhysics.Location);
|
||||
});
|
||||
|
||||
for (const auto& projectile : senses.KnownEnemyProjectiles)
|
||||
{
|
||||
Object* projectileObject = projectile->GetComponent<ObjectRef>().GetObj();
|
||||
const PhysicsView& projectilePhysics = projectile->GetComponent<PhysicsView>();
|
||||
ObjSpecProjectile* spec = ObjSpecProjectile::Cast(projectileObject);
|
||||
|
||||
if (!spec->ground_collision)
|
||||
{
|
||||
TRACE_BEHAVIOR("Projectile is not expected to collide with ground");
|
||||
continue;
|
||||
}
|
||||
|
||||
const PROJ_Def* def = PROJ_DefGet(spec->projectile_index);
|
||||
|
||||
float speed = projectileObject->velocity.Length();
|
||||
float timeToImpact = GetTimeToImpact(spec->ground_collision_position, projectilePhysics);
|
||||
if (timeToImpact > DodgeStartTime)
|
||||
{
|
||||
TRACE_BEHAVIOR("Projectile time to impact of {0} is above threshold", timeToImpact);
|
||||
continue;
|
||||
}
|
||||
|
||||
P3D aiProjectedLocation = aiObject->location + (aiObject->velocity * timeToImpact);
|
||||
if (aiProjectedLocation.DistanceSquared3D(spec->ground_collision_position) < Squared(def->fardist))
|
||||
{
|
||||
return DodgeTarget{ projectile, def->fardist, spec->ground_collision_position };
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool DodgeBehavior::ShouldStartDodge(Entity* entity, Object* object, BehaviorTreeContext& context)
|
||||
{
|
||||
if (!entity->HasComponent<Senses, PhysicsView>())
|
||||
return false;
|
||||
|
||||
if (!World->navMesh)
|
||||
return false;
|
||||
|
||||
auto& state = entity->GetComponent<DodgeBehaviorState>();
|
||||
if (!DodgeTargetValid(state.DodgeTarget))
|
||||
{
|
||||
// Make sure invalid targets have been cleared out
|
||||
state.DodgeTarget = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already have dodge in progress
|
||||
return false;
|
||||
}
|
||||
|
||||
auto [senses, physicsView] = entity->GetComponent<Senses, PhysicsView>();
|
||||
|
||||
state.DodgeTarget = ChooseDodgeTarget(entity, senses, physicsView);
|
||||
if (!state.DodgeTarget)
|
||||
{
|
||||
// No nearby threats
|
||||
return false;
|
||||
}
|
||||
|
||||
float angleToCenter = dirfcalcp3d(&state.DodgeTarget->AvoidLocation, &physicsView.Location);
|
||||
|
||||
float sa, ca;
|
||||
calc_sincosd(dirfadjust(angleToCenter), &sa, &ca);
|
||||
P3D wantLoc = state.DodgeTarget->AvoidLocation;
|
||||
wantLoc.x += (state.DodgeTarget->ImpactRadius + DodgeSafeRadius) * ca;
|
||||
wantLoc.y += (state.DodgeTarget->ImpactRadius + DodgeSafeRadius) * sa;
|
||||
|
||||
MoveGoalParams params;
|
||||
params.Speed = MoveGoalSpeed::Fast;
|
||||
std::shared_ptr<Path> path = PathUtil::GetPath(entity, World->navMesh.get(), physicsView.Location, wantLoc, ¶ms);
|
||||
if (!path)
|
||||
{
|
||||
TRACE_BEHAVIOR("Couldn't path away from projectile");
|
||||
return false;
|
||||
}
|
||||
|
||||
TRACE_BEHAVIOR("Dodging to location {0} {1} {2}, est. impact time {3}",
|
||||
wantLoc.x,
|
||||
wantLoc.y,
|
||||
wantLoc.z,
|
||||
GetTimeToImpact(state.DodgeTarget->AvoidLocation, state.DodgeTarget->Projectile.lock()->GetComponent<PhysicsView>()));
|
||||
|
||||
PathUtil::SetPath(entity, path);
|
||||
|
||||
context.SetChainingEnabled(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
Status DodgeBehavior::MoveToDodgeLocation(Entity* entity, Object* object, BehaviorTreeContext& context)
|
||||
{
|
||||
auto& state = entity->GetComponent<DodgeBehaviorState>();
|
||||
const auto& moveEnactor = entity->GetComponent<MoveEnactor>();
|
||||
|
||||
if (!DodgeTargetValid(state.DodgeTarget)
|
||||
|| !moveEnactor.Path)
|
||||
{
|
||||
TRACE_BEHAVIOR("Dodge target no longer valid; canceling");
|
||||
AbortDodge(state, context);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
const auto& aiPhysics = entity->GetComponent<PhysicsView>();
|
||||
|
||||
float distanceFromImpactSq = state.DodgeTarget->AvoidLocation.DistanceSquared3D(aiPhysics.Location);
|
||||
if (distanceFromImpactSq > Squared(state.DodgeTarget->ImpactRadius + DodgeSafeRadius))
|
||||
{
|
||||
// Got far enough away somehow, we can reset
|
||||
TRACE_BEHAVIOR("AI is {0} units away from impact location with still active dodge behavior; canceling", sqrt(distanceFromImpactSq));
|
||||
AbortDodge(state, context);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
return Status::RUNNING;
|
||||
}
|
||||
|
||||
InnerBehaviorTree DodgeBehavior::Build(ECS::Entity* entity)
|
||||
{
|
||||
assert(entity);
|
||||
|
||||
DodgeBehaviorState& state = entity->AddComponent<DodgeBehaviorState>();
|
||||
|
||||
return BehaviorTreeBuilder()
|
||||
.sequence()
|
||||
.leaf(CreateLeaf(entity, ShouldStartDodge))
|
||||
.leaf(CreateLeaf(entity, MoveToDodgeLocation))
|
||||
.end()
|
||||
.build();
|
||||
}
|
||||
}
|
7
Sdk/Include/Core/Public/EventListenerResult.h
Normal file
7
Sdk/Include/Core/Public/EventListenerResult.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
enum class EventListenerResult
|
||||
{
|
||||
Continue,
|
||||
Cancel
|
||||
};
|
@ -3,11 +3,13 @@
|
||||
#include <functional>
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "EventListenerResult.h"
|
||||
|
||||
template<typename TEventType, typename TEvent>
|
||||
struct IEventSource
|
||||
{
|
||||
virtual ~IEventSource() = default;
|
||||
|
||||
virtual GUID Listen(TEventType event, std::function<void(const TEvent&)> function) noexcept = 0;
|
||||
virtual GUID Listen(TEventType event, std::function<EventListenerResult(const TEvent&)> function) noexcept = 0;
|
||||
virtual void Unlisten(TEventType event, GUID uuid) noexcept = 0;
|
||||
};
|
@ -7,9 +7,6 @@
|
||||
enum class NetPlayerState;
|
||||
enum class GameTeam;
|
||||
|
||||
// {770DEBD3-165D-4340-829D-5262F473FBE3}
|
||||
inline const GUID IID_ITextLookupService = { 0x770debd3, 0x165d, 0x4340, 0x82, 0x9d, 0x52, 0x62, 0xf4, 0x73, 0xfb, 0xe3 };
|
||||
|
||||
/// <summary>
|
||||
/// Service providing localization of text placeholders and friendly-name mappings of common enums.
|
||||
/// </summary>
|
||||
|
@ -46,6 +46,7 @@ struct ChatMessageEvent : GameServerEvent
|
||||
|
||||
tstring_view message{};
|
||||
PlayerIndex senderIndex{};
|
||||
ChatFlag flags{};
|
||||
};
|
||||
|
||||
struct WorldLoadedEvent : GameServerEvent
|
||||
|
@ -8,9 +8,6 @@
|
||||
#include "GameServerEvents.h"
|
||||
#include "NetCommon.h"
|
||||
|
||||
// {B2D67EE7-8063-488F-B3B9-E7DA675CB752}
|
||||
inline const GUID IID_IGameServer = { 0xb2d67ee7, 0x8063, 0x488f, 0xb3, 0xb9, 0xe7, 0xda, 0x67, 0x5c, 0xb7, 0x52 };
|
||||
|
||||
/// <summary>
|
||||
/// Defines an API for communicating with the game server.
|
||||
/// </summary>
|
||||
@ -31,15 +28,24 @@ DEFINE_SERVICE_MULTI("{B2D67EE7-8063-488F-B3B9-E7DA675CB752}", IGameServer, IEve
|
||||
/// Bans the player at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The player index.</param>
|
||||
/// <returns></returns>
|
||||
virtual void BanPlayer(int index) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Removes the IP address from the ban list.
|
||||
/// </summary>
|
||||
/// <param name="index">The IP address.</param>
|
||||
virtual void UnbanPlayer(const IPAddress & ipAddress) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IP addresses that are currently banned.
|
||||
/// </summary>
|
||||
virtual const std::vector<IPAddress> GetBans() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Kicks the player at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The player index.</param>
|
||||
/// <param name="reason">The reason for kicking the player.</param>
|
||||
/// <returns></returns>
|
||||
virtual void KickPlayer(int index, KickReason reason) = 0;
|
||||
|
||||
/// <summary>
|
||||
@ -72,6 +78,4 @@ DEFINE_SERVICE_MULTI("{B2D67EE7-8063-488F-B3B9-E7DA675CB752}", IGameServer, IEve
|
||||
/// </summary>
|
||||
/// <param name="gameDetails">The game details.</param>
|
||||
virtual void ChangeGameDetails(const NetGameDetails& gameDetails) = 0;
|
||||
};
|
||||
|
||||
struct DECLSPEC_UUID("{B2D67EE7-8063-488F-B3B9-E7DA675CB752}") IGameServer;
|
||||
};
|
@ -7,9 +7,6 @@
|
||||
|
||||
typedef std::future<std::vector<ServerInfoResponse>> ServerInfoFuture;
|
||||
|
||||
// {EE129A81-0A86-49C4-8D23-A771A7350952}
|
||||
inline const GUID IID_IGiantsApiClient = { 0xee129a81, 0xa86, 0x49c4, 0x8d, 0x23, 0xa7, 0x71, 0xa7, 0x35, 0x9, 0x52 };
|
||||
|
||||
DEFINE_SERVICE("{EE129A81-0A86-49C4-8D23-A771A7350952}", IGiantsApiClient)
|
||||
{
|
||||
virtual ~IGiantsApiClient() = default;
|
||||
@ -17,6 +14,4 @@ DEFINE_SERVICE("{EE129A81-0A86-49C4-8D23-A771A7350952}", IGiantsApiClient)
|
||||
virtual void DeleteServerInformationAsync(tstring_view gameName, int hostPort) = 0;
|
||||
virtual ServerInfoFuture GetServerInformationAsync() = 0;
|
||||
virtual void PostServerInformationAsync(const nlohmann::json& requestBody) = 0;
|
||||
};
|
||||
|
||||
struct DECLSPEC_UUID("{EE129A81-0A86-49C4-8D23-A771A7350952}") IGiantsApiClient;
|
||||
};
|
82
Sdk/Include/Network/Public/IPAddress.h
Normal file
82
Sdk/Include/Network/Public/IPAddress.h
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
|
||||
class IPAddress
|
||||
{
|
||||
public:
|
||||
int operator[](int index) const
|
||||
{
|
||||
if (index < countof(m_octets) && index > 0)
|
||||
{
|
||||
return m_octets[index];
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Invalid octet index.");
|
||||
}
|
||||
|
||||
bool operator==(const IPAddress& right) const
|
||||
{
|
||||
return (m_octets[0] == right.m_octets[0] &&
|
||||
m_octets[1] == right.m_octets[1] &&
|
||||
m_octets[2] == right.m_octets[2] &&
|
||||
m_octets[3] == right.m_octets[3]);
|
||||
}
|
||||
|
||||
bool operator!= (const IPAddress& right) const
|
||||
{
|
||||
return !operator==(right);
|
||||
}
|
||||
|
||||
bool operator<(const IPAddress& right) const
|
||||
{
|
||||
return ToInt() < right.ToInt();
|
||||
}
|
||||
|
||||
bool operator>(const IPAddress& right) const
|
||||
{
|
||||
return right.operator<(*this);
|
||||
}
|
||||
|
||||
static IPAddress FromString(const tstring_view str)
|
||||
{
|
||||
IPAddress ipAddress;
|
||||
|
||||
char octetBuff[4]{};
|
||||
std::string tmp(str);
|
||||
std::istringstream iss(tmp);
|
||||
|
||||
int octetsRead = 0;
|
||||
while (true)
|
||||
{
|
||||
iss.getline(octetBuff, sizeof(octetBuff), '.');
|
||||
|
||||
if (iss.gcount() <= 0)
|
||||
break;
|
||||
|
||||
int octet = atoi(octetBuff);
|
||||
if (octet > 255 || octet < 0)
|
||||
{
|
||||
throw std::invalid_argument(fmt::format("Octet '{0}' is invalid.", octet));
|
||||
}
|
||||
|
||||
ipAddress.m_octets[octetsRead] = octet;
|
||||
octetsRead++;
|
||||
}
|
||||
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return fmt::sprintf("%d.%d.%d.%d", m_octets[0], m_octets[1], m_octets[2], m_octets[3]);
|
||||
}
|
||||
|
||||
uint ToInt() const
|
||||
{
|
||||
return ((m_octets[0] << 24) + (m_octets[1] << 16) + (m_octets[2] << 8) + m_octets[3]);
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_octets[4]{};
|
||||
};
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "IPAddress.h"
|
||||
|
||||
typedef int PlayerIndex;
|
||||
typedef int PlayerTeamIndex;
|
||||
|
||||
@ -81,13 +83,14 @@ enum class GameTeam
|
||||
struct PlayerInfo
|
||||
{
|
||||
PlayerIndex index = 0;
|
||||
std::string name;
|
||||
tstring name;
|
||||
float score = 0;
|
||||
float deaths = 0;
|
||||
int ping = 0;
|
||||
PlayerTeamIndex team = 0;
|
||||
bool host = false;
|
||||
NetPlayerState state = NetPlayerState::None;
|
||||
IPAddress ipAddress;
|
||||
};
|
||||
|
||||
struct NetGameSettings
|
||||
@ -105,6 +108,7 @@ struct NetGameSettings
|
||||
bool vimpsDisabled = false;
|
||||
bool weaponAvailabilityModified = false;
|
||||
int worldId = 0;
|
||||
tstring sessionName;
|
||||
};
|
||||
|
||||
struct NetGameDetails
|
||||
@ -112,7 +116,7 @@ struct NetGameDetails
|
||||
// User-adjustable settings for the current game.
|
||||
NetGameSettings settings;
|
||||
|
||||
std::string worldName;
|
||||
std::string teamTypeName;
|
||||
std::string gameTypeName;
|
||||
tstring worldName;
|
||||
tstring teamTypeName;
|
||||
tstring gameTypeName;
|
||||
};
|
@ -28,6 +28,7 @@ ServerDialog::~ServerDialog()
|
||||
pGameServer->Unlisten(GameServerEventType::PlayerConnected, m_playerConnectedEventHandle);
|
||||
pGameServer->Unlisten(GameServerEventType::PlayerDisconnected, m_playerDisconnectedEventHandle);
|
||||
pGameServer->Unlisten(GameServerEventType::ChatMessage, m_playerChatMessageHandle);
|
||||
pGameServer->Unlisten(GameServerEventType::WorldLoaded, m_worldLoadedHandle);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user