最终整理版

This commit is contained in:
2026-06-03 17:04:06 +08:00
commit 959055ce90
1240 changed files with 80570 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
extends NpcScript
# Quest ID
const questID : int = ProgressCommons.Quest.SANDSTORM_MINE_ABANDONED_TREASURE
# Required items
var chestMineKeyID : int = DB.GetCellHash("Chest Mine Key")
# Reward items
var shortSwordID : int = DB.GetCellHash("Short Sword")
#
func OnStart():
match GetQuest(questID):
ProgressCommons.SANDSTORM_MINE_ABANDONED_TREASURE.KEY_FOUND: OnTryOpen()
ProgressCommons.SANDSTORM_MINE_ABANDONED_TREASURE.REWARDS_WITHDREW: OnEmpty()
_: OnLocked()
func OnTryOpen():
if not HasItem(chestMineKeyID):
OnLocked()
return
if not IsTriggering():
Trigger()
if HasSpace(1):
Mes("钥匙插进锁孔后,锈住的机关咔哒一声松开。箱子里还躺着一把矿工留下的短剑。")
RemoveItem(chestMineKeyID, 1)
SetQuest(questID, ProgressCommons.SANDSTORM_MINE_ABANDONED_TREASURE.REWARDS_WITHDREW)
AddItem(shortSwordID, 1)
else:
Mes("你找到了能打开箱子的钥匙,但背包已经装不下新的武器。")
func OnEmpty():
Chat("箱子已经空了,只剩下矿砂和木屑。")
func OnLocked():
Chat("矿工留下的旧箱子锁着,需要对应的矿洞钥匙。")
+13
View File
@@ -0,0 +1,13 @@
extends NpcScript
#
func OnStart():
Mes("你就是艾基努派来的侦察员?看起来还站得稳,这已经比我预想的好。")
Mes("别误会,艾基努不是想害你。他只是知道矿洞里需要一个会随机应变的人。")
Mes("从这里往东南走,旧井旁边就是沙漠风暴矿洞入口。")
Mes("如果你一路走到谷地外面,说明方向错了;真正的入口不会离风声太远。")
Mes("看守内森应该在入口站岗。他话多,但眼睛不瞎,能帮你确认矿洞情况。")
Mes("我们的几个人已经先进去了。你进去后先确认路线,再判断哪些宠物和怪物能避开,哪些必须处理。")
Mes("祝你好运。还有,别为了证明胆量去碰看起来会发光的东西。")
@@ -0,0 +1,9 @@
extends NpcScript
#
const mapPos : Vector2i = Vector2i(1760, 2560)
var mapName : int = "Desert Deep Level".hash()
#
func OnAreaEnter(player : PlayerAgent):
NpcCommons.WarpInstance(player, mapName, mapPos)
+20
View File
@@ -0,0 +1,20 @@
extends NpcScript
#
func OnStart():
Mes("从那条西侧山口继续走,就会离开 图利姆沙谷地,进入 祖尼石台地。")
Mes("那里路标少、岩影多,第一次去的人常常把回头路也弄丢。你确定方向吗?")
Choice("我在找 沙漠风暴矿洞。", OnMines)
Choice("我想回 图利姆沙。", OnTulimshar)
func OnMines():
LookAtNpc("To Mines")
Mes("沿这条路走,只会离 沙漠风暴矿洞 越来越远。")
ResetCamera()
Mes("先往回走,再朝谷地南侧找矿道。看到旧木梁和矿车轨迹,就说明方向对了。")
func OnTulimshar():
LookAtNpc("To Tulimshar")
Mes("沿那条路往北,能回到 图利姆沙 的城墙下。")
ResetCamera()
Mes("只要沙尘没有太厚,城墙从这里几乎就能看见。看到旗帜,就继续朝旗帜走。")
@@ -0,0 +1,33 @@
extends NpcScript
#
const QUEST_ID : int = ProgressCommons.Quest.DESERT_DEEP_XAKELBAEL
#
func OnAreaEnter(player : PlayerAgent):
var inst : WorldInstance = WorldAgent.GetInstanceFromAgent(npc)
if not inst or inst.id != player.get_rid().get_id():
return
var questState : int = player.progress.GetQuest(QUEST_ID)
if questState != ProgressCommons.DESERT_DEEP_XAKELBAEL.DEFEATED:
SpawnXakelbael(inst)
npc.RemoveTrigger()
func SpawnXakelbael(inst : WorldInstance):
var spawn : SpawnObject = SpawnObject.new()
spawn.map = inst.map
spawn.type = "Npc"
spawn.nick = "Xakelbael"
spawn.id = spawn.nick.hash()
spawn.spawn_position = Vector2i(1331, 1478)
spawn.spawn_offset = Vector2i(5, 5)
spawn.direction = ActorCommons.Direction.UP
spawn.state = ActorCommons.State.IDLE
spawn.trigger_radius = 120.0
spawn.own_script = "tonori/sandstorm/XakelbaelGlobal.gd"
spawn.player_script = "tonori/sandstorm/Xakelbael.gd"
spawn.is_persistant = false
spawn.respawn_delay = 0.0
WorldAgent.CreateAgent(spawn, inst.id)
@@ -0,0 +1,16 @@
extends NpcScript
# Quest ID
const questID : int = ProgressCommons.Quest.SANDSTORM_MINE_ABANDONED_TREASURE
# Reward items
var chestMineKeyID : int = DB.GetCellHash("Chest Mine Key")
#
func OnStart():
match GetQuest(questID):
ProgressCommons.SANDSTORM_MINE_ABANDONED_TREASURE.INACTIVE:
if HasSpace(1):
Mes("碎石下面露出一把生锈钥匙,柄上还刻着旧矿工的编号。")
SetQuest(questID, ProgressCommons.SANDSTORM_MINE_ABANDONED_TREASURE.KEY_FOUND)
AddItem(chestMineKeyID, 1)
+95
View File
@@ -0,0 +1,95 @@
extends NpcScript
const QUEST_ID = ProgressCommons.Quest.SANDSTORM_NATHAN_WATER
#
func OnStart():
Mes("你好,我是看守内森。平时我在港口站岗,今天被派来守这个快把人烤熟的矿洞入口。")
Mes("如果我说话有点乱,那是太阳先动的手。")
var questState : ProgressCommons.SANDSTORM_NATHAN_WATER = GetQuest(QUEST_ID) as ProgressCommons.SANDSTORM_NATHAN_WATER
Choice("这里就是沙漠风暴矿洞入口?", OnEntrance)
match questState:
ProgressCommons.SANDSTORM_NATHAN_WATER.STARTED:
Choice("关于那瓶水。", OnWaitingWater)
ProgressCommons.SANDSTORM_NATHAN_WATER.REWARDS_WITHDREW:
Choice("现在感觉好点了吗?", OnComplete)
Choice("我先去别处看看。", Farewell)
func Farewell():
Chat("小心脚下,沙子会把旧轨道盖得像没存在过一样。")
# Default dialogue flow
func OnEntrance():
Mes("没错。旧矿道就在这口井旁边,风从里面吹出来时会带着铁锈味。")
Mes("以前矿工每天从这里进出。后来沙暴越来越重,沙蝎和别的东西也把下层当成了巢。")
Mes("艾基努的人已经进去了,他们要确认矿道能不能重新开放。说实话,我更希望答案是不能。")
Choice("我就是来加入侦察的。", OnJoinThem)
func OnJoinThem():
Mes("真的?你看起来不像矿工。没有镐,也没有一脸认命的表情。")
Choice("我不是来采矿的,只负责侦察。", OnJustScouting)
func OnJustScouting():
Mes("明白了。那就进去吧,里面的人应该正等你。")
Mes("先别急着深入。入口层确认安全后,再考虑往废弃矿层和更深处走。")
Mes("如果你听见像石头在呼吸的声音,别逞强,先退回来。")
Choice("谢谢,内森。", OnNiceDay)
if GetQuest(QUEST_ID) == ProgressCommons.SANDSTORM_NATHAN_WATER.INACTIVE:
Choice("有什么能帮你的吗?", OnJobEasier)
func OnNiceDay():
Chat("等我能回港口看海,那才叫好日子。")
# Water quest
func OnJobEasier():
Mes("既然你问了,我确实想要一瓶水。")
Mes("不是喝的,我还有一点能喝的。")
Mes("我只是想把水倒在脸上,让自己别像挂在太阳底下的肉干。")
Mes("这请求听起来很蠢,但在这里站半天后,你会理解的。")
Choice("我理解,我会帮你找一瓶。", AcceptQuest)
Choice("抱歉,我现在有更紧急的事。", RefuseQuest)
func RefuseQuest():
Mes("没事,我懂。忘了我提过这事吧。")
Mes("大概就是因为我太会抱怨,才被派到这里来。")
Action(Farewell)
func AcceptQuest():
Mes("我就知道你会懂。水是生命,浇脸上的水也是。")
Narrate("内森低头看了看脚边被风埋住一半的靴子。")
Mes("我会在这里等你。反正我想走也走不了。")
SetQuest(QUEST_ID, ProgressCommons.SANDSTORM_NATHAN_WATER.STARTED)
if HasItem(DB.GetCellHash("Water Bottle")):
Choice("我身上正好有一瓶。", OnDeliverWater)
Choice("我去找找。", Farewell)
func OnWaitingWater():
Mes("是你啊。抱歉,风沙一大,我看谁都像会走路的土堆。")
Mes("找到水瓶了吗?")
if HasItem(DB.GetCellHash("Water Bottle")):
Choice("找到了。", OnDeliverWater)
Choice("还没有,我继续找。", Farewell)
func OnDeliverWater():
var waterBottleHash : int = DB.GetCellHash("Water Bottle")
if HasItem(waterBottleHash):
RemoveItem(waterBottleHash)
SetQuest(QUEST_ID, ProgressCommons.SANDSTORM_NATHAN_WATER.REWARDS_WITHDREW)
Mes("谢谢你,朋友。终于能喘口气了。")
Narrate("内森把你带来的水迅速倒在脸上和脖子上。")
Narrate("水顺着盔甲缝隙流进沙地,很快就被热风带走。")
AddExp(50)
AddGP(100)
Action(OnComplete)
else:
Action(Farewell)
func OnComplete():
Mes("这正是我需要的。你不知道这有多救命。")
Mes("现在我只需要再来一瓶。")
Chat("开玩笑的。大部分是。")
+32
View File
@@ -0,0 +1,32 @@
extends NpcScript
#
func OnStart():
Mes("等等,旅人。风向几分钟就变一次,别急着把自己交给沙子。")
Mes("如果你要去矿洞,让旧井一直在左手边。还有,别追沙尘里那些会动的影子。")
OnMainChoice()
func OnMainChoice():
Choice("矿洞附近发生了什么?", OnMines)
Choice("你见过异常的宠物吗?", OnPets)
Choice("出发前有什么建议?", OnAdvice)
Choice("我该继续赶路了。", Farewell)
func OnMines():
Mes("女王 想重新开放矿洞,可沙漠已经有好几年时间把那里变成自己的巢。")
Mes("沙蝎藏在暖石缝里,蛇会贴着薄沙游动,更深处还有一些不像普通动物的东西。")
Mes("艾基努的侦察队先进去,是因为总得有人在矿工送命前搞清楚里面到底有多糟。")
OnMainChoice()
func OnPets():
Mes("见过不少。风平时啾啾鸟会沿路盘旋,沙虫聚在仙人掌根旁,入夜后矿洞入口基本归沙蝎。")
Mes("想捕捉的话,先削弱它,再准备备用捕捉护符。沙漠不会等你慢慢翻包。")
OnMainChoice()
func OnAdvice():
Mes("水、护目镜、一只你信得过的宠物。顺序别弄错。")
Mes("如果风变红,找岩石躲。如果沙声突然安静,说明附近有东西在听。")
OnMainChoice()
func Farewell():
Chat("狂风压下来时,把身子放低。")
+48
View File
@@ -0,0 +1,48 @@
extends NpcScript
#
func OnStart():
Mes("沿这条路往东走,就会离开 图利姆沙谷地,进入 玛纳伊尔海岸 的方向。")
Mes("你是在找路,还是在确认自己没有被风带偏?")
DisplayChoices()
func DisplayChoices(hideChoice : int = -1):
if hideChoice != 1:
Choice("我在找 沙漠风暴矿洞。", OnMines)
if hideChoice != 2:
Choice("这片谷地有什么要注意?", OnValley)
if hideChoice != 3:
Choice("玛纳伊尔海岸是什么地方?", OnManayir)
if hideChoice != 4:
Choice("谢谢,我知道了。", Farewell)
func OnMines():
LookAtNpc("To Mines")
Mes("从这里直接往南,就能到 沙漠风暴矿洞。")
ResetCamera()
Mes("矿洞荒废很久了,不过我刚才看见一队 图利姆沙 人往那边去。")
Mes("他们不像普通商队,更像是带着目的来的。你如果也要下矿,最好先确认补给和宠物状态。")
DisplayChoices()
func OnValley():
Mes("图利姆沙谷地 是 托诺里 沙漠里少见的低谷,城就靠这里躲开最狠的热风。")
Mes("城墙把谷地、港口和居民区圈在一起,也把大部分野兽和沙暴挡在外面。")
Mes("但相对安全不等于安全。南边旧住区有失控的 卡奥雷,西边石台地更容易迷路。")
DisplayChoices()
func OnManayir():
Mes("那里靠海,是 托诺里 少数气候温和的地方。风里有盐味,沙子也不像谷地里这么烫。")
Mes("海滩外伸出一片半岛,我们称它为 纳瓦。")
Mes("玛纳伊尔教团 就在那里研究 玛纳、星象和一些普通人听完会头痛的东西。")
Choice("玛纳伊尔教团是什么?", OnManayirOrder)
DisplayChoices(3)
func OnManayirOrder():
Mes("那是一支古老的法师组织,研究 玛纳 的方式比商人算账还认真。")
Mes("旧故事里说,他们曾在远古时代治理过 图利姆沙。现在他们更愿意待在塔里,偶尔才和城里交易。")
Mes("我的族人尊 玛纳 为 圣灵。我们和 玛纳伊尔 交换知识,也互相保持距离。智慧有时比刀更锋利。")
DisplayChoices()
func Farewell():
Chat("顺着路标走,别让风替你决定方向。")
@@ -0,0 +1,21 @@
extends NpcScript
#
func OnStart():
var questState : int = GetQuest(ProgressCommons.Quest.DESERT_DEEP_XAKELBAEL)
if questState == ProgressCommons.DESERT_DEEP_XAKELBAEL.DEFEATED:
Mes("你比我记住的更强。")
Mes("但深层矿道不会因为一次胜利就恢复安静。")
Mes("我们还会再见。卡奥雷 从不只留下一个影子。")
else:
Mes("谁踏进了这截被遗忘的根脉?")
Mes("矿工带走铁,王冠带走命令,而你带着宠物和一身不知天高地厚的勇气。")
Mes("这里的 玛纳树 早已听不见祈祷,只剩 卡奥雷 在石头里回响。")
Mes("如果你要替图利姆沙打开这条路,就先证明你能活着穿过我的影子。")
Action(npc.ownScript.StartFight)
func OnQuit():
super.OnQuit()
var questState : int = GetQuest(ProgressCommons.Quest.DESERT_DEEP_XAKELBAEL)
if questState == ProgressCommons.DESERT_DEEP_XAKELBAEL.DEFEATED:
npc.ownScript.RunAway.call_deferred()
@@ -0,0 +1,84 @@
extends NpcScript
#
const QUEST_ID : int = ProgressCommons.Quest.DESERT_DEEP_XAKELBAEL
const exitDelay : float = 8.0
const exitPosition : Vector2 = Vector2(1760, 2533)
#
var player : PlayerAgent = null
var playerModifier : StatModifier = null
#
func OnStart():
Callback.PlugCallback(npc.ready, DisableAIBehaviour)
func DisableAIBehaviour():
npc.aiBehaviour = AICommons.Behaviour.NONE
AI.Stop(npc)
func OnAreaEnter(_player : PlayerAgent):
if IsVisible() and _player and not _player.ownScript:
var questState : int = _player.progress.GetQuest(QUEST_ID)
if questState != ProgressCommons.DESERT_DEEP_XAKELBAEL.DEFEATED:
player = _player
Callback.OneShotCallback(player.tree_exiting, OnPlayerLeft)
npc.Interact(player)
func OnPlayerLeft():
RemovePlayerModifier()
if player:
NpcCommons.SetQuest(player, QUEST_ID, ProgressCommons.DESERT_DEEP_XAKELBAEL.INACTIVE)
player = null
# Player modifier
func AddPlayerModifier():
if not playerModifier and player:
playerModifier = AddModifier(CellCommons.Modifier.DodgeRate, 10000, player)
func RemovePlayerModifier():
if playerModifier and player:
RemoveModifier(playerModifier, player)
playerModifier = null
# Actions
func StartFight():
NpcCommons.SetQuest(player, QUEST_ID, ProgressCommons.DESERT_DEEP_XAKELBAEL.FIGHTING)
SetVisible(false)
AddPlayerModifier()
var mobs : Array[MonsterAgent] = Spawn(npc.data._id, 1, npc.position, Vector2i.DOWN)
if not mobs.is_empty():
var monsterAgent : MonsterAgent = mobs[0]
monsterAgent.agent_killed.connect(OnMonsterKilled)
AI.Refresh(monsterAgent)
func OnMonsterKilled(mob : BaseAgent):
RemovePlayerModifier()
npc.position = mob.position
RemoveAgent(mob)
SetState(ActorCommons.State.DEATH)
SetVisible(true)
NpcCommons.SetQuest(player, QUEST_ID, ProgressCommons.DESERT_DEEP_XAKELBAEL.DEFEATED)
if player and ActorCommons.IsAlive(player) and not player.ownScript:
player.AddScript(npc)
if player.ownScript:
player.ownScript.ApplyStep()
func RunAway():
if player:
Callback.ClearOneShot(player.tree_exiting)
player = null
SetState(ActorCommons.State.IDLE)
AddModifier(CellCommons.Modifier.WalkSpeed, 200)
AI.Reset(npc)
npc.WalkToward(exitPosition)
AddTimer(npc, exitDelay, WorldAgent.RemoveAgent.bind(npc))