Skip to content

Commit dab6886

Browse files
authored
Merge pull request #1135 from openmultiplayer/amir/npc-fixes
Some NPC fixes and changes
2 parents 787ef4d + 5db04b8 commit dab6886

File tree

8 files changed

+123
-25
lines changed

8 files changed

+123
-25
lines changed

SDK

Server/Components/CAPI/Impl/NPCs/APIs.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
#include "../ComponentManager.hpp"
1010
#include <Server/Components/NPCs/npcs.hpp>
1111

12-
OMP_CAPI(NPC_Create, objectPtr(const char* name))
12+
OMP_CAPI(NPC_Create, objectPtr(StringCharPtr name, int* id))
1313
{
1414
COMPONENT_CHECK_RET(npcs, nullptr);
1515
if (name)
1616
{
1717
auto npc = npcs->create(name);
1818
if (npc)
1919
{
20+
*id = npc->getID();
2021
return npc;
2122
}
2223
}
@@ -48,6 +49,12 @@ OMP_CAPI(NPC_IsValid, bool(objectPtr npc))
4849
return npcs->get(npc_->getID()) != nullptr;
4950
}
5051

52+
OMP_CAPI(NPC_GetPlayer, objectPtr(objectPtr npc))
53+
{
54+
POOL_ENTITY_RET(npcs, INPC, npc, npc_, nullptr);
55+
return npc_->getPlayer();
56+
}
57+
5158
OMP_CAPI(NPC_Spawn, bool(objectPtr npc))
5259
{
5360
POOL_ENTITY_RET(npcs, INPC, npc, npc_, false);
@@ -782,7 +789,7 @@ OMP_CAPI(NPC_GetAnimation, bool(objectPtr npc, int* animationId, float* delta, b
782789
return true;
783790
}
784791

785-
OMP_CAPI(NPC_ApplyAnimation, bool(objectPtr npc, const char* animlib, const char* animname, float delta, bool loop, bool lockX, bool lockY, bool freeze, int time))
792+
OMP_CAPI(NPC_ApplyAnimation, bool(objectPtr npc, StringCharPtr animlib, StringCharPtr animname, float delta, bool loop, bool lockX, bool lockY, bool freeze, int time))
786793
{
787794
POOL_ENTITY_RET(npcs, INPC, npc, npc_, false);
788795
if (!animlib || !animname)
@@ -814,7 +821,7 @@ OMP_CAPI(NPC_GetSpecialAction, int(objectPtr npc))
814821
return npc_->getSpecialAction();
815822
}
816823

817-
OMP_CAPI(NPC_StartPlayback, bool(objectPtr npc, const char* recordName, bool autoUnload, float startPosX, float startPosY, float startPosZ, float startRotX, float startRotY, float startRotZ))
824+
OMP_CAPI(NPC_StartPlayback, bool(objectPtr npc, StringCharPtr recordName, bool autoUnload, float startPosX, float startPosY, float startPosZ, float startRotX, float startRotY, float startRotZ))
818825
{
819826
POOL_ENTITY_RET(npcs, INPC, npc, npc_, false);
820827
if (!recordName)
@@ -856,7 +863,7 @@ OMP_CAPI(NPC_IsPlaybackPaused, bool(objectPtr npc))
856863
return npc_->isPlaybackPaused();
857864
}
858865

859-
OMP_CAPI(NPC_LoadRecord, int(const char* filePath))
866+
OMP_CAPI(NPC_LoadRecord, int(StringCharPtr filePath))
860867
{
861868
COMPONENT_CHECK_RET(npcs, -1);
862869
if (filePath)

Server/Components/NPCs/NPC/npc.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ NPC::NPC(NPCComponent* component, IPlayer* playerPtr)
7171
, aimOffsetFrom_({ 0.0f, 0.0f, 0.0f })
7272
, aimOffset_({ 0.0f, 0.0f, 0.0f })
7373
, updateAimAngle_(false)
74+
, playerAimingAt_(nullptr)
7475
, betweenCheckFlags_(EntityCheckType::None)
7576
, hitId_(0)
7677
, hitType_(PlayerBulletHitType_None)
@@ -507,6 +508,11 @@ bool NPC::isMoving() const
507508
return moving_;
508509
}
509510

511+
bool NPC::isMovingToPlayer(IPlayer& player) const
512+
{
513+
return followingPlayer_ != nullptr;
514+
}
515+
510516
void NPC::setSkin(int model)
511517
{
512518
player_->setSkin(model);
@@ -1153,24 +1159,22 @@ void NPC::aimAt(const Vector3& point, bool shoot, int shootDelay, bool setAngle,
11531159
return;
11541160
}
11551161

1156-
// Set the aiming flag
1157-
if (!aiming_)
1162+
if (aiming_)
11581163
{
1159-
// Get the shooting start tick
1160-
shootUpdateTime_ = lastUpdate_;
1161-
reloading_ = false;
1164+
stopAim();
11621165
}
11631166

1167+
// Get the shooting start tick
1168+
shootUpdateTime_ = lastUpdate_;
1169+
reloading_ = false;
1170+
11641171
// Update aiming data
11651172
aimOffsetFrom_ = offsetFrom;
11661173
updateAimData(point, setAngle);
11671174

11681175
// Set keys
1169-
if (!aiming_)
1170-
{
1171-
aiming_ = true;
1172-
applyKey(Key::AIM);
1173-
}
1176+
applyKey(Key::AIM);
1177+
aiming_ = true;
11741178

11751179
// Set the shoot delay
11761180
auto updateRate = npcComponent_->getGeneralNPCUpdateRate();
@@ -1196,6 +1200,7 @@ void NPC::aimAtPlayer(IPlayer& atPlayer, bool shoot, int shootDelay, bool setAng
11961200
hitId_ = atPlayer.getID();
11971201
hitType_ = PlayerBulletHitType_Player;
11981202
aimOffset_ = offset;
1203+
playerAimingAt_ = &atPlayer;
11991204
}
12001205

12011206
void NPC::stopAim()
@@ -1219,6 +1224,7 @@ void NPC::stopAim()
12191224
hitType_ = PlayerBulletHitType_None;
12201225
updateAimAngle_ = false;
12211226
betweenCheckFlags_ = EntityCheckType::None;
1227+
playerAimingAt_ = nullptr;
12221228

12231229
// Reset keys
12241230
removeKey(Key::AIM);
@@ -1878,6 +1884,16 @@ void NPC::updateWeaponState()
18781884
}
18791885
}
18801886

1887+
IPlayer* NPC::getPlayerAimingAt()
1888+
{
1889+
return playerAimingAt_;
1890+
}
1891+
1892+
IPlayer* NPC::getPlayerMovingTo()
1893+
{
1894+
return followingPlayer_;
1895+
}
1896+
18811897
void NPC::kill(IPlayer* killer, uint8_t weapon)
18821898
{
18831899
if (dead_)

Server/Components/NPCs/NPC/npc.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
5050

5151
bool isMoving() const override;
5252

53+
bool isMovingToPlayer(IPlayer& player) const override;
54+
5355
void setSkin(int model) override;
5456

5557
bool isStreamedInForPlayer(const IPlayer& other) const override;
@@ -112,6 +114,8 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
112114

113115
PlayerWeaponState getWeaponState() const override;
114116

117+
void setWeaponState(PlayerWeaponState state) override;
118+
115119
void setAmmoInClip(int ammo) override;
116120

117121
int getAmmoInClip() const override;
@@ -246,16 +250,18 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
246250

247251
void resetSurfingData() override;
248252

253+
void kill(IPlayer* killer, uint8_t weapon) override;
254+
255+
IPlayer* getPlayerAimingAt() override;
256+
257+
IPlayer* getPlayerMovingTo() override;
258+
249259
void setAnimation(uint16_t animationId, uint16_t flags);
250260

251261
void processPlayback(TimePoint now);
252262

253-
void setWeaponState(PlayerWeaponState state);
254-
255263
void updateWeaponState();
256264

257-
void kill(IPlayer* killer, uint8_t weapon);
258-
259265
void processDamage(IPlayer* damager, float damage, uint8_t weapon, BodyPart bodyPart, bool handleHealthAndArmour);
260266

261267
void updateAim();
@@ -465,6 +471,7 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
465471
Vector3 aimOffsetFrom_;
466472
Vector3 aimOffset_;
467473
bool updateAimAngle_;
474+
IPlayer* playerAimingAt_;
468475

469476
// Weapon raycast/shot checks data
470477
EntityCheckType betweenCheckFlags_;

Server/Components/NPCs/Playback/playback.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ struct NPCRecord
2727
DynamicArray<NetCode::Packet::PlayerVehicleSync> vehicleData;
2828
};
2929

30-
constexpr int INVALID_RECORD_ID = -1;
31-
3230
class NPC;
3331
class NPCRecordManager;
3432

Server/Components/NPCs/npcs_impl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ void NPCComponent::onPoolEntryDestroyed(IPlayer& player)
187187
npc->stopMove();
188188
npc->resetFollowingPlayer();
189189
}
190+
191+
if (npc->isAiming() && npc->isAimingAtPlayer(player))
192+
{
193+
npc->stopAim();
194+
}
190195
}
191196
}
192197

