werewolf.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. import { defineStore } from 'pinia'
  2. import { werewolfAPI } from '@/services/api/games/werewolf'
  3. // 玩家角色类型
  4. export type WerewolfRole =
  5. | 'werewolf' // 狼人
  6. | 'villager' // 村民
  7. | 'seer' // 预言家
  8. | 'witch' // 女巫
  9. | 'hunter' // 猎人
  10. | 'guard' // 守卫
  11. | 'idiot' // 白痴
  12. | 'elder' // 长老
  13. | 'cupid' // 丘比特
  14. | 'thief' // 盗贼
  15. | 'moderator'; // 主持人/上帝
  16. // 游戏阶段
  17. export type GamePhase =
  18. | 'waiting' // 等待开始
  19. | 'night' // 夜晚
  20. | 'day' // 白天
  21. | 'vote' // 投票
  22. | 'ended'; // 游戏结束
  23. // 行动类型
  24. export type ActionType =
  25. | 'kill' // 狼人杀人
  26. | 'check' // 预言家查验
  27. | 'save' // 女巫救人
  28. | 'poison' // 女巫毒人
  29. | 'protect' // 守卫保护
  30. | 'shoot' // 猎人开枪
  31. | 'vote' // 投票
  32. | 'pair'; // 丘比特连线
  33. // 玩家状态
  34. export type PlayerStatus =
  35. | 'alive' // 存活
  36. | 'dead' // 死亡
  37. | 'protected' // 受保护
  38. | 'poisoned' // 中毒
  39. | 'coupled'; // 情侣
  40. // 游戏结果类型
  41. export type GameResult =
  42. | 'werewolf_win' // 狼人阵营胜利
  43. | 'villager_win' // 村民阵营胜利
  44. | 'couple_win' // 情侣胜利
  45. | 'draw' // 平局
  46. | null; // 游戏进行中
  47. // 玩家信息
  48. export interface WerewolfPlayer {
  49. id: string;
  50. name: string;
  51. avatar: string;
  52. role: WerewolfRole;
  53. status: PlayerStatus;
  54. isReady: boolean;
  55. isDead: boolean;
  56. actions: {
  57. [key in ActionType]?: boolean;
  58. };
  59. // 特殊状态
  60. isLovers?: boolean; // 是否为情侣
  61. lastWords?: string; // 遗言
  62. voteTarget?: string; // 投票目标
  63. deadRound?: number; // 死亡回合
  64. }
  65. // 游戏日志
  66. export interface GameLog {
  67. round: number;
  68. phase: GamePhase;
  69. content: string;
  70. timestamp: number;
  71. isPublic: boolean;
  72. targetPlayers?: string[];
  73. }
  74. // 游戏状态
  75. export interface WerewolfGame {
  76. id: string;
  77. title: string;
  78. hosterId: string;
  79. hosterName: string;
  80. createTime: number;
  81. startTime: number | null;
  82. endTime: number | null;
  83. players: WerewolfPlayer[];
  84. currentRound: number;
  85. phase: GamePhase;
  86. result: GameResult;
  87. currentAction: ActionType | null;
  88. timeLimit: number; // 每个阶段的时间限制(秒)
  89. logs: GameLog[];
  90. options: {
  91. roles: {
  92. [key in WerewolfRole]?: number; // 角色数量配置
  93. };
  94. includeSpecialRoles: boolean; // 是否包含特殊角色
  95. allowLastWords: boolean; // 是否允许遗言
  96. nightTimeLimit: number; // 夜晚时间限制
  97. dayTimeLimit: number; // 白天时间限制
  98. voteTimeLimit: number; // 投票时间限制
  99. };
  100. }
  101. // 定义 Store
  102. export const useWerewolfStore = defineStore('werewolf', {
  103. state: () => ({
  104. currentGame: null as WerewolfGame | null,
  105. loading: false,
  106. error: null as string | null,
  107. currentPlayer: null as WerewolfPlayer | null,
  108. timer: null as number | null,
  109. remainingTime: 0,
  110. myRole: null as WerewolfRole | null,
  111. myActions: [] as ActionType[],
  112. gameResult: null as GameResult,
  113. showRoleInfo: false,
  114. showActionInfo: false
  115. }),
  116. getters: {
  117. // 获取活着的玩家
  118. alivePlayers: (state) => {
  119. if (!state.currentGame) return [];
  120. return state.currentGame.players.filter(p => !p.isDead);
  121. },
  122. // 获取死亡的玩家
  123. deadPlayers: (state) => {
  124. if (!state.currentGame) return [];
  125. return state.currentGame.players.filter(p => p.isDead);
  126. },
  127. // 获取狼人玩家
  128. werewolfPlayers: (state) => {
  129. if (!state.currentGame) return [];
  130. return state.currentGame.players.filter(p => p.role === 'werewolf');
  131. },
  132. // 获取村民阵营玩家
  133. villagerTeamPlayers: (state) => {
  134. if (!state.currentGame) return [];
  135. return state.currentGame.players.filter(p =>
  136. p.role !== 'werewolf' && p.role !== 'moderator'
  137. );
  138. },
  139. // 当前玩家是否是狼人
  140. isWerewolf: (state) => {
  141. return state.myRole === 'werewolf';
  142. },
  143. // 是否是夜晚
  144. isNightPhase: (state) => {
  145. return state.currentGame?.phase === 'night';
  146. },
  147. // 是否是白天
  148. isDayPhase: (state) => {
  149. return state.currentGame?.phase === 'day';
  150. },
  151. // 是否是投票阶段
  152. isVotePhase: (state) => {
  153. return state.currentGame?.phase === 'vote';
  154. },
  155. // 游戏是否结束
  156. isGameEnded: (state) => {
  157. return state.currentGame?.phase === 'ended';
  158. },
  159. // 当前玩家是否可以行动
  160. canAct: (state) => {
  161. if (!state.currentGame || !state.myRole || !state.currentPlayer) return false;
  162. if (state.currentPlayer.isDead) return false;
  163. const { phase, currentAction } = state.currentGame;
  164. // 根据游戏阶段和角色确定是否可以行动
  165. if (phase === 'night') {
  166. switch (currentAction) {
  167. case 'kill': return state.myRole === 'werewolf';
  168. case 'check': return state.myRole === 'seer';
  169. case 'save':
  170. case 'poison': return state.myRole === 'witch';
  171. case 'protect': return state.myRole === 'guard';
  172. case 'pair': return state.myRole === 'cupid';
  173. default: return false;
  174. }
  175. } else if (phase === 'vote') {
  176. return !state.currentPlayer.voteTarget;
  177. }
  178. return false;
  179. },
  180. // 获取当前可选择的目标玩家
  181. availableTargets: (state) => {
  182. if (!state.currentGame || !state.myRole) return [];
  183. const { phase, currentAction, players } = state.currentGame;
  184. // 根据不同行动类型过滤可选目标
  185. if (phase === 'night') {
  186. switch (currentAction) {
  187. case 'kill': // 狼人只能杀死非狼人
  188. return players.filter(p => !p.isDead && p.role !== 'werewolf');
  189. case 'check': // 预言家查验活着的玩家
  190. return players.filter(p => !p.isDead);
  191. case 'save': // 女巫只能救死亡的玩家
  192. return players.filter(p => p.status === 'poisoned');
  193. case 'poison': // 女巫只能毒活着的玩家
  194. return players.filter(p => !p.isDead);
  195. case 'protect': // 守卫只能保护活着的玩家
  196. return players.filter(p => !p.isDead);
  197. default:
  198. return [];
  199. }
  200. } else if (phase === 'vote') {
  201. // 投票阶段可以选择所有活着的玩家(除了自己)
  202. return players.filter(p => !p.isDead && p.id !== state.currentPlayer?.id);
  203. }
  204. return [];
  205. }
  206. },
  207. actions: {
  208. // 加载游戏数据
  209. async loadGame(gameId: string, role: string) {
  210. this.loading = true;
  211. this.error = null;
  212. try {
  213. const result = await werewolfAPI.getGameData(gameId, role);
  214. if (result && result.game) {
  215. this.currentGame = result.game;
  216. // 找到当前玩家
  217. if (this.currentGame.players) {
  218. // 这里需要根据实际情况从某处获取当前用户ID
  219. const currentUserId = 'current_user_id'; // 应替换为实际的用户ID获取方式
  220. this.currentPlayer = this.currentGame.players.find(p => p.id === currentUserId) || null;
  221. this.myRole = this.currentPlayer?.role || null;
  222. }
  223. return true;
  224. }
  225. this.error = '加载游戏数据失败';
  226. return false;
  227. } catch (err) {
  228. console.error('加载狼人杀游戏失败:', err);
  229. this.error = err instanceof Error ? err.message : '未知错误';
  230. return false;
  231. } finally {
  232. this.loading = false;
  233. }
  234. },
  235. // 准备游戏
  236. async readyGame() {
  237. if (!this.currentGame || !this.currentPlayer) return false;
  238. try {
  239. await werewolfAPI.playerAction(
  240. this.currentGame.id,
  241. this.currentPlayer.id,
  242. 'ready'
  243. );
  244. return true;
  245. } catch (err) {
  246. console.error('准备游戏失败:', err);
  247. return false;
  248. }
  249. },
  250. // 玩家行动
  251. async performAction(action: ActionType, targetId?: string) {
  252. if (!this.currentGame || !this.currentPlayer) return false;
  253. try {
  254. await werewolfAPI.playerAction(
  255. this.currentGame.id,
  256. this.currentPlayer.id,
  257. action,
  258. targetId
  259. );
  260. return true;
  261. } catch (err) {
  262. console.error('执行行动失败:', err);
  263. return false;
  264. }
  265. },
  266. // 狼人杀人
  267. async killPlayer(targetId: string) {
  268. return this.performAction('kill', targetId);
  269. },
  270. // 预言家查验
  271. async checkPlayer(targetId: string) {
  272. return this.performAction('check', targetId);
  273. },
  274. // 女巫救人
  275. async savePlayer(targetId: string) {
  276. return this.performAction('save', targetId);
  277. },
  278. // 女巫毒人
  279. async poisonPlayer(targetId: string) {
  280. return this.performAction('poison', targetId);
  281. },
  282. // 守卫保护
  283. async protectPlayer(targetId: string) {
  284. return this.performAction('protect', targetId);
  285. },
  286. // 投票
  287. async votePlayer(targetId: string) {
  288. return this.performAction('vote', targetId);
  289. },
  290. // 猎人开枪
  291. async shootPlayer(targetId: string) {
  292. return this.performAction('shoot', targetId);
  293. },
  294. // 丘比特连线
  295. async couplePlayer(player1Id: string, player2Id: string) {
  296. try {
  297. await werewolfAPI.playerAction(
  298. this.currentGame!.id,
  299. this.currentPlayer!.id,
  300. 'pair',
  301. JSON.stringify([player1Id, player2Id])
  302. );
  303. return true;
  304. } catch (err) {
  305. console.error('丘比特连线失败:', err);
  306. return false;
  307. }
  308. },
  309. // 留遗言
  310. async leaveLastWords(message: string) {
  311. if (!this.currentGame || !this.currentPlayer) return false;
  312. try {
  313. await werewolfAPI.playerAction(
  314. this.currentGame.id,
  315. this.currentPlayer.id,
  316. 'lastWords',
  317. message
  318. );
  319. return true;
  320. } catch (err) {
  321. console.error('留遗言失败:', err);
  322. return false;
  323. }
  324. },
  325. // 开始倒计时
  326. startTimer(seconds: number) {
  327. this.remainingTime = seconds;
  328. // 清除现有的计时器
  329. if (this.timer !== null) {
  330. clearInterval(this.timer);
  331. }
  332. // 设置新的计时器
  333. this.timer = window.setInterval(() => {
  334. if (this.remainingTime > 0) {
  335. this.remainingTime--;
  336. } else {
  337. if (this.timer !== null) {
  338. clearInterval(this.timer);
  339. this.timer = null;
  340. }
  341. }
  342. }, 1000);
  343. },
  344. // 停止倒计时
  345. stopTimer() {
  346. if (this.timer !== null) {
  347. clearInterval(this.timer);
  348. this.timer = null;
  349. }
  350. },
  351. // 显示角色信息
  352. showRoleInformation() {
  353. this.showRoleInfo = true;
  354. },
  355. // 隐藏角色信息
  356. hideRoleInformation() {
  357. this.showRoleInfo = false;
  358. },
  359. // 清理游戏数据
  360. clearGame() {
  361. this.currentGame = null;
  362. this.currentPlayer = null;
  363. this.myRole = null;
  364. this.myActions = [];
  365. this.gameResult = null;
  366. this.stopTimer();
  367. }
  368. }
  369. });