]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Allow showing translated campaign level descriptions in game and add Chinese translat...
authorterencehill <piuntn@gmail.com>
Thu, 15 Jun 2023 16:59:55 +0000 (16:59 +0000)
committerterencehill <piuntn@gmail.com>
Thu, 15 Jun 2023 16:59:55 +0000 (16:59 +0000)
maps/campaignxonoticbeta.txt.zh_CN [new file with mode: 0644]
maps/campaignxonoticbeta.txt.zh_HK [new file with mode: 0644]
maps/campaignxonoticbeta.txt.zh_TW [new file with mode: 0644]
qcsrc/client/main.qc
qcsrc/common/campaign_common.qh
qcsrc/common/campaign_file.qc
qcsrc/menu/xonotic/dialog_welcome.qc
qcsrc/server/campaign.qc
qcsrc/server/campaign.qh
qcsrc/server/client.qc

diff --git a/maps/campaignxonoticbeta.txt.zh_CN b/maps/campaignxonoticbeta.txt.zh_CN
new file mode 100644 (file)
index 0000000..91e89ef
--- /dev/null
@@ -0,0 +1,44 @@
+//campaign:Xonotic 战役
+//"game","mapname","bots","skill","fraglimit","timelimit","mutator-sets","description","long description"
+//fraglimit: Score limit + lead limit, use "default" to leave the implicit value in effect, leave unset for no limit. eg: 50, 30+5, +10, 0+default
+//timelimit: Match duration in minutes, use "default" to leave the implicit value in effect, leave unset for no limit.
+"dm","boil","5","2","10",,,"死亡竞赛:怒火中烧","欢迎来到 Xonotic!\n我们从简出发,在《怒火中烧》地图对付 5 只简单的机器人。\nXonotic 主要是多人游戏, 不过在开始在线游戏之前, 练习对付机器人更好。"
+"tdm","stormkeep","5","2",,"5",,"团队死亡竞赛:风暴要塞","下一步我们在《风暴要塞》练习 3 对 3 的团队死亡竞赛。\n你需要在这 5 分钟内做到最好, 因为得分最高的团队获胜!"
+"mayhem","warfare","5","2",,"5",,"大乱斗:针锋相对","持续五分钟的大乱斗!\n在这里,你全副武装,带着所有武器加入游戏。武器对自己没有伤害;造成最多伤害、杀敌最多的玩家获胜!"
+"ctf","dance","9","3","3",,,"夺旗战:起舞","在夺旗战中,你要拿到对方的旗帜、把它带到你的基地。同时也得保护你自己的旗帜、不让对方拿走,才能成功夺取!\n夺取 3 次即获胜。"
+"dm","finalrage","6","3","15",,,"死亡竞赛:最终狂怒","另一场死亡竞赛,不过机器人的水平比之前要好。"
+"dom","atelier","11","4","50",,,"统治:工作坊","占领并保卫控制点、驱离进犯者,得分以获胜。"
+"kh","runningmanctf","5","5","500",,,"钥匙猎取:向前冲","每个团队都有一把钥匙。你要把它们都拿到手(杀死钥匙携带者,捡起掉落的钥匙),之后与团队内其他携带者会面。"
+"ctf","geoplanetary","13","5","5",,,"夺旗战:行星地带","一场很“拥挤”的夺旗战。\n开始在线游戏前,值得一练。"
+"dm","darkzone","4","5","15",,"g_instagib 1","【特别】死亡竞赛:暗黑地带","InstaGib(瞬杀)! 每个人都有一把武器——汽化者。\n瞄准你的敌人,一击必杀。(除非他获得如“额外生命”等加成)"
+"ctf","vorix","11","6","5",,"g_grappling_hook 1","【特别】夺旗战:Vorix","钩爪:按 e 键或‘鼠标按键 5’来使用。 勾住一面墙,感受强大的拉力。"
+//"rc","leave_em_behind","0","0","2400",,,"竞速:统统甩开","这是竞速,跑得越快越好!靠近墙壁或地面时,使用镭射枪(第一把武器)击打之可获得加速度。按住空格以连续加速跳跃(“兔兔蹦”)。\n夺得 24 秒以下的记录以通过这关。"
+"dm","solarium","8","6","15",,"g_nix 1","【特别】死亡竞赛:日光浴场","NIX(无物品 Xonotic): 每个人都有相同的武器, 不过每隔一段时间会随机更换。"
+"ft","erbium","5","6","5",,,"冰封战:废弃铒工厂","当你被杀死时,你被冻结。站在被冻结的队友身旁以复活他们。如果一个团队的玩家都被冻结,此轮结束。"
+"lms","opium","6","6","5",,,"笑到最后:麻木","在此游戏模式中,你有 5 条生命。 目标是顽强斗争、活到最后!"
+"tdm","afterslime","5","7","20",,"sv_gravity 200","【特别】团队死亡竞赛:史莱姆研究室","另一场团队死亡竞赛。\n不过,这里的重力低一些。"
+"ctf","go","5","7","5",,,"夺旗战:勇往直前","又一次在太空中的夺旗战,这次机器人的水平要稍微高一些。当心脚下,不要掉入虚空!"
+"tka","runningman","5","7","15",,,"团队驱离:向前冲","为团队争夺光球,拿起来,开始杀敌!\n提示:你可以向传送门内射弹,命中另一边的敌人。"
+//"nb","nexballarena","5","7","5",,,"Nex 球赛:Nex 球赛竞技场","这个有点像足球。把球踢进对方的球门里。率先得 5 分的团队获胜!"
+"kh","silentsiege","8","8","600",,,"钥匙猎取:静谧围城","再一场钥匙猎取!得 600 分获胜。"
+"ca","bromine","5","8","5",,,"组队竞技:废弃铒工厂","这是轮流制的团队竞争。武器对自己无伤害,但如果你死亡,你就需要等到下一轮才能再次加入游戏。竞争后仍有幸存玩家的队伍获胜!"
+"ctf","implosion","7","8","5",,"g_jetpack 1","【特别】夺旗战:聚爆实验场","喷气背包:在空中时跳跃(空格)以使用,享受飞行!"
+"as","techassault","7","8","30",,"g_campaign_forceteam 1","突击:科技突袭","你是进攻方,需要摧毁所有目标。摧毁一个目标后,会出现下一目标。"
+"tmayhem","trident","7","8",,"5",,"团队大乱斗:三叉戟","在这里,你全副武装,带着所有武器加入游戏。武器对己方团队没有伤害;造成最多伤害、杀敌最多的团队获胜!"
+//"cts","courtfun","0","0","6000",,,"CTS 竞速:殿堂欢乐","CTS 竞速 (Complete the Stage) 类似于普通竞速,不过只需要到达终点。你需要在 1 分钟内完成。"
+"ft","xoylent","5","8","5",,,"冰封战:Xoylent","当你被杀死时,你被冻结。站在被冻结的队友身旁以复活他们。如果一个团队的玩家都被冻结,此轮结束。"
+"ons","runningmanctf","7","8","1","10",,"猛攻:向前冲","猛攻:贴近已连接但还没有被占领的控制点以占领它;摧毁并占领所有敌方的控制点。最终摧毁敌方的发电核心以取胜!"
+"ctf","catharsis","9","9","5",,,"夺旗战:水晶地带","夺旗战,有到目前为止最难的机器人!5 次夺取以获胜。"
+"dm","stormkeep","5","9","15",,"g_new_toys 1; g_cloaked 1","【特别】死亡竞赛:风暴要塞","新玩意:这里会生成一些新武器,像地雷放置器,重型镭射突击大炮,和 T.A.G. 瞄准者。\n此外还有另一个修改:近乎隐形的玩家。"
+"ctf","space-elevator","7","10","3",,"g_instagib 1; g_grappling_hook 1","【特别】夺旗战:太空电梯","这次是瞬杀夺旗战。同时你会体验使用非手持抓钩!(按 e 键或‘鼠标按键 5’来使用)"
+"duel","fuse","1","10","10","5","g_forced_respawn 1","【特别】决斗:导火索","这次你只面对一个机器人——一场所谓的“决斗”。多人游戏非常流行决斗。"
+"ca","warfare","5","10","5",,"g_vampire 1; g_vampire_factor 0.75; g_balance_health_limit 400; g_ca_start_health 400; g_ca_start_armor 0","【特别】组队竞技:针锋相对","启用了吸血修改,造成伤害可以恢复血量!\n竞争后仍有幸存玩家的队伍获胜!"
+"dm","glowplant","5","11","20",,,"【最终】死亡竞赛:荧光反应堆","在这场最终竞赛,你要打败 5 只能力最强的机器人。你需要 20 次杀敌以完结这场战役!此后你就有能力和真人对抗!"
+"mayhem","stormkeep","9","11","300",,"g_weaponarena devastator; g_mayhem_selfdamage 1","【附加】大乱斗:风暴要塞","惊喜!\n欢迎来到火箭地狱!\n这里只有灭世火箭炮,可以对自己造成伤害——不要炸飞自己!玩得开心!"
+// Dr. Jaska: fix bot weapon priority and weapon balance before enabling full weapon arsenal for this one
+"mayhem","trident","6","1337",,"5","g_weaponarena \"blaster mortar crylink devastator \"","【终结】大乱斗:三叉戟","惊喜!\n欢迎来到这场灵魂出窍的大乱斗!\n没有多年的游戏经验和出色的战斗技巧,是无法在这一关取胜的。"
+
+// rc & cts disabled, since we hide these modes
+
+// note that currently any cvars changed in mutator-sets must be accessed in code using the cvar() function (or autocvar aliases to that), otherwise they will not work
+// see https://gitlab.com/xonotic/xonotic-data.pk3dir/issues/1976 for details
diff --git a/maps/campaignxonoticbeta.txt.zh_HK b/maps/campaignxonoticbeta.txt.zh_HK
new file mode 100644 (file)
index 0000000..04e203b
--- /dev/null
@@ -0,0 +1,44 @@
+//campaign:Xonotic 戰役
+//"game","mapname","bots","skill","fraglimit","timelimit","mutator-sets","description","long description"
+//fraglimit: Score limit + lead limit, use "default" to leave the implicit value in effect, leave unset for no limit. eg: 50, 30+5, +10, 0+default
+//timelimit: Match duration in minutes, use "default" to leave the implicit value in effect, leave unset for no limit.
+"dm","boil","5","2","10",,,"死亡競賽:怒火中燒","歡迎來到 Xonotic!\n我們從簡出發,在《怒火中燒》地圖對付 5 隻簡單的機器人。\nXonotic 主要是多人遊戲, 不過在開始在線遊戲之前, 練習對付機器人更好。"
+"tdm","stormkeep","5","2",,"5",,"團隊死亡競賽:風暴要塞","下一步我們在《風暴要塞》練習 3 對 3 的團隊死亡競賽。\n你需要在這 5 分鐘內做到最好, 因為得分最高的團隊獲勝!"
+"mayhem","warfare","5","2",,"5",,"大亂鬥:針鋒相對","持續五分鐘的大亂鬥!\n在這裏,你全副武裝,帶着所有武器加入遊戲。武器對自己沒有傷害;造成最多傷害、殺敵最多的玩家獲勝!"
+"ctf","dance","9","3","3",,,"奪旗戰:起舞","在奪旗戰中,你要拿到對方的旗幟、把它帶到你的基地。同時也得保護你自己的旗幟、不讓對方拿走,才能成功奪取!\n奪取 3 次即獲勝。"
+"dm","finalrage","6","3","15",,,"死亡競賽:最終狂怒","另一場死亡競賽,不過機器人的水平比之前要好。"
+"dom","atelier","11","4","50",,,"統治:工作坊","佔領並保衞控制點、驅離進犯者,得分以獲勝。"
+"kh","runningmanctf","5","5","500",,,"鑰匙獵取:向前衝","每個團隊都有一把鑰匙。你要把它們都拿到手(殺死鑰匙攜帶者,撿起掉落的鑰匙),之後與團隊內其他攜帶者會面。"
+"ctf","geoplanetary","13","5","5",,,"奪旗戰:行星地帶","一場很“擁擠”的奪旗戰。\n開始在線遊戲前,值得一練。"
+"dm","darkzone","4","5","15",,"g_instagib 1","【特別】死亡競賽:暗黑地帶","InstaGib(瞬殺)! 每個人都有一把武器——汽化者。\n瞄準你的敵人,一擊必殺。(除非他獲得如“額外生命”等加成)"
+"ctf","vorix","11","6","5",,"g_grappling_hook 1","【特別】奪旗戰:Vorix","鈎爪:按 e 鍵或‘鼠標按鍵 5’來使用。 勾住一面牆,感受強大的拉力。"
+//"rc","leave_em_behind","0","0","2400",,,"競速:統統甩開","這是競速,跑得越快越好!靠近牆壁或地面時,使用鐳射槍(第一把武器)擊打之可獲得加速度。按住空格以連續加速跳躍(“兔兔蹦”)。\n奪得 24 秒以下的記錄以通過這關。"
+"dm","solarium","8","6","15",,"g_nix 1","【特別】死亡競賽:日光浴場","NIX(無物品 Xonotic): 每個人都有相同的武器, 不過每隔一段時間會隨機更換。"
+"ft","erbium","5","6","5",,,"冰封戰:廢棄鉺工廠","當你被殺死時,你被凍結。站在被凍結的隊友身旁以復活他們。如果一個團隊的玩家都被凍結,此輪結束。"
+"lms","opium","6","6","5",,,"笑到最後:麻木","在此遊戲模式中,你有 5 條生命。 目標是頑強鬥爭、活到最後!"
+"tdm","afterslime","5","7","20",,"sv_gravity 200","【特別】團隊死亡競賽:史萊姆研究室","另一場團隊死亡競賽。\n不過,這裏的重力低一些。"
+"ctf","go","5","7","5",,,"奪旗戰:勇往直前","又一次在太空中的奪旗戰,這次機器人的水平要稍微高一些。當心腳下,不要掉入虛空!"
+"tka","runningman","5","7","15",,,"團隊驅離:向前衝","為團隊爭奪光球,拿起來,開始殺敵!\n提示:你可以向傳送門內射彈,命中另一邊的敵人。"
+//"nb","nexballarena","5","7","5",,,"Nex 球賽:Nex 球賽競技場","這個有點像足球。把球踢進對方的球門裏。率先得 5 分的團隊獲勝!"
+"kh","silentsiege","8","8","600",,,"鑰匙獵取:靜謐圍城","再一場鑰匙獵取!得 600 分獲勝。"
+"ca","bromine","5","8","5",,,"組隊競技:廢棄鉺工廠","這是輪流制的團隊競爭。武器對自己無傷害,但如果你死亡,你就需要等到下一輪才能再次加入遊戲。競爭後仍有倖存玩家的隊伍獲勝!"
+"ctf","implosion","7","8","5",,"g_jetpack 1","【特別】奪旗戰:聚爆實驗場","噴氣揹包:在空中時跳躍(空格)以使用,享受飛行!"
+"as","techassault","7","8","30",,"g_campaign_forceteam 1","突擊:科技突襲","你是進攻方,需要摧毀所有目標。摧毀一個目標後,會出現下一目標。"
+"tmayhem","trident","7","8",,"5",,"團隊大亂鬥:三叉戟","在這裏,你全副武裝,帶着所有武器加入遊戲。武器對己方團隊沒有傷害;造成最多傷害、殺敵最多的團隊獲勝!"
+//"cts","courtfun","0","0","6000",,,"CTS 競速:殿堂歡樂","CTS 競速 (Complete the Stage) 類似於普通競速,不過只需要到達終點。你需要在 1 分鐘內完成。"
+"ft","xoylent","5","8","5",,,"冰封戰:Xoylent","當你被殺死時,你被凍結。站在被凍結的隊友身旁以復活他們。如果一個團隊的玩家都被凍結,此輪結束。"
+"ons","runningmanctf","7","8","1","10",,"猛攻:向前衝","猛攻:貼近已連接但還沒有被佔領的控制點以佔領它;摧毀並佔領所有敵方的控制點。最終摧毀敵方的發電核心以取勝!"
+"ctf","catharsis","9","9","5",,,"奪旗戰:水晶地帶","奪旗戰,有到目前為止最難的機器人!5 次奪取以獲勝。"
+"dm","stormkeep","5","9","15",,"g_new_toys 1; g_cloaked 1","【特別】死亡競賽:風暴要塞","新玩意:這裏會生成一些新武器,像地雷放置器,重型鐳射突擊大炮,和 T.A.G. 瞄準者。\n此外還有另一個修改:近乎隱形的玩家。"
+"ctf","space-elevator","7","10","3",,"g_instagib 1; g_grappling_hook 1","【特別】奪旗戰:太空電梯","這次是瞬殺奪旗戰。同時你會體驗使用非手持抓鈎!(按 e 鍵或‘鼠標按鍵 5’來使用)"
+"duel","fuse","1","10","10","5","g_forced_respawn 1","【特別】決鬥:導火索","這次你只面對一個機器人——一場所謂的“決鬥”。多人遊戲非常流行決鬥。"
+"ca","warfare","5","10","5",,"g_vampire 1; g_vampire_factor 0.75; g_balance_health_limit 400; g_ca_start_health 400; g_ca_start_armor 0","【特別】組隊競技:針鋒相對","啓用了吸血修改,造成傷害可以恢復血量!\n競爭後仍有倖存玩家的隊伍獲勝!"
+"dm","glowplant","5","11","20",,,"【最終】死亡競賽:熒光反應堆","在這場最終競賽,你要打敗 5 隻能力最強的機器人。你需要 20 次殺敵以完結這場戰役!此後你就有能力和真人對抗!"
+"mayhem","stormkeep","9","11","300",,"g_weaponarena devastator; g_mayhem_selfdamage 1","【附加】大亂鬥:風暴要塞","驚喜!\n歡迎來到火箭地獄!\n這裏只有滅世火箭炮,可以對自己造成傷害——不要炸飛自己!玩得開心!"
+// Dr. Jaska: fix bot weapon priority and weapon balance before enabling full weapon arsenal for this one
+"mayhem","trident","6","1337",,"5","g_weaponarena \"blaster mortar crylink devastator \"","【終結】大亂鬥:三叉戟","驚喜!\n歡迎來到這場靈魂出竅的大亂鬥!\n沒有多年的遊戲經驗和出色的戰鬥技巧,是無法在這一關取勝的。"
+
+// rc & cts disabled, since we hide these modes
+
+// note that currently any cvars changed in mutator-sets must be accessed in code using the cvar() function (or autocvar aliases to that), otherwise they will not work
+// see https://gitlab.com/xonotic/xonotic-data.pk3dir/issues/1976 for details
diff --git a/maps/campaignxonoticbeta.txt.zh_TW b/maps/campaignxonoticbeta.txt.zh_TW
new file mode 100644 (file)
index 0000000..3e9c63f
--- /dev/null
@@ -0,0 +1,44 @@
+//campaign:Xonotic 戰役
+//"game","mapname","bots","skill","fraglimit","timelimit","mutator-sets","description","long description"
+//fraglimit: Score limit + lead limit, use "default" to leave the implicit value in effect, leave unset for no limit. eg: 50, 30+5, +10, 0+default
+//timelimit: Match duration in minutes, use "default" to leave the implicit value in effect, leave unset for no limit.
+"dm","boil","5","2","10",,,"死亡競賽:怒火中燒","歡迎來到 Xonotic!\n我們從簡出發,在《怒火中燒》地圖對付 5 隻簡單的機器人。\nXonotic 主要是多人遊戲, 不過在開始線上遊戲之前, 練習對付機器人更好。"
+"tdm","stormkeep","5","2",,"5",,"團隊死亡競賽:風暴要塞","下一步我們在《風暴要塞》練習 3 對 3 的團隊死亡競賽。\n你需要在這 5 分鐘內做到最好, 因為得分最高的團隊獲勝!"
+"mayhem","warfare","5","2",,"5",,"大亂鬥:針鋒相對","持續五分鐘的大亂鬥!\n在這裡,你全副武裝,帶著所有武器加入遊戲。武器對自己沒有傷害;造成最多傷害、殺敵最多的玩家獲勝!"
+"ctf","dance","9","3","3",,,"奪旗戰:起舞","在奪旗戰中,你要拿到對方的旗子、把它帶到你的基地。同時也得保護你自己的旗子、不讓對方拿走,才能成功奪取!\n奪取 3 次即獲勝。"
+"dm","finalrage","6","3","15",,,"死亡競賽:最終狂怒","另一場死亡競賽,不過機器人的水平比之前要好。"
+"dom","atelier","11","4","50",,,"統治:工作坊","佔領並保衛控制點、驅離進犯者,得分以獲勝。"
+"kh","runningmanctf","5","5","500",,,"鑰匙獵取:向前衝","每個團隊都有一把鑰匙。你要把它們都拿到手(殺死鑰匙攜帶者,撿起掉落的鑰匙),之後與團隊內其他攜帶者會面。"
+"ctf","geoplanetary","13","5","5",,,"奪旗戰:行星地帶","一場很「擁擠」的奪旗戰。\n開始線上遊戲前,值得一練。"
+"dm","darkzone","4","5","15",,"g_instagib 1","【特別】死亡競賽:暗黑地帶","InstaGib(瞬殺)! 每個人都有一把武器——汽化者。\n瞄準你的敵人,一擊必殺。(除非他獲得如「額外生命」等加成)"
+"ctf","vorix","11","6","5",,"g_grappling_hook 1","【特別】奪旗戰:Vorix","鉤爪:按 e 鍵或‘滑鼠按鍵 5’來使用。 勾住一面牆,感受強大的拉力。"
+//"rc","leave_em_behind","0","0","2400",,,"競速:統統甩開","這是競速,跑得越快越好!靠近牆壁或地面時,使用鐳射槍(第一把武器)擊打之可獲得加速度。按住空格以連續加速跳躍(「兔兔蹦」)。\n奪得 24 秒以下的記錄以透過這關。"
+"dm","solarium","8","6","15",,"g_nix 1","【特別】死亡競賽:日光浴場","NIX(無物品 Xonotic): 每個人都有相同的武器, 不過每隔一段時間會隨機更換。"
+"ft","erbium","5","6","5",,,"冰封戰:廢棄鉺工廠","當你被殺死時,你被凍結。站在被凍結的隊友身旁以復活他們。如果一個團隊的玩家都被凍結,此輪結束。"
+"lms","opium","6","6","5",,,"適者生存:麻木","在此遊戲類型中,你有 5 條生命。 目標是頑強鬥爭、活到最後!"
+"tdm","afterslime","5","7","20",,"sv_gravity 200","【特別】團隊死亡競賽:史萊姆研究室","另一場團隊死亡競賽。\n不過,這裡的重力低一些。"
+"ctf","go","5","7","5",,,"奪旗戰:勇往直前","又一次在太空中的奪旗戰,這次機器人的水平要稍微高一些。當心腳下,不要掉入虛空!"
+"tka","runningman","5","7","15",,,"團隊驅離:向前衝","為團隊爭奪光球,拿起來,開始殺敵!\n提示:你可以向傳送門內射彈,命中另一邊的敵人。"
+//"nb","nexballarena","5","7","5",,,"Nex 球賽:Nex 球賽競技場","這個有點像足球。把球踢進對方的球門裡。率先得 5 分的團隊獲勝!"
+"kh","silentsiege","8","8","600",,,"鑰匙獵取:靜謐圍城","再一場鑰匙獵取!得 600 分獲勝。"
+"ca","bromine","5","8","5",,,"組隊競技:廢棄鉺工廠","這是輪流制的團隊競爭。武器對自己無傷害,但如果你死亡,你就需要等到下一輪才能再次加入遊戲。競爭後仍有倖存玩家的隊伍獲勝!"
+"ctf","implosion","7","8","5",,"g_jetpack 1","【特別】奪旗戰:聚爆實驗場","噴氣揹包:在空中時跳躍(空格)以使用,享受飛行!"
+"as","techassault","7","8","30",,"g_campaign_forceteam 1","突擊:科技突襲","你是進攻方,需要摧毀所有目標。摧毀一個目標後,會出現下一目標。"
+"tmayhem","trident","7","8",,"5",,"團隊大亂鬥:三叉戟","在這裡,你全副武裝,帶著所有武器加入遊戲。武器對己方團隊沒有傷害;造成最多傷害、殺敵最多的團隊獲勝!"
+//"cts","courtfun","0","0","6000",,,"CTS 競速:殿堂歡樂","CTS 競速 (Complete the Stage) 類似於普通競速,不過只需要到達終點。你需要在 1 分鐘內完成。"
+"ft","xoylent","5","8","5",,,"冰封戰:Xoylent","當你被殺死時,你被凍結。站在被凍結的隊友身旁以復活他們。如果一個團隊的玩家都被凍結,此輪結束。"
+"ons","runningmanctf","7","8","1","10",,"猛攻:向前衝","猛攻:貼近已連線但還沒有被佔領的控制點以佔領它;摧毀並佔領所有敵方的控制點。最終摧毀敵方的發電核心以取勝!"
+"ctf","catharsis","9","9","5",,,"奪旗戰:水晶地帶","奪旗戰,有到目前為止最難的機器人!5 次奪取以獲勝。"
+"dm","stormkeep","5","9","15",,"g_new_toys 1; g_cloaked 1","【特別】死亡競賽:風暴要塞","新玩意:這裡會生成一些新武器,像地雷放置器,重型鐳射突擊大炮,和 T.A.G. 瞄準者。\n此外還有另一個修改:近乎隱形的玩家。"
+"ctf","space-elevator","7","10","3",,"g_instagib 1; g_grappling_hook 1","【特別】奪旗戰:太空電梯","這次是瞬殺奪旗戰。同時你會體驗使用非手持抓鉤!(按 e 鍵或‘滑鼠按鍵 5’來使用)"
+"duel","fuse","1","10","10","5","g_forced_respawn 1","【特別】決鬥:導火索","這次你只面對一個機器人——一場所謂的「決鬥」。多人遊戲非常流行決鬥。"
+"ca","warfare","5","10","5",,"g_vampire 1; g_vampire_factor 0.75; g_balance_health_limit 400; g_ca_start_health 400; g_ca_start_armor 0","【特別】組隊競技:針鋒相對","啟用了吸血修改,造成傷害可以恢復血量!\n競爭後仍有倖存玩家的隊伍獲勝!"
+"dm","glowplant","5","11","20",,,"【最終】死亡競賽:熒光反應堆","在這場最終競賽,你要打敗 5 隻能力最強的機器人。你需要 20 次殺敵以完結這場戰役!此後你就有能力和真人對抗!"
+"mayhem","stormkeep","9","11","300",,"g_weaponarena devastator; g_mayhem_selfdamage 1","【附加】大亂鬥:風暴要塞","驚喜!\n歡迎來到火箭地獄!\n這裡只有滅世火箭炮,可以對自己造成傷害——不要炸飛自己!玩得開心!"
+// Dr. Jaska: fix bot weapon priority and weapon balance before enabling full weapon arsenal for this one
+"mayhem","trident","6","1337",,"5","g_weaponarena \"blaster mortar crylink devastator \"","【終結】大亂鬥:三叉戟","驚喜!\n歡迎來到這場靈魂出竅的大亂鬥!\n沒有多年的遊戲經驗和出色的戰鬥技巧,是無法在這一關取勝的。"
+
+// rc & cts disabled, since we hide these modes
+
+// note that currently any cvars changed in mutator-sets must be accessed in code using the cvar() function (or autocvar aliases to that), otherwise they will not work
+// see https://gitlab.com/xonotic/xonotic-data.pk3dir/issues/1976 for details
index 327a9edf877667958d07ba8a278051c00583181d..58d497aab77b176a9ef60b951762e60d7eecac95 100644 (file)
@@ -1402,18 +1402,18 @@ bool net_handle_ServerWelcome()
        campaign = ReadByte();
        if (campaign)
        {
-               string campaign_title = ReadString();
                int campaign_level = ReadByte();
-               string campaign_msg = ReadString();
-               string welcomedialog_args;
-               welcomedialog_args = strcat("HOSTNAME \"", campaign_title, "\"");
+               // Menu can't build the whole campaign message because it lacks getcommandkey and CCR
+               // so we build part of the message here and let the menu insert the level description
+               // (that client doesn't know) by replacing the keyword _LEVEL_DESC
                string key = getcommandkey(_("jump"), "+jump");
                string msg = strcat(
                        CCR("^F1"), sprintf(_("Level %d:"), campaign_level),
-                       sprintf(CCR(" ^BG%s\n^3\n"), campaign_msg),
+                       sprintf(CCR(" ^BG%s\n\n"), "_LEVEL_DESC"),
                        sprintf(CCR(_("^BGPress ^F2%s^BG to enter the game")), key));
                msg = MakeConsoleSafe(strreplace("\n", "\\n", msg));
-               welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\"");
+               string welcomedialog_args = strcat("CAMPAIGN ", itos(campaign_level), " \"", msg, "\"");
+
                localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
                return true;
        }
