diff --git a/SDK b/SDK index c266ae1a3..4ca9e317e 160000 --- a/SDK +++ b/SDK @@ -1 +1 @@ -Subproject commit c266ae1a3318bdb2edb60b4e18d1cd04440ac8d9 +Subproject commit 4ca9e317e5c541689d0f6a6b7d8f51f7ff316273 diff --git a/Server/Components/NPCs/NPC/npc.cpp b/Server/Components/NPCs/NPC/npc.cpp index 8a6620702..57a5a6769 100644 --- a/Server/Components/NPCs/NPC/npc.cpp +++ b/Server/Components/NPCs/NPC/npc.cpp @@ -141,8 +141,7 @@ void NPC::spawn() npcComponent_->emulateRPCIn(*player_, NetCode::RPC::PlayerRequestSpawn::PacketID, emptyBS); npcComponent_->emulateRPCIn(*player_, NetCode::RPC::PlayerSpawn::PacketID, emptyBS); - // Make sure we resend this again, at spawn - player_->setSkin(player_->getSkin()); + setSkin(skin_); // Set the player stats setHealth(100.0f); @@ -158,6 +157,38 @@ void NPC::spawn() npcComponent_->getEventDispatcher_internal().dispatch(&NPCEventHandler::onNPCSpawn, *this); } +void NPC::respawn() +{ + //npcComponent_->getCore()->getPlayers().sendClientMessageToAll(Colour::White(), String("State: " + player_->getState())); + if (!(player_->getState() == PlayerState_OnFoot || player_->getState() == PlayerState_Driver || player_->getState() == PlayerState_Passenger || player_->getState() == PlayerState_Spawned)) + { + npcComponent_->getCore()->printLn("NPC is not in a valid state to respawn"); + return; + } + + setSkin(skin_); + setPosition(position_); + setRotation(getRotation()); + + if (isEqualFloat(getHealth(), 0.0f)) { + setHealth(100.0f); + setArmour(0.0f); + } else { + setHealth(getHealth()); + setArmour(getArmour()); + } + + setWeapon(weapon_); + setAmmo(ammo_); + + dead_ = false; + + lastDamager_ = nullptr; + lastDamagerWeapon_ = PlayerWeapon_End; + + npcComponent_->getEventDispatcher_internal().dispatch(&NPCEventHandler::onNPCRespawn, *this); +} + bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed) { if (moveType == NPCMoveType_None) @@ -170,6 +201,8 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed) stopAim(); } + resetKeys(); + // Set up everything to start moving in next tick auto position = getPosition(); float distance = glm::distance(position, pos); @@ -239,7 +272,7 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed) if (!(std::fabs(glm::length(velocity_)) < DBL_EPSILON)) { - estimatedArrivalTimeMS_ = duration_cast(Time::now().time_since_epoch()).count() + (static_cast(distance / glm::length(velocity_)) * (/* (npcComponent_->getFootSyncRate() * 10000) +*/ 1000)); + estimatedArrivalTimeMS_ = duration_cast(Time::now().time_since_epoch()).count() + (static_cast(distance / glm::length(velocity_))/* * (npcComponent_->getFootSyncRate() * 10000)*/); } else { @@ -254,6 +287,12 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed) return true; } +bool NPC::moveToPlayer(IPlayer& player, NPCMoveType moveType, float moveSpeed) +{ + auto pos = player.getPosition(); + return move(pos, moveType, moveSpeed); +} + void NPC::stopMove() { moving_ = false; @@ -276,6 +315,7 @@ bool NPC::isMoving() const void NPC::setSkin(int model) { + skin_ = model; player_->setSkin(model); } diff --git a/Server/Components/NPCs/NPC/npc.hpp b/Server/Components/NPCs/NPC/npc.hpp index 44a2456f8..0fadf38bd 100644 --- a/Server/Components/NPCs/NPC/npc.hpp +++ b/Server/Components/NPCs/NPC/npc.hpp @@ -33,8 +33,12 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy void spawn() override; + void respawn() override; + bool move(Vector3 position, NPCMoveType moveType, float moveSpeed = NPC_MOVE_SPEED_AUTO) override; + bool moveToPlayer(IPlayer& player, NPCMoveType moveType, float moveSpeed = NPC_MOVE_SPEED_AUTO) override; + void stopMove() override; bool isMoving() const override; diff --git a/Server/Components/Pawn/Scripting/NPC/Natives.cpp b/Server/Components/Pawn/Scripting/NPC/Natives.cpp index d3189c69a..bb1957205 100644 --- a/Server/Components/Pawn/Scripting/NPC/Natives.cpp +++ b/Server/Components/Pawn/Scripting/NPC/Natives.cpp @@ -42,6 +42,12 @@ SCRIPT_API(NPC_Spawn, bool(INPC& npc)) return true; } +SCRIPT_API(NPC_Respawn, bool(INPC& npc)) +{ + npc.respawn(); + return true; +} + SCRIPT_API(NPC_SetPos, bool(INPC& npc, Vector3 position)) { npc.setPosition(position); @@ -97,6 +103,11 @@ SCRIPT_API(NPC_Move, bool(INPC& npc, Vector3 targetPos, int moveType, float move return npc.move(targetPos, NPCMoveType(moveType), moveSpeed); } +SCRIPT_API(NPC_MoveToPlayer, bool(INPC& npc, IPlayer& player, int moveType, float moveSpeed)) +{ + return npc.moveToPlayer(player, NPCMoveType(moveType), moveSpeed); +} + SCRIPT_API(NPC_StopMove, bool(INPC& npc)) { npc.stopMove();