石器百科 开始游戏

PK 与决斗

石器时代 2.5 没有「野外随意杀人」的 PK。玩家之间的战斗只有几种正规途径:

方式 在哪里 输了会怎样
决斗 几乎任何地方,对方必须开着「决斗」开关 只影响 DP,不掉东西、不回城
家族 PK 场 家族 PK 竞技场,需要族长预约 被请出场地,最后按人数定胜负
庄园争夺战 各村庄园的 PK 场 决定庄园归属

战斗本身的规则(伤害、属性、闪避等)和打怪完全一样,见 战斗系统。本文只讲玩家对战特有的部分。

决斗

怎么发起

  1. 面对你想挑战的玩家(站在他旁边、朝向他那一格)。
  2. 按画面右侧面板的「决斗」按钮。
  3. 只要对方的「决斗」开关是开着的,战斗立刻开始,没有确认步骤。

几个条件:

  • 对方必须在选单(游戏设定窗口)里把「决斗」设为允许。不允许的话会提示「无人可以对战」;面前没人则提示「那里没有任何人」。
  • 你自己是队员(不是队长)时按决斗无效。
  • 对方是某个队伍的队员时,你会直接对上他的整支队伍(找他的队长)。你自己是队长时,你的整队也一起参战。
  • 双方都已经在战斗中、或者双方在同一个队伍里,会提示遭遇失败。
  • 面前同时站着多个可决斗的玩家时,会弹出「要和谁战斗?」的选择窗口,并标明对方是「团体」还是「单独」。

出处:callfromcli.c lssproto_DU_recv(只检查面前一格、CHAR_ISDUEL、队员找队长);battle/battle.c BATTLE_CreateVsPlayer(BATTLE_ERR_ALREADYBATTLE、BATTLE_ERR_SAMEPARTY)。

决斗开关会自动关闭

为了防止被人「偷袭决斗」,「决斗」开关在两种时候会被服务端自动关掉:

  • 每次登录时。
  • 每打完一场决斗后。

想继续接受挑战,需要重新在选单里打开。

出处:char/char.c CHAR_login(CHAR_setFlg( charaindex, CHAR_ISDUEL, 0));battle/battle.c BATTLE_Exit(BATTLE_TYPE_P_vs_P 时关闭 CHAR_ISDUEL 并 lssproto_FS_send)。

决斗中的规则

  • 双方都由玩家自己下指令,宠物照常出战。
  • 不能捕捉,不能求救 / 参战(别人不能中途加入)。
  • 逃跑必定成功,但可能扣 DP(见下节)。
  • 没有经验值、没有掉落物、没有石币。
  • 倒下、被击飞都没有魅力和忠诚度惩罚,也不会被送回记录点;战斗结束时倒下的人 HP 变为 1,留在原地。
  • 异常状态的命中率计算中,决斗时不计等级差修正(等级高也不会更容易让对方中毒、石化)。
  • 战斗结束的结算窗口会显示本场 DP 的增减和合计。

出处:battle/battle_event.c BATTLE_EscapeCheck(P_vs_P 直接成功)、BATTLE_StatusAttackCheck(P_vs_P 时 level = 0);battle/battle.c BATTLE_RescueEntry(P_vs_P 拒绝加入)、BATTLE_CreateVsPlayer(清除 BSIDE_FLG_HELP_OK)、BATTLE_NormalDeadExtra / BATTLE_UltimateExtra(惩罚只在 P_vs_E)、BATTLE_GetProfit(dpbattle == 1 时只结算 DP)。

DP(决斗点数)

DP 是玩家对战的积分,显示在人物状态窗口和名片里,也是「强者表」排名的依据。

  • 新角色的 DP 是 100,上限 1 亿,不会低于 0。
  • 打怪不影响 DP,只有决斗会改变它。

出处:include/defaultPlayer.h(CHAR_DUELPOINT 默认 100);include/char_base.h(CHAR_MAXDUELPOINT 100000000)。

