Skip to content
Draft
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
1 change: 1 addition & 0 deletions game/game/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ enum Action:uint32_t {
AI_LookAt,
AI_WhirlToNpc,
AI_TurnAway,
AI_QuickLook,
};


Expand Down
8 changes: 8 additions & 0 deletions game/game/gamescript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ void GameScript::initCommon() {
bindExternal("ai_standupquick", &GameScript::ai_standupquick);
bindExternal("ai_continueroutine", &GameScript::ai_continueroutine);
bindExternal("ai_stoplookat", &GameScript::ai_stoplookat);
bindExternal("ai_quicklook", &GameScript::ai_quicklook);
bindExternal("ai_lookat", &GameScript::ai_lookat);
bindExternal("ai_lookatnpc", &GameScript::ai_lookatnpc);
bindExternal("ai_removeweapon", &GameScript::ai_removeweapon);
Expand Down Expand Up @@ -2896,6 +2897,13 @@ void GameScript::ai_stoplookat(std::shared_ptr<zenkit::INpc> selfRef) {
self->aiPush(AiQueue::aiStopLookAt());
}

void GameScript::ai_quicklook(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef) {
auto npc = findNpc(npcRef);
auto self = findNpc(selfRef);
if(self!=nullptr)
self->aiPush(AiQueue::aiQuickLook(npc));
}

void GameScript::ai_lookat(std::shared_ptr<zenkit::INpc> selfRef, std::string_view waypoint) {
auto self = findNpc(selfRef);
auto to = world().findPoint(waypoint);
Expand Down
1 change: 1 addition & 0 deletions game/game/gamescript.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ class GameScript final {
void ai_standupquick (std::shared_ptr<zenkit::INpc> selfRef);
void ai_continueroutine (std::shared_ptr<zenkit::INpc> selfRef);
void ai_stoplookat (std::shared_ptr<zenkit::INpc> selfRef);
void ai_quicklook (std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef);
void ai_lookat (std::shared_ptr<zenkit::INpc> selfRef, std::string_view waypoint);
void ai_lookatnpc (std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef);
void ai_removeweapon (std::shared_ptr<zenkit::INpc> npcRef);
Expand Down
7 changes: 7 additions & 0 deletions game/world/aiqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ AiQueue::AiAction AiQueue::aiLookAt(const WayPoint* to) {
return a;
}

AiQueue::AiAction AiQueue::aiQuickLook(Npc* other) {
AiAction a;
a.act = AI_QuickLook;
a.target = other;
return a;
}

AiQueue::AiAction AiQueue::aiLookAtNpc(Npc* other) {
AiAction a;
a.act = AI_LookAtNpc;
Expand Down
1 change: 1 addition & 0 deletions game/world/aiqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class AiQueue {
void onWldItemRemoved(const Item& itm);

static AiAction aiLookAt(const WayPoint* to);
static AiAction aiQuickLook(Npc* other);
static AiAction aiLookAtNpc(Npc* other);
static AiAction aiStopLookAt();
static AiAction aiRemoveWeapon();
Expand Down
47 changes: 41 additions & 6 deletions game/world/objects/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,17 +1274,19 @@ bool Npc::implPointAt(const Tempest::Vec3& to) {
}

bool Npc::implLookAtWp(uint64_t dt) {
if(currentLookAt==nullptr)
// nothing to look at, or a quicklook is handled in implLookAtNpc
if(currentLookAt==nullptr || quickLookNpc!=nullptr)
return false;
auto dvec = currentLookAt->position();
return implLookAt(dvec.x,dvec.y,dvec.z,dt);
}

bool Npc::implLookAtNpc(uint64_t dt) {
if(currentLookAtNpc==nullptr)
if(currentLookAtNpc==nullptr && quickLookNpc == nullptr)
return false;
auto selfHead = visual.mapHeadBone();
auto otherHead = currentLookAtNpc->visual.mapHeadBone();
auto other = (quickLookNpc!=nullptr) ? quickLookNpc : currentLookAtNpc;
auto otherHead = other->visual.mapHeadBone();
auto dvec = otherHead - selfHead;
return implLookAt(dvec.x,dvec.y,dvec.z,dt);
}
Expand Down Expand Up @@ -2132,6 +2134,16 @@ void Npc::tick(uint64_t dt) {
if(dbg && !isPlayer() && hnpc->id!=kId)
return;

// Unset QuickLook after the timeout
if(quickLookEnd > 0 && owner.tickCount() > quickLookEnd) {
quickLookEnd = 0;
quickLookNpc = nullptr;

// if nothing else to look at, re-set head rotation
if(currentLookAt==nullptr && currentLookAtNpc==nullptr)
visual.setHeadRotation(0,0);
}

tickAnimationTags();

if(!visual.pose().hasAnim())
Expand Down Expand Up @@ -2214,11 +2226,19 @@ void Npc::nextAiAction(AiQueue& queue, uint64_t dt) {
case AI_LookAtNpc:{
currentLookAt=nullptr;
currentLookAtNpc=act.target;
quickLookEnd=0;
quickLookNpc=nullptr;
break;
}
case AI_QuickLook:{
// Nothing to do, as the QuickLook just works in parallel
break;
}
case AI_LookAt:{
currentLookAtNpc=nullptr;
currentLookAt=act.point;
quickLookEnd=0;
quickLookNpc=nullptr;
break;
}
case AI_TurnAway: {
Expand Down Expand Up @@ -2304,6 +2324,8 @@ void Npc::nextAiAction(AiQueue& queue, uint64_t dt) {
case AI_StopLookAt:
currentLookAtNpc=nullptr;
currentLookAt=nullptr;
quickLookEnd=0;
quickLookNpc=nullptr;
visual.setHeadRotation(0,0);
break;
case AI_RemoveWeapon:
Expand Down Expand Up @@ -3091,9 +3113,19 @@ void Npc::setToFistMode() {
}

void Npc::aiPush(AiQueue::AiAction&& a) {
if(a.act==AI_OutputSvmOverlay)
aiQueueOverlay.pushBack(std::move(a)); else
aiQueue.pushBack(std::move(a));
switch(a.act) {
case AI_OutputSvmOverlay:
aiQueueOverlay.pushBack(std::move(a));
break;
case AI_QuickLook:
// QuickLook is supposed to last for 2 seconds
// and should not interrupt other AI actions like walking
quickLookEnd = owner.tickCount()+2000;
quickLookNpc = a.target;
default:
aiQueue.pushBack(std::move(a));
break;
}
}

void Npc::resumeAiRoutine() {
Expand Down Expand Up @@ -4221,6 +4253,9 @@ bool Npc::isAiBusy() const {
void Npc::clearAiQueue() {
currentLookAt = nullptr;
currentLookAtNpc = nullptr;
quickLookEnd = 0;
quickLookNpc = nullptr;

visual.setHeadRotation(0,0);

aiQueue.clear();
Expand Down
3 changes: 3 additions & 0 deletions game/world/objects/npc.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ class Npc final {
Npc* currentOther =nullptr;
Npc* currentVictim =nullptr;

Npc* quickLookNpc=nullptr;
uint64_t quickLookEnd=0;

const WayPoint* currentLookAt=nullptr;
Npc* currentLookAtNpc=nullptr;
Npc* currentTarget =nullptr;
Expand Down