|
| 1 | +import { |
| 2 | + Crosshair, |
| 3 | + Dna, |
| 4 | + Eye, |
| 5 | + Flame, |
| 6 | + Gavel, |
| 7 | + Ghost, |
| 8 | + LucideIcon, |
| 9 | + Moon, |
| 10 | + Pill, |
| 11 | + Search, |
| 12 | + Shield, |
| 13 | + ShoppingBag, |
| 14 | + Skull, |
| 15 | + Sparkles, |
| 16 | + Sword, |
| 17 | + Swords, |
| 18 | + User, |
| 19 | + Wine, |
| 20 | + Zap, |
| 21 | +} from 'lucide-react'; |
| 22 | + |
| 23 | +export interface GameEntityConfig { |
| 24 | + id: string; |
| 25 | + color: string; |
| 26 | + icon: LucideIcon; |
| 27 | + translationKey: string; |
| 28 | + camp?: 'WEREWOLF' | 'GOD' | 'VILLAGER' | 'OTHER'; |
| 29 | +} |
| 30 | + |
| 31 | +export const GAME_ROLES: Record<string, GameEntityConfig> = { |
| 32 | + WEREWOLF: { |
| 33 | + id: 'WEREWOLF', |
| 34 | + color: '#ef4444', // Red-500 |
| 35 | + icon: Skull, |
| 36 | + translationKey: 'roles.labels.WEREWOLF', |
| 37 | + camp: 'WEREWOLF', |
| 38 | + }, |
| 39 | + WOLF_KING: { |
| 40 | + id: 'WOLF_KING', |
| 41 | + color: '#b91c1c', // Red-700 |
| 42 | + icon: Flame, |
| 43 | + translationKey: 'roles.labels.WOLF_KING', |
| 44 | + camp: 'WEREWOLF', |
| 45 | + }, |
| 46 | + WOLF_YOUNGER_BROTHER: { |
| 47 | + id: 'WOLF_YOUNGER_BROTHER', |
| 48 | + color: '#f87171', // Red-400 |
| 49 | + icon: Zap, |
| 50 | + translationKey: 'roles.labels.WOLF_YOUNGER_BROTHER', |
| 51 | + camp: 'WEREWOLF', |
| 52 | + }, |
| 53 | + WOLF_BROTHER: { |
| 54 | + id: 'WOLF_BROTHER', |
| 55 | + color: '#dc2626', // Red-600 |
| 56 | + icon: Skull, |
| 57 | + translationKey: 'roles.labels.WOLF_BROTHER', |
| 58 | + camp: 'WEREWOLF', |
| 59 | + }, |
| 60 | + SEER: { |
| 61 | + id: 'SEER', |
| 62 | + color: '#06b6d4', // Cyan-500 |
| 63 | + icon: Eye, |
| 64 | + translationKey: 'roles.labels.SEER', |
| 65 | + camp: 'GOD', |
| 66 | + }, |
| 67 | + WITCH: { |
| 68 | + id: 'WITCH', |
| 69 | + color: '#a855f7', // Purple-500 |
| 70 | + icon: Wine, |
| 71 | + translationKey: 'roles.labels.WITCH', |
| 72 | + camp: 'GOD', |
| 73 | + }, |
| 74 | + GUARD: { |
| 75 | + id: 'GUARD', |
| 76 | + color: '#3b82f6', // Blue-500 |
| 77 | + icon: Shield, |
| 78 | + translationKey: 'roles.labels.GUARD', |
| 79 | + camp: 'GOD', |
| 80 | + }, |
| 81 | + HUNTER: { |
| 82 | + id: 'HUNTER', |
| 83 | + color: '#f97316', // Orange-500 |
| 84 | + icon: Swords, |
| 85 | + translationKey: 'roles.labels.HUNTER', |
| 86 | + camp: 'GOD', |
| 87 | + }, |
| 88 | + VILLAGER: { |
| 89 | + id: 'VILLAGER', |
| 90 | + color: '#10b981', // Emerald-500 |
| 91 | + icon: User, |
| 92 | + translationKey: 'roles.labels.VILLAGER', |
| 93 | + camp: 'VILLAGER', |
| 94 | + }, |
| 95 | + IDIOT: { |
| 96 | + id: 'IDIOT', |
| 97 | + color: '#facc15', // Yellow-400 |
| 98 | + icon: Gavel, |
| 99 | + translationKey: 'roles.labels.IDIOT', |
| 100 | + camp: 'GOD', |
| 101 | + }, |
| 102 | + KNIGHT: { |
| 103 | + id: 'KNIGHT', |
| 104 | + color: '#6366f1', // Indigo-500 |
| 105 | + icon: Sword, |
| 106 | + translationKey: 'roles.labels.KNIGHT', |
| 107 | + camp: 'GOD', |
| 108 | + }, |
| 109 | + GRAVE_KEEPER: { |
| 110 | + id: 'GRAVE_KEEPER', |
| 111 | + color: '#475569', // Slate-600 |
| 112 | + icon: Skull, |
| 113 | + translationKey: 'roles.labels.GRAVE_KEEPER', |
| 114 | + camp: 'GOD', |
| 115 | + }, |
| 116 | + DREAM_EATER: { |
| 117 | + id: 'DREAM_EATER', |
| 118 | + color: '#ec4899', // Pink-500 |
| 119 | + icon: Moon, |
| 120 | + translationKey: 'roles.labels.DREAM_EATER', |
| 121 | + camp: 'GOD', |
| 122 | + }, |
| 123 | + MAGICIAN: { |
| 124 | + id: 'MAGICIAN', |
| 125 | + color: '#8b5cf6', // Violet-500 |
| 126 | + icon: Sparkles, |
| 127 | + translationKey: 'roles.labels.MAGICIAN', |
| 128 | + camp: 'GOD', |
| 129 | + }, |
| 130 | + WHITE_WOLF_KING: { |
| 131 | + id: 'WHITE_WOLF_KING', |
| 132 | + color: '#ef4444', // Red-500 |
| 133 | + icon: Flame, |
| 134 | + translationKey: 'roles.labels.WHITE_WOLF_KING', |
| 135 | + camp: 'WEREWOLF', |
| 136 | + }, |
| 137 | + HIDDEN_WOLF: { |
| 138 | + id: 'HIDDEN_WOLF', |
| 139 | + color: '#dc2626', // Red-600 |
| 140 | + icon: Ghost, |
| 141 | + translationKey: 'roles.labels.HIDDEN_WOLF', |
| 142 | + camp: 'WEREWOLF', |
| 143 | + }, |
| 144 | + GARGOYLE: { |
| 145 | + id: 'GARGOYLE', |
| 146 | + color: '#991b1b', // Red-800 |
| 147 | + icon: Eye, |
| 148 | + translationKey: 'roles.labels.GARGOYLE', |
| 149 | + camp: 'WEREWOLF', |
| 150 | + }, |
| 151 | + NIGHT_KNIGHT: { |
| 152 | + id: 'NIGHT_KNIGHT', |
| 153 | + color: '#7f1d1d', // Red-900 |
| 154 | + icon: Crosshair, |
| 155 | + translationKey: 'roles.labels.NIGHT_KNIGHT', |
| 156 | + camp: 'WEREWOLF', |
| 157 | + }, |
| 158 | + BLOOD_MOON: { |
| 159 | + id: 'BLOOD_MOON', |
| 160 | + color: '#991b1b', // Red-800 |
| 161 | + icon: Moon, |
| 162 | + translationKey: 'roles.labels.BLOOD_MOON', |
| 163 | + camp: 'WEREWOLF', |
| 164 | + }, |
| 165 | + ROBOT_WOLF: { |
| 166 | + id: 'ROBOT_WOLF', |
| 167 | + color: '#dc2626', // Red-600 |
| 168 | + icon: Zap, |
| 169 | + translationKey: 'roles.labels.ROBOT_WOLF', |
| 170 | + camp: 'WEREWOLF', |
| 171 | + }, |
| 172 | + CLONE: { |
| 173 | + id: 'CLONE', |
| 174 | + color: '#8b5cf6', // Violet-500 |
| 175 | + icon: Dna, |
| 176 | + translationKey: 'roles.labels.CLONE', |
| 177 | + camp: 'GOD', |
| 178 | + }, |
| 179 | + DARK_MERCHANT: { |
| 180 | + id: 'DARK_MERCHANT', |
| 181 | + color: '#eab308', // Gold-500 |
| 182 | + icon: ShoppingBag, |
| 183 | + translationKey: 'roles.labels.DARK_MERCHANT', |
| 184 | + camp: 'GOD', |
| 185 | + }, |
| 186 | + HIDDEN: { |
| 187 | + id: 'HIDDEN', |
| 188 | + color: '#64748b', // Slate-500 |
| 189 | + icon: Ghost, |
| 190 | + translationKey: 'roles.labels.HIDDEN', |
| 191 | + camp: 'OTHER', |
| 192 | + }, |
| 193 | +}; |
| 194 | + |
| 195 | +export const GAME_ACTIONS: Record<string, GameEntityConfig> = { |
| 196 | + WEREWOLF_KILL: { |
| 197 | + id: 'WEREWOLF_KILL', |
| 198 | + color: '#ef4444', |
| 199 | + icon: Sword, |
| 200 | + translationKey: 'roles.actions.WEREWOLF_KILL', |
| 201 | + }, |
| 202 | + WOLF_YOUNGER_BROTHER_EXTRA_KILL: { |
| 203 | + id: 'WOLF_YOUNGER_BROTHER_EXTRA_KILL', |
| 204 | + color: '#f87171', |
| 205 | + icon: Flame, |
| 206 | + translationKey: 'roles.actions.WOLF_YOUNGER_BROTHER_EXTRA_KILL', |
| 207 | + }, |
| 208 | + WITCH_ANTIDOTE: { |
| 209 | + id: 'WITCH_ANTIDOTE', |
| 210 | + color: '#10b981', |
| 211 | + icon: Pill, |
| 212 | + translationKey: 'roles.actions.WITCH_ANTIDOTE', |
| 213 | + }, |
| 214 | + WITCH_POISON: { |
| 215 | + id: 'WITCH_POISON', |
| 216 | + color: '#a855f7', |
| 217 | + icon: Pill, |
| 218 | + translationKey: 'roles.actions.WITCH_POISON', |
| 219 | + }, |
| 220 | + SEER_CHECK: { |
| 221 | + id: 'SEER_CHECK', |
| 222 | + color: '#06b6d4', |
| 223 | + icon: Search, |
| 224 | + translationKey: 'roles.actions.SEER_CHECK', |
| 225 | + }, |
| 226 | + GUARD_PROTECT: { |
| 227 | + id: 'GUARD_PROTECT', |
| 228 | + color: '#f59e0b', |
| 229 | + icon: Shield, |
| 230 | + translationKey: 'roles.actions.GUARD_PROTECT', |
| 231 | + }, |
| 232 | + HUNTER_REVENGE: { |
| 233 | + id: 'HUNTER_REVENGE', |
| 234 | + color: '#ec4899', |
| 235 | + icon: Crosshair, |
| 236 | + translationKey: 'roles.actions.HUNTER_REVENGE', |
| 237 | + }, |
| 238 | + WOLF_KING_REVENGE: { |
| 239 | + id: 'WOLF_KING_REVENGE', |
| 240 | + color: '#b91c1c', |
| 241 | + icon: Flame, |
| 242 | + translationKey: 'roles.actions.WOLF_KING_REVENGE', |
| 243 | + }, |
| 244 | + DARK_MERCHANT_TRADE: { |
| 245 | + id: 'DARK_MERCHANT_TRADE', |
| 246 | + color: '#eab308', |
| 247 | + icon: ShoppingBag, |
| 248 | + translationKey: 'roles.actions.DARK_MERCHANT_TRADE', |
| 249 | + }, |
| 250 | + MERCHANT_SEER_CHECK: { |
| 251 | + id: 'MERCHANT_SEER_CHECK', |
| 252 | + color: '#06b6d4', |
| 253 | + icon: Search, |
| 254 | + translationKey: 'roles.actions.MERCHANT_SEER_CHECK', |
| 255 | + }, |
| 256 | + MERCHANT_POISON: { |
| 257 | + id: 'MERCHANT_POISON', |
| 258 | + color: '#a855f7', |
| 259 | + icon: Pill, |
| 260 | + translationKey: 'roles.actions.MERCHANT_POISON', |
| 261 | + }, |
| 262 | + MERCHANT_GUN: { |
| 263 | + id: 'MERCHANT_GUN', |
| 264 | + color: '#ec4899', |
| 265 | + icon: Crosshair, |
| 266 | + translationKey: 'roles.actions.MERCHANT_GUN', |
| 267 | + }, |
| 268 | + DEATH: { |
| 269 | + id: 'DEATH', |
| 270 | + color: '#6b7280', |
| 271 | + icon: Skull, |
| 272 | + translationKey: 'roles.actions.DEATH', |
| 273 | + }, |
| 274 | +}; |
| 275 | + |
| 276 | +// Helper function to get role config by name (handling English/Chinese variants if needed) |
| 277 | +export const getRoleConfig = (roleName: string): GameEntityConfig => { |
| 278 | + const upper = roleName.toUpperCase(); |
| 279 | + if (GAME_ROLES[upper]) return GAME_ROLES[upper]; |
| 280 | + |
| 281 | + // Fallback for Chinese names if they come from backend directly |
| 282 | + if (roleName.includes('白狼王')) return GAME_ROLES.WHITE_WOLF_KING; |
| 283 | + if (roleName.includes('狼王')) return GAME_ROLES.WOLF_KING; |
| 284 | + if (roleName.includes('狼弟')) return GAME_ROLES.WOLF_YOUNGER_BROTHER; |
| 285 | + if (roleName.includes('狼兄')) return GAME_ROLES.WOLF_BROTHER; |
| 286 | + if (roleName.includes('隱狼')) return GAME_ROLES.HIDDEN_WOLF; |
| 287 | + if (roleName.includes('石像鬼')) return GAME_ROLES.GARGOYLE; |
| 288 | + if (roleName.includes('惡靈騎士')) return GAME_ROLES.NIGHT_KNIGHT; |
| 289 | + if (roleName.includes('血月使者')) return GAME_ROLES.BLOOD_MOON; |
| 290 | + if (roleName.includes('機械狼')) return GAME_ROLES.ROBOT_WOLF; |
| 291 | + if (roleName.includes('狼')) return GAME_ROLES.WEREWOLF; |
| 292 | + if (roleName.includes('預言')) return GAME_ROLES.SEER; |
| 293 | + if (roleName.includes('女巫')) return GAME_ROLES.WITCH; |
| 294 | + if (roleName.includes('守衛')) return GAME_ROLES.GUARD; |
| 295 | + if (roleName.includes('獵人')) return GAME_ROLES.HUNTER; |
| 296 | + if (roleName.includes('白痴')) return GAME_ROLES.IDIOT; |
| 297 | + if (roleName.includes('騎士')) return GAME_ROLES.KNIGHT; |
| 298 | + if (roleName.includes('守墓人')) return GAME_ROLES.GRAVE_KEEPER; |
| 299 | + if (roleName.includes('攝夢人')) return GAME_ROLES.DREAM_EATER; |
| 300 | + if (roleName.includes('魔術師')) return GAME_ROLES.MAGICIAN; |
| 301 | + if (roleName.includes('平民') || roleName.includes('村民')) return GAME_ROLES.VILLAGER; |
| 302 | + if (roleName.includes('黑市')) return GAME_ROLES.DARK_MERCHANT; |
| 303 | + if (roleName.includes('複製')) return GAME_ROLES.CLONE; |
| 304 | + |
| 305 | + return GAME_ROLES.HIDDEN; |
| 306 | +}; |
| 307 | + |
| 308 | +// Helper function to get action config by ID |
| 309 | +export const getActionConfig = (actionId: string): GameEntityConfig => { |
| 310 | + const config = Object.values(GAME_ACTIONS).find((a) => actionId.includes(a.id)); |
| 311 | + if (config) return config; |
| 312 | + |
| 313 | + return { |
| 314 | + id: 'UNKNOWN', |
| 315 | + color: '#6b7280', |
| 316 | + icon: Gavel, |
| 317 | + translationKey: 'roles.actions.UNKNOWN', |
| 318 | + }; |
| 319 | +}; |
0 commit comments