Skip to content

Commit

Permalink
Display ? and ! above NPCs
Browse files Browse the repository at this point in the history
? means a player that the NPC is aggressive towards is close to them, but the NPC won't attack unless the distance is reduced

! means the NPC has entered combat
  • Loading branch information
madsboddum committed Jun 28, 2022
1 parent 99b21a2 commit 870df0c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
@@ -1,9 +1,11 @@
package com.projectswg.holocore.resources.support.npc.ai

import com.projectswg.common.data.RGB
import com.projectswg.common.data.encodables.oob.StringId
import com.projectswg.common.data.encodables.tangible.Posture
import com.projectswg.common.data.location.Location
import com.projectswg.common.data.location.Point3D
import com.projectswg.common.data.objects.GameObjectType
import com.projectswg.common.network.packets.swg.zone.object_controller.ShowFlyText
import com.projectswg.holocore.intents.support.global.command.QueueCommandIntent
import com.projectswg.holocore.intents.support.npc.ai.ScheduleNpcModeIntent
import com.projectswg.holocore.intents.support.npc.ai.StartNpcCombatIntent
Expand Down Expand Up @@ -54,10 +56,15 @@ class NpcCombatMode(obj: AIObject) : NpcMode(obj) {
}

override fun onModeStart() {
showExclamationMarkAboveNpc()
StopNpcMovementIntent.broadcast(ai)
returnLocation.set(NavigationPoint.at(ai.parent, ai.location, npcRunSpeed))
}

private fun showExclamationMarkAboveNpc() {
ai.sendObservers(ShowFlyText(ai.objectId, StringId("npc_reaction/flytext", "threaten"), ShowFlyText.Scale.SMALL, RGB(204, 0, 0)))
}

override fun onModeEnd() {
val obj = ai
obj.lookAtTargetId = 0
Expand Down
Expand Up @@ -26,7 +26,11 @@
***********************************************************************************/
package com.projectswg.holocore.resources.support.objects.swg.custom;

import com.projectswg.common.data.RGB;
import com.projectswg.common.data.encodables.oob.StringId;
import com.projectswg.common.data.location.Location;
import com.projectswg.common.network.packets.swg.zone.baselines.Baseline.BaselineType;
import com.projectswg.common.network.packets.swg.zone.object_controller.ShowFlyText;
import com.projectswg.holocore.intents.support.npc.ai.ScheduleNpcModeIntent;
import com.projectswg.holocore.intents.support.npc.ai.StartNpcCombatIntent;
import com.projectswg.holocore.resources.support.npc.spawn.Spawner;
Expand All @@ -41,6 +45,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -62,6 +67,7 @@ public class AIObject extends CreatureObject {
private ScheduledThreadPool executor;
private ScheduledFuture<?> previousScheduled;
private String creatureId;
private Instant questionMarkBlockedUntil;

public AIObject(long objectId) {
super(objectId);
Expand All @@ -77,6 +83,7 @@ public AIObject(long objectId) {
this.activeMode = null;
this.creatureId = null;
incapSafetyTimer = new IncapSafetyTimer(45_000);
questionMarkBlockedUntil = Instant.now();
}

@Override
Expand Down Expand Up @@ -130,9 +137,42 @@ public void onObjectMoveInAware(SWGObject aware) {
return;
playersNearby.add(player);

boolean npcIsInCombat = isInCombat();

Instant now = Instant.now();

boolean questionMarkTimerExpired = now.isAfter(questionMarkBlockedUntil);

if (!npcIsInCombat) {
boolean npcIsAggressiveTowardsPlayer = isAttackable(player);

if (npcIsAggressiveTowardsPlayer) {
boolean playerIsInLineOfSight = isLineOfSight(player);

if (playerIsInLineOfSight) {
Location playerWorldLocation = player.getWorldLocation();
Location aiWorldLocation = this.getWorldLocation();
double questionMarkRange = 64;
double distanceBetweenNpcAndPlayer = aiWorldLocation.distanceTo(playerWorldLocation);
boolean playerIsInRange = distanceBetweenNpcAndPlayer <= questionMarkRange;

if (playerIsInRange) {
if (questionMarkTimerExpired) {
showQuestionMarkAboveNpc();
questionMarkBlockedUntil = Instant.now().plusSeconds(60);
}
}
}
}
}

checkAwareAttack(player);
}

private void showQuestionMarkAboveNpc() {
this.sendObservers(new ShowFlyText(this.getObjectId(), new StringId("npc_reaction/flytext", "alert"), ShowFlyText.Scale.SMALL, new RGB(204, 0, 0)));
}

private void checkAwareAttack(CreatureObject player) {
boolean incapSafetyTimerExpired = incapSafetyTimer.isExpired(System.currentTimeMillis(), player.getLastIncapTime());

Expand Down

0 comments on commit 870df0c

Please sign in to comment.