打倒对手:抢走他 10% 的 DP

决斗中,每当有玩家被打倒(HP 归零或被击飞),他立即失去当前 DP 的 10%(取整)。这些 DP 分给打出那一击的人:

  • 分给「打倒他的那次行动」的所有参与者(合击时多人平分),宠物打倒的算在宠物主人头上。
  • 每人至少分到 1 点。
  • 如果是被自己人打倒的(例如混乱时误伤),这份 DP 改为平分给对方还活着的玩家。
  • 宠物被打倒不影响 DP。

例:DP 500 的玩家 A 被 B、C 的合击打倒 → A 失去 50,B、C 各得 25。

出处:battle/battle.c BATTLE_AddDuelPoint(DUELPOINT_RATE = 0.1,side != j 时分给攻击者、否则 BATTLE_AddDpAlive 分给对方存活者);include/battle.h DUELPOINT_RATE。

逃跑:第一回合免费,之后扣双倍

  • 开战第一回合就逃跑,不扣 DP。
  • 第二回合以后逃跑:逃跑者失去 DP 的 20%(即 10% 的两倍,最少 2 点);对方每个还活着的玩家得到「逃跑者 DP 的 10% ÷ 对方存活人数」(至少 1 点)。
  • 决斗中断线 / 登出按逃跑处理。

例:DP 1000 的玩家在第 3 回合逃跑,对面活着 2 人 → 逃跑者 -200,对面两人各 +50。

出处:battle/battle.c BATTLE_EscapeDpSend(BATTLE_FLG_FREEDP 时为 0;否则 -dpadd*2,对方 dpadd / cnt);battle/battle_command.c BattleCommandDispach(第 0 回合不清除 FREEDP);char/char.c 登出时调用 BATTLE_EscapeDpSend。

结算

一场决斗中所有得失先累计,战斗结束(或你离开战斗)时一次性加到 DP 上:只要本场有变化,最少也会 ±1。

注意:原版没有「胜利奖励」。DP 只通过「打倒对手」和「对手逃跑」流动——赢了但一个人都没打倒(对方第一回合全跑了)就拿不到 DP。

出处:battle/battle.c BATTLE_GetDuelPoint(dpadd 至少 ±1,lssproto_RD_send 显示结算)。原版另有一套按胜负整场结算的 BATTLE_DpCalc,只在定义了 DANTAI 时才编译,2.5 服务端没有启用。

网页版照原版移植:打倒时累计、逃跑 / 断线时立即结算、结束时 BATTLE_GetDuelPoint,第 0 回合与「本回合只有逃跑指令」时的免费逃跑(BattleCommandDispach 的 EscapeFree)也一样(packages/tools/src/game/world.ts duelDead / duelEscapeDp / duelGetPoint / duelCommand)。

强者表(DP 排行)

各村的「强者表」NPC 可以查看全服务器的 DP 排行:

地图 坐标
萨姆吉尔村 (60,61)、(88,105)
玛丽娜丝渔村 (63,55)、(81,78)
加加村 (108,84)
卡鲁它那村 (83,59)
竞技场 (40,13)、(22,58)

和它对话后可以选择:

  • 强者们:从第 1 名开始,每页 10 人,显示名次、DP、等级、名字。可以翻页,也可以输入名次直接跳到那一页。
  • 自己:跳到自己所在的那一页(从自己的前 5 名开始显示),自己那一行前面有 ★ 标记。

出处:npc/npc_duelranking.c(NPC_DUELRANKING_WINDOWLINENUM 10、NPC_Duelranking_CallMyRanking 中 count -= 5、★ 标记);data/npc/chatroom/duelranking.create(各「强者表」的位置)。

观战

原版可以观看别人的战斗:

  1. 面对一个正在战斗中的玩家。
  2. 在以下地图按「参战」按钮会变成观战,其他地图则是参战(加入对方的战斗):
  3. 面前有多个战斗中的人时,会弹出「观看谁的战斗呢?」让你选择。

