| 238 | } |
| 239 | |
| 240 | function tryMovePlayer(dx: number, dy: number): void { |
| 241 | const nx = player.mapX + dx; |
| 242 | const ny = player.mapY + dy; |
| 243 | |
| 244 | if (!isWalkable(nx, ny)) return; |
| 245 | |
| 246 | // Check for NPC |
| 247 | const ni = npcAt(nx, ny); |
| 248 | if (ni >= 0) { |
| 249 | if (npcs[ni].friendly) { |
| 250 | // Talk |
| 251 | dialogueNpc = ni; |
| 252 | dialogueText = npcs[ni].dialogue[npcs[ni].dialogueIndex]; |
| 253 | showDialogue = true; |
| 254 | } else { |
| 255 | // Combat |
| 256 | const dmg = Math.max(1, player.attack - npcs[ni].defense + randomInt(-2, 2)); |
| 257 | npcs[ni].hp = npcs[ni].hp - dmg; |
| 258 | showMsg("Hit " + npcs[ni].name + " for " + dmg.toString() + "!"); |
| 259 | if (npcs[ni].hp <= 0) { |
| 260 | showMsg("Defeated " + npcs[ni].name + "!"); |
| 261 | exp = exp + 10; |
| 262 | if (exp >= level * 20) { |
| 263 | level = level + 1; |
| 264 | player.maxHp = player.maxHp + 5; |
| 265 | player.hp = player.maxHp; |
| 266 | player.attack = player.attack + 2; |
| 267 | showMsg("Level up! You are now level " + level.toString()); |
| 268 | } |
| 269 | } else { |
| 270 | // Enemy counterattack |
| 271 | const eDmg = Math.max(1, npcs[ni].attack - player.defense + randomInt(-1, 1)); |
| 272 | player.hp = player.hp - eDmg; |
| 273 | showMsg(npcs[ni].name + " hits back for " + eDmg.toString() + "!"); |
| 274 | } |
| 275 | } |
| 276 | return; |
| 277 | } |
| 278 | |
| 279 | player.mapX = nx; |
| 280 | player.mapY = ny; |
| 281 | |
| 282 | // Check items |
| 283 | for (let i = 0; i < items.length; i++) { |
| 284 | if (items[i].active && items[i].mapX === nx && items[i].mapY === ny) { |
| 285 | items[i].active = false; |
| 286 | if (items[i].type === ITEM_COIN) { |
| 287 | gold = gold + 10; |
| 288 | showMsg("Found 10 gold!"); |
| 289 | } else if (items[i].type === ITEM_POTION) { |
| 290 | player.hp = Math.min(player.hp + 10, player.maxHp); |
| 291 | showMsg("Used potion! +10 HP"); |
| 292 | } else { |
| 293 | inventory.push(items[i].type); |
| 294 | showMsg("Found " + items[i].name + "!"); |
| 295 | if (items[i].type === ITEM_SWORD) player.attack = player.attack + 3; |
| 296 | if (items[i].type === ITEM_SHIELD) player.defense = player.defense + 2; |
| 297 | } |