@@ -284,7 +289,7 @@ void NPCComponent::destroy(INPC& npc)
284289
int NPCComponent::createPath()
285290
{
286291
NPCPath* path = pathManager_.create();
287-
return path ? path->getID() : -1;
292+
return path ? path->getID() : INVALID_PATH_ID;
288293
}
289294

290295
bool NPCComponent::destroyPath(int pathId)

Server/Components/Pawn/Scripting/NPC/Natives.cpp

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,27 @@ SCRIPT_API(NPC_IsMoving, bool(INPC& npc))
123123
return npc.isMoving();
124124
}
125125

126+
SCRIPT_API(NPC_IsMovingToPlayer, bool(INPC& npc, IPlayer& player))
127+
{
128+
return npc.isMovingToPlayer(player);
129+
}
130+
126131
SCRIPT_API(NPC_SetSkin, bool(INPC& npc, int model))
127132
{
128133
npc.setSkin(model);
129134
return true;
130135
}
131136

137+
SCRIPT_API(NPC_GetSkin, bool(INPC& npc))
138+
{
139+
auto player = npc.getPlayer();
140+
if (player)
141+
{
142+
return player->getSkin();
143+
}
144+
return -1;
145+
}
146+
132147
SCRIPT_API(NPC_IsStreamedIn, bool(INPC& npc, IPlayer& player))
133148
{
134149
return npc.isStreamedInForPlayer(player);
@@ -932,15 +947,15 @@ SCRIPT_API(NPC_IsInvulnerable, bool(INPC& npc))
932947
return npc.isInvulnerable();
933948
}
934949