index 088aefea09a0479c2061e483491923090653df60..8f70c51cfaf5e960b6c7c8982332926070f88242 100644 (file)
@@ -14,8 +14,10 @@ float campaign_botskill[CAMPAIGN_MAX_ENTRIES];
 string campaign_fraglimit[CAMPAIGN_MAX_ENTRIES];
 string campaign_timelimit[CAMPAIGN_MAX_ENTRIES];
 string campaign_mutators[CAMPAIGN_MAX_ENTRIES];
+#ifndef SVQC
 string campaign_shortdesc[CAMPAIGN_MAX_ENTRIES];
 string campaign_longdesc[CAMPAIGN_MAX_ENTRIES];
+#endif
 string campaign_title; // filled upon loading
 
 // load the campaign file, but use the given offset and limit the number of
index 65e1917fabdddc6a5b5c4ba274a3c6dd58a87133..0fef7816b34720448f34b36185ef14e6b40e6e45 100644 (file)
@@ -62,8 +62,13 @@ float CampaignFile_Load(int offset, float n)
                                CAMPAIGN_GETARG; campaign_fraglimit[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_timelimit[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_mutators[campaign_entries] = strzone(a);
+                               #ifdef SVQC
+                               CAMPAIGN_GETARG;
+                               CAMPAIGN_GETARG;
+                               #else
                                CAMPAIGN_GETARG; campaign_shortdesc[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_longdesc[campaign_entries] = strzone(strreplace("\\n", "\n", a));
+                               #endif
 
                                if(i > entlen)
                                        error("syntax error in campaign file: line has not enough fields");
@@ -95,8 +100,10 @@ void CampaignFile_Unload()
                        strfree(campaign_fraglimit[i]);
                        strfree(campaign_timelimit[i]);
                        strfree(campaign_mutators[i]);
+                       #ifndef SVQC
                        strfree(campaign_shortdesc[i]);
                        strfree(campaign_longdesc[i]);
+                       #endif
                }
                campaign_entries = 0;
        }
index bf45084d73bc47b305d62ed831e09536e42f14b9..1651af5e6d4ca725e0ff29635227bbe78881d449 100644 (file)
@@ -6,6 +6,7 @@
 #include "radiobutton.qh"
 #include "commandbutton.qh"
 #include "slider.qh"
+#include <common/campaign_common.qh>
 
 void welcomeDialog_resetStrings(entity me)
 {
@@ -56,6 +57,23 @@ void XonoticWelcomeDialog_readInputArgs(entity me, int argsbuf)
                        strcpy(me.serverinfo_name, bufstr_get(argsbuf, ++i));
                else if(s == "WELCOME")
                        strcpy(me.serverinfo_MOTD, bufstr_get(argsbuf, ++i));
+               else if(s == "CAMPAIGN")
+               {
+                       strcpy(me.serverinfo_name, campaign_title);
+
+                       int level = stoi(bufstr_get(argsbuf, ++i)) - 1;
+                       string campaign_msg;
+                       if (level < 0 || level >= campaign_entries)
+                               campaign_msg = strcat("^1Error: invalid level number ", itos(level + 1));
+                       else
+                       {
+                               string desc = strcat(campaign_shortdesc[level], "\n\n", campaign_longdesc[level]);
+                               desc = strreplace("\n", "\\n", desc);
+                               campaign_msg = strreplace("_LEVEL_DESC", desc, bufstr_get(argsbuf, ++i));
+                       }
+                       strcpy(me.serverinfo_MOTD, campaign_msg);
+                       break;
+               }
                else if(s == "RESET")
                {
                        welcomeDialog_resetStrings(me);
index bdb704b985d5beba3e3f707f71c4615a480cc08a..6ebce75b8e3e90a74fc8f1073cbb61ace801988f 100644 (file)
@@ -41,21 +41,11 @@ float Campaign_Invalid()
        return 0;
 }
 
-string Campaign_GetTitle()
-{
-       return campaign_title;
-}
-
 int Campaign_GetLevelNum()
 {
        return campaign_level + 1;
 }
 
-string Campaign_GetMessage()
-{
-       return strcat(campaign_shortdesc[0], "\n^3\n", campaign_longdesc[0]);
-}
-
 void CampaignPreInit()
 {
        float baseskill;
index 10e06a240f836f6328cf7834c6a66989529e6a1a..a9c790e3647a9cb0d8622652c63ee85de49956e2 100644 (file)
@@ -10,9 +10,7 @@ int autocvar_g_campaign_skill;
 // this must be included BEFORE campaign_common.h to make this a memory saving
 #define CAMPAIGN_MAX_ENTRIES 2
 
-string Campaign_GetTitle();
 int Campaign_GetLevelNum();
-string Campaign_GetMessage();
 
 void CampaignPreInit();
 void CampaignPostInit();
index 0a8846d5d166ee6750dc83fd4e0da570c8d4c0ab..00063bba214fae3ba064a144ec18bf2983db2eae 100644 (file)
@@ -1044,9 +1044,7 @@ void SendWelcomeMessage(entity this, int msg_type)
        WriteByte(msg_type, boolean(autocvar_g_campaign));
        if (boolean(autocvar_g_campaign))
        {
-               WriteString(msg_type, Campaign_GetTitle());
                WriteByte(msg_type, Campaign_GetLevelNum());
-               WriteString(msg_type, Campaign_GetMessage());
                return;
        }
        WriteString(msg_type, autocvar_hostname);