Files
Loke/assets/scripts/tonori/tulimshar/LightTriggerGlobal.gd
T
2026-06-03 17:04:06 +08:00

96 lines
3.4 KiB
GDScript

extends NpcScript
class_name TulimsharWestWallLightTrigerGlobal
#
const QUEST_ID : int = ProgressCommons.Quest.TULIMSHAR_OLD_FRIENDSHIP
const GUARD_SPEED_BOOST : int = 200
const APPROACH_DISTANCE : float = 48.0
#
static var activeCatches : Dictionary[int, NpcAgent] = {}
#
func OnAreaEnter(player : PlayerAgent):
CallGuard(player)
static func CallGuard(player : PlayerAgent):
if not ActorCommons.IsAlive(player):
return
var playerRID : int = player.get_rid().get_id()
if activeCatches.has(playerRID):
return
var questState : int = player.progress.GetQuest(QUEST_ID)
if questState >= ProgressCommons.TULIMSHAR_OLD_FRIENDSHIP.LETTERS_DELIVERED:
return
if player.SetState(ActorCommons.State.TRIGGER):
var inst : WorldInstance = WorldAgent.GetInstanceFromAgent(player)
if inst:
var guard : BaseAgent = SpawnGuard(inst)
if guard:
activeCatches[playerRID] = guard
NpcCommons.PushNotification(player, "被守卫发现了!")
Callback.AddCallback(player.tree_exiting, Cleanup, [player, guard, playerRID], ConnectFlags.CONNECT_ONE_SHOT)
Callback.OneShotCallback(guard.ready, OnGuardReady.bind(player, guard, playerRID))
static func SpawnGuard(inst : WorldInstance) -> BaseAgent:
var spawn : SpawnObject = SpawnObject.new()
spawn.map = inst.map
spawn.type = "Npc"
spawn.nick = "图利姆沙 Guard" if randi() % 2 == 0 else "图利姆沙 Sbire"
spawn.id = spawn.nick.hash()
spawn.spawn_position = Vector2i(2688, 1472) # tile (84, 46)
spawn.spawn_offset = Vector2i.DOWN
spawn.player_script = "tonori/tulimshar/PatrolGuardCaught.gd"
return WorldAgent.CreateAgent(spawn, inst.id)
static func OnGuardReady(player : PlayerAgent, guard : NpcAgent, playerRID : int):
if not guard or not ActorCommons.IsAlive(player):
Cleanup(player, guard, playerRID)
return
var guardRID : int = guard.get_rid().get_id()
Launcher.World.BulkPreload(guard, guardRID, player.peerID)
player.CheckVisibility(guard)
# Wait one full update cycle for the SetData to be called
StartGuardNavigation.call_deferred(player, guard, playerRID)
static func StartGuardNavigation(player : PlayerAgent, guard : NpcAgent, playerRID : int):
if not guard or not ActorCommons.IsAlive(player):
Cleanup(player, guard, playerRID)
return
NpcCommons.AddModifier(guard, CellCommons.Modifier.WalkSpeed, GUARD_SPEED_BOOST)
AI.Stop(guard)
# Check if in correct distance to start the guard interaction
if (guard.position - player.position).length() < APPROACH_DISTANCE / 2.0:
OnGuardArrived(player, guard, playerRID)
# Stop right before the player position but still within the trigger position
else:
var stopPos : Vector2 = player.position + (guard.position - player.position).normalized() * APPROACH_DISTANCE / 2.0
guard.WalkToward(stopPos)
Callback.OneShotCallback(guard.agent.navigation_finished, OnGuardArrived.bind(player, guard, playerRID))
static func OnGuardArrived(player : PlayerAgent, guard : NpcAgent, playerRID : int):
if not guard or not ActorCommons.IsAlive(player):
Cleanup(player, guard, playerRID)
return
guard.Interact(player)
static func Cleanup(player : PlayerAgent, guard : NpcAgent, playerRID : int):
activeCatches.erase(playerRID)
if player and is_instance_valid(player):
if player.ownScript:
NpcCommons.ToggleContext(player, false)
player.ClearScript()
if player.state == ActorCommons.State.TRIGGER:
player.SetState(ActorCommons.State.TRIGGER)
if guard and is_instance_valid(guard):
WorldAgent.RemoveAgent.call_deferred(guard)