935-
SCRIPT_API(NPC_SetSurfingOffset, bool(INPC& npc, Vector3 offset))
950+
SCRIPT_API(NPC_SetSurfingOffsets, bool(INPC& npc, Vector3 offset))
936951
{
937952
auto data = npc.getSurfingData();
938953
data.offset = offset;
939954
npc.setSurfingData(data);
940955
return true;
941956
}
942957

943-
SCRIPT_API(NPC_GetSurfingOffset, bool(INPC& npc, Vector3& offset))
958+
SCRIPT_API(NPC_GetSurfingOffsets, bool(INPC& npc, Vector3& offset))
944959
{
945960
auto data = npc.getSurfingData();
946961
offset = data.offset;
@@ -1023,3 +1038,53 @@ SCRIPT_API(NPC_ResetSurfingData, bool(INPC& npc))
10231038
npc.resetSurfingData();
10241039
return true;
10251040
}
1041+
1042+
SCRIPT_API(NPC_IsSpawned, bool(INPC& npc))
1043+
{
1044+
auto player = npc.getPlayer();
1045+
if (player)
1046+
{
1047+
auto state = player->getState();
1048+
if (state == PlayerState_OnFoot || state == PlayerState_Driver || state == PlayerState_Passenger || state == PlayerState_Spawned)
1049+
{
1050+
return true;
1051+
}
1052+
}
1053+
return false;
1054+
}
1055+
1056+
SCRIPT_API(NPC_Kill, bool(INPC& npc, IPlayer* killer, int reason))
1057+
{
1058+
npc.kill(killer, reason);
1059+
return true;
1060+
}
1061+
1062+
SCRIPT_API(NPC_SetVelocity, bool(INPC& npc, Vector3 velocity))
1063+
{
1064+
npc.setVelocity(velocity, true);
1065+
return true;
1066+
}
1067+
1068+
SCRIPT_API(NPC_GetVelocity, bool(INPC& npc, Vector3& velocity))
1069+
{
1070+
velocity = npc.getVelocity();
1071+
return true;
1072+
}
1073+
1074+
SCRIPT_API(NPC_GetPlayerAimingAt, int(INPC& npc))
1075+
{
1076+
auto player = npc.getPlayerAimingAt();
1077+
return player ? player->getID() : INVALID_PLAYER_ID;
1078+
}
1079+
1080+
SCRIPT_API(NPC_GetPlayerMovingTo, int(INPC& npc))
1081+
{
1082+
auto player = npc.getPlayerMovingTo();
1083+
return player ? player->getID() : INVALID_PLAYER_ID;
1084+
}
1085+
1086+
SCRIPT_API(NPC_SetWeaponState, bool(INPC& npc, int weaponState))
1087+
{
1088+
npc.setWeaponState(PlayerWeaponState(weaponState));
1089+
return true;
1090+
}

0 commit comments

Comments
 (0)