观战时你只能看,不能下指令;想离开就按战斗画面里的离开指令。决斗和打怪都可以观战。

出处:callfromcli.c lssproto_JB_recv(地图 1007/2007/3007/4007/130 走 BATTLE_WatchTry,其余 BATTLE_RescueTry)、lssproto_LB_recv;battle/battle.c BATTLE_WatchTry、BATTLE_WatchEntry、BATTLE_CreateForWatcher;battle/battle_command.c「U」指令(观战中为 BATTLE_WatchStop)。

网页版已实现观战(右上「按滑鼠右键 / 结束观战」窗;触屏点这个窗也能离开)。面前同一格有多名战斗中的玩家时,原版弹出「观看谁的战斗呢?」选单,网页版直接观看客户端选中的那一位。

家族 PK

家族之间的正式对战在家族 PK 场进行,由族长预约、双方家族成员进场互相决斗。这里只简述流程,家族相关的完整说明见 家族。

场地

场地 用途
草原PK竞技场、丛林PK竞技场、武斗场PK竞技场、水池PK竞技场、树洞PK竞技场 家族对家族的预约 PK
萨姆吉尔庄园竞技场、玛丽娜丝庄园PK场、加加村庄园PK场、卡鲁它那庄园PK场 庄园争夺战

出处:char/family.c fmpkflnum[](142~146、1042、2032、3032、4032)。

流程

  1. 预约:族长找「场地预约人」(scheduleman),选一个时段和对手家族,发出挑战。
  2. 接受:对方族长到预约人那里同意,这场 PK 就排进赛程。一个家族同一时间只能排一场。
  3. 进场:时间到了,由「家族对战向导」把双方成员分别送进场地。准备时间内还不能打。
  4. 开战:向导宣布「开战罗~!!」之后,场内不同家族的成员之间可以用「决斗」按钮互相开打;同家族之间不能决斗,开战前也不能决斗。
  5. 出局:在 PK 场决斗中输掉的人会被请出场地(「战败离场」)。
  6. 胜负:一方在场人数归零,另一方获胜;如果打到该小时的 59 分还没分出胜负,按场内剩余人数(或损失人数,看预约时选的规则)判定,人数相同为平手。之后清场。

出处:npc/npc_scheduleman.c(预约、NPC_AlreadyScheduled 一族一场);npc/npc_fmwarpman.c(FMWARPMAN_CLEANPLACE 59、「战败离场」、「双方平手」);callfromcli.c lssproto_DU_recv(PK 场内 CHAR_WORKBATTLEFLAG == -1 时不能决斗、同 CHAR_FMINDEX 不能决斗);battle/battle.c BATTLE_Exit(倒下者 CHAR_WORKFMPKFLAG = -1)。

庄园争夺战

庄园可以由排名靠前的家族(本服务端版本为前 20 名)发起挑战,在庄园 PK 场进行,胜者取得或保住庄园。规则细节见 家族。

出处:include/version.h _FIX_FAMILY_PK_LIMIT(「将可挑战庄园的由前十大改为前二十大」)、_MANOR_PKRULE。

其他 PK 相关功能(本服务端未实际启用)

这份 2.5 私服服务端源码里还编译了两个扩展 PK 功能,但数据里没有对应内容,实际游戏中用不到:

  • 强制 PK 道具(_BATTLE_PK):对任意玩家强行开战,输的一方被送回记录点。data/itemset.txt 中没有任何道具使用这个功能。
  • 自动 PK 赛(_AUTO_PK):在地图 20000 定时举办的淘汰赛,有战况广播和冠军记录。数据中没有地图 20000,也没有对应的 NPC。

出处:item/item_event.c ITEM_BattlePK;battle/battle.c BATTLE_Finish 中 _BATTLE_PK / _AUTO_PK 段;npc/npc_autopk.c。