PageRenderTime 70ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/Server/src/modPlayer.bas

https://bitbucket.org/Helladen/eclipse-worlds
Visual Basic | 2456 lines | 1824 code | 386 blank | 246 comment | 1 complexity | 5775e0c6f7cd6d22f4d5d59121ca2904 MD5 | raw file
  1. Attribute VB_Name = "modPlayer"
  2. Option Explicit
  3. Sub HandleUseChar(ByVal index As Long)
  4. If Not IsPlaying(index) Then
  5. Call JoinGame(index)
  6. Call AddLog(GetPlayerLogin(index) & "/" & GetPlayerName(index) & " has began playing " & Options.Name & ".", "Player")
  7. Call TextAdd(GetPlayerLogin(index) & "/" & GetPlayerName(index) & " has began playing " & Options.Name & ".")
  8. Call UpdateCaption
  9. End If
  10. End Sub
  11. Sub JoinGame(ByVal index As Long)
  12. Dim i As Long
  13. Dim n As Long
  14. Dim Color As Long
  15. ' Set the flag so we know the person is in the game
  16. TempPlayer(index).InGame = True
  17. ' Update the log
  18. frmServer.lvwInfo.ListItems(index).SubItems(1) = GetPlayerIP(index)
  19. frmServer.lvwInfo.ListItems(index).SubItems(2) = GetPlayerLogin(index)
  20. frmServer.lvwInfo.ListItems(index).SubItems(3) = GetPlayerName(index)
  21. ' Send an ok to client to start receiving in game data
  22. Call SendLogin(index)
  23. TotalPlayersOnline = TotalPlayersOnline + 1
  24. ' Send data
  25. Call SendItems(index)
  26. Call SendAnimations(index)
  27. Call SendNPCs(index)
  28. Call SendShops(index)
  29. Call SendSpells(index)
  30. Call SendResources(index)
  31. Call SendInventory(index)
  32. Call SendWornEquipment(index)
  33. Call SendMapEquipment(index)
  34. Call CheckEquippedItems(index)
  35. Call SendHotbar(index)
  36. Call SendTitles(index)
  37. Call SendMorals(index)
  38. Call SendEmoticons(index)
  39. Call SendQuests(index)
  40. ' Spell Cooldowns
  41. For i = 1 To MAX_PLAYER_SPELLS
  42. If GetPlayerSpell(index, i) > 0 Then
  43. ' Check if the CD has expired
  44. If GetPlayerSpellCD(index, i) - timeGetTime < 1 Then Call SetPlayerSpellCD(index, i, 0)
  45. If GetPlayerSpellCD(index, i) - timeGetTime >= Spell(GetPlayerSpell(index, i)).CDTime * 1000 Then Call SetPlayerSpellCD(index, i, 0)
  46. If GetPlayerSpellCD(index, i) <= timeGetTime Then Call SetPlayerSpellCD(index, i, 0)
  47. ' Send it
  48. Call SendSpellCooldown(index, i)
  49. End If
  50. Next
  51. ' Check for glitches in the inventory
  52. Call UpdatePlayerItems(index)
  53. ' Check for glitches in equipment
  54. Call UpdatePlayerEquipmentItems(index)
  55. ' Send the player's data
  56. Call SendPlayerData(index)
  57. ' Send vitals to player of all other players online
  58. For n = 1 To Player_HighIndex
  59. For i = 1 To Vitals.Vital_Count - 1
  60. If IsPlaying(n) Then
  61. Call SendVitalTo(index, n, i) ' Sends all players to new player
  62. If Not index = n Then
  63. Call SendVitalTo(n, index, i) ' Sends new player to logged in players
  64. End If
  65. End If
  66. Next
  67. Next
  68. ' Send other data
  69. Call SendPlayerStatus(index)
  70. Call SendPlayerExp(index)
  71. ' Warp the player to their saved location
  72. Call PlayerWarp(index, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index), True)
  73. ' Send welcome messages
  74. Call SendWelcome(index)
  75. ' Send Resource cache
  76. For i = 0 To ResourceCache(GetPlayerMap(index)).Resource_Count
  77. SendResourceCacheTo index, i
  78. Next
  79. Call UpdateClassData(index)
  80. ' Send a global message that they joined
  81. If GetPlayerAccess(index) <= STAFF_MODERATOR Then
  82. If Class(GetPlayerClass(index)).Color = Orange Then
  83. Color = RGB(255, 165, 0)
  84. Else
  85. Color = Class(GetPlayerClass(index)).Color
  86. End If
  87. Call GlobalMsg(GetPlayerName(index) & " has joined " & Options.Name & "!", Color)
  88. Else
  89. ' Color for access
  90. Select Case GetPlayerAccess(index)
  91. Case 0
  92. Color = 15
  93. Case 1
  94. Color = 3
  95. Case 2
  96. Color = 2
  97. Case 3
  98. Color = BrightBlue
  99. Case 4
  100. Color = Yellow
  101. Case 5
  102. Color = RGB(255, 165, 0)
  103. End Select
  104. Call GlobalMsg(GetPlayerName(index) & " has joined " & Options.Name & "!", Color)
  105. End If
  106. ' Send the flag so they know they can start doing stuff
  107. Call SendInGame(index)
  108. ' Refresh the friends list to all players online
  109. For i = 1 To Player_HighIndex
  110. Call UpdateFriendsList(i)
  111. Next
  112. ' Refresh the foes list to all players online
  113. For i = 1 To Player_HighIndex
  114. Call UpdateFoesList(i)
  115. Next
  116. ' Update guild list
  117. If GetPlayerGuild(index) > 0 Then
  118. Call SendPlayerGuildMembers(index)
  119. End If
  120. End Sub
  121. Sub LeftGame(ByVal index As Long)
  122. Dim n As Long, i As Long
  123. Dim TradeTarget As Long
  124. If TempPlayer(index).InGame Then
  125. TempPlayer(index).InGame = False
  126. ' Check if player was the only player on the map and stop npc processing if so
  127. If GetTotalMapPlayers(GetPlayerMap(index)) < 1 Then
  128. PlayersOnMap(GetPlayerMap(index)) = NO
  129. End If
  130. ' Clear any invites out
  131. If TempPlayer(index).TradeRequest > 0 Or TempPlayer(index).PartyInvite > 0 Or TempPlayer(index).GuildInvite > 0 Then
  132. If TempPlayer(index).TradeRequest > 0 Then
  133. Call DeclineTradeRequest(index)
  134. End If
  135. If TempPlayer(index).PartyInvite > 0 Then
  136. Call Party_InviteDecline(TempPlayer(index).PartyInvite, index)
  137. End If
  138. If TempPlayer(index).GuildInvite > 0 Then
  139. Call DeclineGuildInvite(index)
  140. End If
  141. End If
  142. ' Cancel any trade they're in
  143. If TempPlayer(index).InTrade > 0 Then
  144. TradeTarget = TempPlayer(index).InTrade
  145. PlayerMsg TradeTarget, Trim$(GetPlayerName(index)) & " has declined the trade!", BrightRed
  146. ' Clear out trade
  147. For i = 1 To MAX_INV
  148. TempPlayer(TradeTarget).TradeOffer(i).Num = 0
  149. TempPlayer(TradeTarget).TradeOffer(i).Value = 0
  150. Next
  151. TempPlayer(TradeTarget).InTrade = 0
  152. SendCloseTrade TradeTarget
  153. End If
  154. ' Leave party
  155. Party_PlayerLeave index
  156. ' Loop through entire map and purge npc targets from player
  157. For i = 1 To Map(GetPlayerMap(index)).NPC_HighIndex
  158. If MapNPC(GetPlayerMap(index)).NPC(i).Num > 0 Then
  159. If MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_PLAYER Then
  160. If MapNPC(GetPlayerMap(index)).NPC(i).target = index Then
  161. MapNPC(GetPlayerMap(index)).NPC(i).target = 0
  162. MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_NONE
  163. Call SendMapNPCTarget(GetPlayerMap(index), i, 0, 0)
  164. End If
  165. End If
  166. End If
  167. Next
  168. ' Refresh guild members
  169. For i = 1 To Player_HighIndex
  170. If IsPlaying(i) Then
  171. If Not i = index Then
  172. If GetPlayerGuild(i) = GetPlayerGuild(index) Then
  173. SendPlayerGuildMembers i, index
  174. End If
  175. End If
  176. End If
  177. Next
  178. ' Send a global message that they left
  179. If GetPlayerAccess(index) <= STAFF_MODERATOR Then
  180. Call GlobalMsg(GetPlayerName(index) & " has left " & Options.Name & "!", Grey)
  181. Else
  182. Call GlobalMsg(GetPlayerName(index) & " has left " & Options.Name & "!", DarkGrey)
  183. End If
  184. Call TextAdd(GetPlayerName(index) & " has disconnected from " & Options.Name & ".")
  185. Call SendLeftGame(index)
  186. TotalPlayersOnline = TotalPlayersOnline - 1
  187. ' Save and clear data
  188. Call SaveAccount(index)
  189. Call ClearAccount(index)
  190. ' Refresh the friends list of all players online
  191. For i = 1 To Player_HighIndex
  192. Call UpdateFriendsList(i)
  193. Next
  194. ' Refresh the foes list of all players online
  195. For i = 1 To Player_HighIndex
  196. Call UpdateFoesList(i)
  197. Next
  198. End If
  199. End Sub
  200. Sub PlayerWarp(ByVal index As Long, ByVal MapNum As Integer, ByVal X As Long, ByVal Y As Long, Optional ByVal NeedMap = False, Optional ByVal Dir As Integer = -1)
  201. Dim ShopNum As Long
  202. Dim OldMap As Long
  203. Dim i As Long
  204. Dim Buffer As clsBuffer
  205. ' Check for subscript out of range
  206. If IsPlaying(index) = False Or MapNum <= 0 Or MapNum > MAX_MAPS Then Exit Sub
  207. ' Check if you are out of bounds
  208. If X > Map(MapNum).MaxX Then X = Map(MapNum).MaxX
  209. If Y > Map(MapNum).MaxY Then Y = Map(MapNum).MaxY
  210. If X < 0 Then X = 0
  211. If Y < 0 Then Y = 0
  212. ' Save old map to send erase player data to
  213. OldMap = GetPlayerMap(index)
  214. If OldMap <> MapNum Then
  215. UpdateMapBlock OldMap, GetPlayerX(index), GetPlayerY(index), False
  216. End If
  217. Call SetPlayerX(index, X)
  218. Call SetPlayerY(index, Y)
  219. UpdateMapBlock MapNum, X, Y, True
  220. ' Set direction
  221. If Dir > -1 Then
  222. Call SetPlayerDir(index, Dir)
  223. End If
  224. ' if same map then just send their co-ordinates
  225. If MapNum = GetPlayerMap(index) And Not NeedMap Then
  226. Call SendPlayerPosition(index)
  227. ' Clear spell casting
  228. ClearAccountSpellBuffer index
  229. Exit Sub
  230. End If
  231. ' Clear events
  232. TempPlayer(index).EventProcessingCount = 0
  233. TempPlayer(index).EventMap.CurrentEvents = 0
  234. ' Clear target
  235. TempPlayer(index).target = 0
  236. TempPlayer(index).targetType = TARGET_TYPE_NONE
  237. SendPlayerTarget index
  238. ' Loop through entire map and purge npc targets from player
  239. For i = 1 To Map(GetPlayerMap(index)).NPC_HighIndex
  240. If MapNPC(GetPlayerMap(index)).NPC(i).Num > 0 Then
  241. If MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_PLAYER Then
  242. If MapNPC(GetPlayerMap(index)).NPC(i).target = index Then
  243. MapNPC(GetPlayerMap(index)).NPC(i).target = 0
  244. MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_NONE
  245. Call SendMapNPCTarget(OldMap, i, 0, 0)
  246. End If
  247. End If
  248. End If
  249. Next
  250. ' Leave the old map
  251. If Not OldMap = MapNum Then
  252. Call SendLeaveMap(index, OldMap)
  253. End If
  254. If Not OldMap = MapNum Then
  255. ' Set the new map
  256. Call SetPlayerMap(index, MapNum)
  257. End If
  258. ' Send player's equipment to new map
  259. SendMapEquipment index
  260. ' Send equipment of all people on new map
  261. If GetTotalMapPlayers(MapNum) > 0 Then
  262. For i = 1 To Player_HighIndex
  263. If IsPlaying(i) Then
  264. If GetPlayerMap(i) = MapNum Then
  265. SendMapEquipmentTo i, index
  266. End If
  267. End If
  268. Next
  269. End If
  270. ' Now we check if there were any players left on the map the player just left, and if not stop processing npcs
  271. If GetTotalMapPlayers(OldMap) = 0 Then
  272. PlayersOnMap(OldMap) = NO
  273. ' Get all NPCs' vitals
  274. For i = 1 To Map(OldMap).NPC_HighIndex
  275. If MapNPC(OldMap).NPC(i).Num > 0 Then
  276. MapNPC(OldMap).NPC(i).Vital(Vitals.HP) = GetNPCMaxVital(MapNPC(OldMap).NPC(i).Num, Vitals.HP)
  277. End If
  278. Next
  279. End If
  280. ' Clear spell casting
  281. ClearAccountSpellBuffer index
  282. ' Sets it so we know to process npcs on the map
  283. PlayersOnMap(MapNum) = YES
  284. TempPlayer(index).GettingMap = YES
  285. Set Buffer = New clsBuffer
  286. Call SendCheckForMap(index, MapNum)
  287. End Sub
  288. Sub PlayerMove(ByVal index As Long, ByVal Dir As Long, ByVal movement As Long, Optional ByVal SendToSelf As Boolean = False)
  289. Dim Buffer As clsBuffer, MapNum As Integer
  290. Dim X As Long, Y As Long, i As Long
  291. Dim Moved As Byte, MovedSoFar As Boolean
  292. Dim TileType As Long, VitalType As Long, Color As Long, Amount As Long
  293. Dim NewMapY As Long, NewMapX As Long
  294. ' Check for subscript out of range
  295. If IsPlaying(index) = False Or Dir < DIR_UP Or Dir > DIR_DOWNRIGHT Or movement < 1 Or movement > 2 Then Exit Sub
  296. ' Don't allow them to move if they are transfering to a new map
  297. If TempPlayer(index).GettingMap = YES Then Exit Sub
  298. ' Don't let them move if an event is waiting for their response
  299. If TempPlayer(index).EventProcessingCount > 0 Then
  300. For i = 1 To TempPlayer(index).EventProcessingCount
  301. If TempPlayer(index).EventProcessing(i).WaitingForResponse > 0 Then
  302. Call SendPlayerPosition(index)
  303. Exit Sub
  304. End If
  305. Next
  306. End If
  307. ' Prevent player from moving if they are casting a spell
  308. If TempPlayer(index).SpellBuffer.Spell > 0 Then Exit Sub
  309. ' If stunned, stop them moving
  310. If TempPlayer(index).StunDuration > 0 Then Exit Sub
  311. Call SetPlayerDir(index, Dir)
  312. Moved = NO
  313. MapNum = GetPlayerMap(index)
  314. Select Case Dir
  315. Case DIR_UPLEFT
  316. ' Check to make sure not outside of boundries
  317. If GetPlayerY(index) > 0 Or GetPlayerX(index) > 0 Then
  318. ' Check to make sure that the tile is walkable
  319. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_UP + 1) And Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_LEFT + 1) Then
  320. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index) - 1).Type <> TILE_TYPE_BLOCKED Then
  321. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index) - 1).Type <> TILE_TYPE_RESOURCE Then
  322. Call SetPlayerY(index, GetPlayerY(index) - 1)
  323. Call SetPlayerX(index, GetPlayerX(index) - 1)
  324. SendPlayerMove index, movement, SendToSelf
  325. Moved = YES
  326. End If
  327. End If
  328. End If
  329. Else
  330. ' Check to see if we can move them to the another map
  331. If Map(GetPlayerMap(index)).Up > 0 And Map(GetPlayerMap(index)).Left > 0 Then
  332. NewMapY = Map(Map(GetPlayerMap(index)).Up).MaxY
  333. Call PlayerWarp(index, Map(GetPlayerMap(index)).Up, GetPlayerX(index), NewMapY)
  334. Moved = YES
  335. ' clear their target
  336. TempPlayer(index).target = 0
  337. TempPlayer(index).targetType = TARGET_TYPE_NONE
  338. SendPlayerTarget index
  339. End If
  340. End If
  341. Case DIR_UPRIGHT
  342. ' Check to make sure not outside of boundries
  343. If GetPlayerY(index) > 0 Or GetPlayerX(index) < Map(MapNum).MaxX Then
  344. ' Check to make sure that the tile is walkable
  345. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_UP + 1) And Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_RIGHT + 1) Then
  346. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index) - 1).Type <> TILE_TYPE_BLOCKED Then
  347. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index) - 1).Type <> TILE_TYPE_RESOURCE Then
  348. Call SetPlayerY(index, GetPlayerY(index) - 1)
  349. Call SetPlayerX(index, GetPlayerX(index) + 1)
  350. SendPlayerMove index, movement, SendToSelf
  351. Moved = YES
  352. End If
  353. End If
  354. End If
  355. Else
  356. ' Check to see if we can move them to the another map
  357. If Map(GetPlayerMap(index)).Up > 0 And Map(GetPlayerMap(index)).Right > 0 Then
  358. NewMapY = Map(Map(GetPlayerMap(index)).Up).MaxY
  359. Call PlayerWarp(index, Map(GetPlayerMap(index)).Up, GetPlayerX(index), NewMapY)
  360. Moved = YES
  361. ' clear their target
  362. TempPlayer(index).target = 0
  363. TempPlayer(index).targetType = TARGET_TYPE_NONE
  364. SendPlayerTarget index
  365. End If
  366. End If
  367. Case DIR_DOWNLEFT
  368. ' Check to make sure not outside of boundries
  369. If GetPlayerY(index) < Map(MapNum).MaxY Or GetPlayerX(index) > 0 Then
  370. ' Check to make sure that the tile is walkable
  371. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_DOWN + 1) And Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_LEFT + 1) Then
  372. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index) + 1).Type <> TILE_TYPE_BLOCKED Then
  373. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index) + 1).Type <> TILE_TYPE_RESOURCE Then
  374. Call SetPlayerY(index, GetPlayerY(index) + 1)
  375. Call SetPlayerX(index, GetPlayerX(index) - 1)
  376. SendPlayerMove index, movement, SendToSelf
  377. Moved = YES
  378. End If
  379. End If
  380. End If
  381. Else
  382. ' Check to see if we can move them to the another map
  383. If Map(GetPlayerMap(index)).Down > 0 And Map(GetPlayerMap(index)).Left > 0 Then
  384. Call PlayerWarp(index, Map(GetPlayerMap(index)).Down, GetPlayerX(index), 0)
  385. Moved = YES
  386. ' clear their target
  387. TempPlayer(index).target = 0
  388. TempPlayer(index).targetType = TARGET_TYPE_NONE
  389. SendPlayerTarget index
  390. End If
  391. End If
  392. Case DIR_DOWNRIGHT
  393. ' Check to make sure not outside of boundries
  394. If GetPlayerY(index) < Map(MapNum).MaxY Or GetPlayerX(index) < Map(MapNum).MaxX Then
  395. ' Check to make sure that the tile is walkable
  396. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_DOWN + 1) And Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_RIGHT + 1) Then
  397. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index) + 1).Type <> TILE_TYPE_BLOCKED Then
  398. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index) + 1).Type <> TILE_TYPE_RESOURCE Then
  399. Call SetPlayerY(index, GetPlayerY(index) + 1)
  400. Call SetPlayerX(index, GetPlayerX(index) + 1)
  401. SendPlayerMove index, movement, SendToSelf
  402. Moved = YES
  403. End If
  404. End If
  405. End If
  406. Else
  407. ' Check to see if we can move them to the another map
  408. If Map(GetPlayerMap(index)).Down > 0 And Map(GetPlayerMap(index)).Right > 0 Then
  409. Call PlayerWarp(index, Map(GetPlayerMap(index)).Down, GetPlayerX(index), 0)
  410. Moved = YES
  411. ' clear their target
  412. TempPlayer(index).target = 0
  413. TempPlayer(index).targetType = TARGET_TYPE_NONE
  414. SendPlayerTarget index
  415. End If
  416. End If
  417. Case DIR_UP
  418. ' Check to make sure not outside of boundries
  419. If GetPlayerY(index) > 0 Then
  420. ' Check to make sure that the tile is walkable
  421. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_UP + 1) Then
  422. If Not IsPlayerBlocked(index, 0, -1) Then
  423. If Not IsEventBlocked(index, 0, -1) Then
  424. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index) - 1).Type <> TILE_TYPE_BLOCKED Then
  425. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index) - 1).Type <> TILE_TYPE_RESOURCE Then
  426. Call SetPlayerY(index, GetPlayerY(index) - 1)
  427. SendPlayerMove index, movement, SendToSelf
  428. Moved = YES
  429. End If
  430. End If
  431. End If
  432. End If
  433. End If
  434. Else
  435. ' Check to see if we can move them to the another map
  436. If Map(GetPlayerMap(index)).Up > 0 Then
  437. Call PlayerWarp(index, Map(GetPlayerMap(index)).Up, GetPlayerX(index), Map(MapNum).MaxY)
  438. Moved = YES
  439. ' Clear their target
  440. TempPlayer(index).target = 0
  441. TempPlayer(index).targetType = TARGET_TYPE_NONE
  442. SendPlayerTarget index
  443. End If
  444. End If
  445. Case DIR_DOWN
  446. ' Check to make sure not outside of boundries
  447. If GetPlayerY(index) < Map(MapNum).MaxY Then
  448. ' Check to make sure that the tile is walkable
  449. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_DOWN + 1) Then
  450. If Not IsPlayerBlocked(index, 0, 1) Then
  451. If Not IsEventBlocked(index, 0, 1) Then
  452. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index) + 1).Type <> TILE_TYPE_BLOCKED Then
  453. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index) + 1).Type <> TILE_TYPE_RESOURCE Then
  454. Call SetPlayerY(index, GetPlayerY(index) + 1)
  455. SendPlayerMove index, movement, SendToSelf
  456. Moved = YES
  457. End If
  458. End If
  459. End If
  460. End If
  461. End If
  462. Else
  463. ' Check to see if we can move them to the another map
  464. If Map(GetPlayerMap(index)).Down > 0 Then
  465. Call PlayerWarp(index, Map(GetPlayerMap(index)).Down, GetPlayerX(index), 0)
  466. Moved = YES
  467. ' Clear their target
  468. TempPlayer(index).target = 0
  469. TempPlayer(index).targetType = TARGET_TYPE_NONE
  470. SendPlayerTarget index
  471. End If
  472. End If
  473. Case DIR_LEFT
  474. ' Check to make sure not outside of boundries
  475. If GetPlayerX(index) > 0 Then
  476. ' Check to make sure that the tile is walkable
  477. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_LEFT + 1) Then
  478. If Not IsPlayerBlocked(index, -1, 0) Then
  479. If Not IsEventBlocked(index, -1, 0) Then
  480. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index)).Type <> TILE_TYPE_BLOCKED Then
  481. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) - 1, GetPlayerY(index)).Type <> TILE_TYPE_RESOURCE Then
  482. Call SetPlayerX(index, GetPlayerX(index) - 1)
  483. SendPlayerMove index, movement, SendToSelf
  484. Moved = YES
  485. End If
  486. End If
  487. End If
  488. End If
  489. End If
  490. Else
  491. ' Check to see if we can move them to the another map
  492. If Map(GetPlayerMap(index)).Left > 0 Then
  493. Call PlayerWarp(index, Map(GetPlayerMap(index)).Left, Map(MapNum).MaxX, GetPlayerY(index))
  494. Moved = YES
  495. ' Clear their target
  496. TempPlayer(index).target = 0
  497. TempPlayer(index).targetType = TARGET_TYPE_NONE
  498. SendPlayerTarget index
  499. End If
  500. End If
  501. Case DIR_RIGHT
  502. ' Check to make sure not outside of boundries
  503. If GetPlayerX(index) < Map(MapNum).MaxX Then
  504. ' Check to make sure that the tile is walkable
  505. If Not IsDirBlocked(Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index)).DirBlock, DIR_RIGHT + 1) Then
  506. If Not IsPlayerBlocked(index, 1, 0) Then
  507. If Not IsEventBlocked(index, 1, 0) Then
  508. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index)).Type <> TILE_TYPE_BLOCKED Then
  509. If Map(GetPlayerMap(index)).Tile(GetPlayerX(index) + 1, GetPlayerY(index)).Type <> TILE_TYPE_RESOURCE Then
  510. Call SetPlayerX(index, GetPlayerX(index) + 1)
  511. SendPlayerMove index, movement, SendToSelf
  512. Moved = YES
  513. End If
  514. End If
  515. End If
  516. End If
  517. End If
  518. Else
  519. ' Check to see if we can move them to the another map
  520. If Map(GetPlayerMap(index)).Right > 0 Then
  521. Call PlayerWarp(index, Map(GetPlayerMap(index)).Right, 0, GetPlayerY(index))
  522. Moved = YES
  523. ' Clear their target
  524. TempPlayer(index).target = 0
  525. TempPlayer(index).targetType = TARGET_TYPE_NONE
  526. SendPlayerTarget index
  527. End If
  528. End If
  529. End Select
  530. With Map(GetPlayerMap(index)).Tile(GetPlayerX(index), GetPlayerY(index))
  531. ' Check to see if the tile is a warp tile, and if so warp them
  532. If .Type = TILE_TYPE_WARP Then
  533. MapNum = .Data1
  534. X = .Data2
  535. Y = .Data3
  536. Call PlayerWarp(index, MapNum, X, Y)
  537. Moved = YES
  538. End If
  539. ' Check for a shop, and if so open it
  540. If .Type = TILE_TYPE_SHOP Then
  541. X = .Data1
  542. If X > 0 Then ' Shop exists?
  543. If Len(Trim$(Shop(X).Name)) > 0 Then ' Name exists?
  544. SendOpenShop index, X
  545. TempPlayer(index).InShop = X ' Stops movement and the like
  546. End If
  547. End If
  548. End If
  549. ' Check to see if the tile is a bank, and if so send bank
  550. If .Type = TILE_TYPE_BANK Then
  551. SendBank index
  552. TempPlayer(index).InBank = True
  553. Moved = YES
  554. End If
  555. ' Check if it's a heal tile
  556. If .Type = TILE_TYPE_HEAL Then
  557. VitalType = .Data1
  558. Amount = .Data2
  559. If VitalType = Int(Vitals.HP) Then
  560. Color = BrightGreen
  561. ElseIf VitalType = Int(Vitals.MP) Then
  562. Color = BrightBlue
  563. End If
  564. If Not GetPlayerVital(index, VitalType) = GetPlayerMaxVital(index, VitalType) Then
  565. If GetPlayerVital(index, VitalType) + Amount > GetPlayerMaxVital(index, VitalType) Then
  566. Amount = GetPlayerMaxVital(index, VitalType) - GetPlayerVital(index, VitalType)
  567. End If
  568. SendActionMsg GetPlayerMap(index), "+" & Amount, Color, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32, 1
  569. SetPlayerVital index, VitalType, GetPlayerVital(index, VitalType) + Amount
  570. Call SendVital(index, VitalType)
  571. Else
  572. SendActionMsg GetPlayerMap(index), "+0", Color, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32, 1
  573. If TempPlayer(index).InParty > 0 Then SendPartyVitals TempPlayer(index).InParty, index
  574. End If
  575. Moved = YES
  576. End If
  577. ' Check if it's a trap tile
  578. If .Type = TILE_TYPE_TRAP Then
  579. VitalType = .Data1
  580. Amount = .Data2
  581. If VitalType = Int(Vitals.HP) Then
  582. Color = BrightRed
  583. ElseIf VitalType = Int(Vitals.MP) Then
  584. Color = Magenta
  585. End If
  586. If Not GetPlayerVital(index, VitalType) < 1 Then
  587. If GetPlayerVital(index, VitalType) - Amount < 1 Then
  588. Amount = GetPlayerVital(index, VitalType)
  589. End If
  590. SendActionMsg GetPlayerMap(index), "-" & Amount, Color, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32, 1
  591. If GetPlayerVital(index, HP) - Amount < 1 And VitalType = 1 Then
  592. KillPlayer index
  593. Call GlobalMsg(GetPlayerName(index) & " has been killed by a trap!", BrightRed)
  594. Else
  595. SetPlayerVital index, VitalType, GetPlayerVital(index, VitalType) - Amount
  596. Call SendVital(index, VitalType)
  597. End If
  598. Else
  599. SetPlayerVital index, HP, GetPlayerVital(index, HP) - Amount
  600. PlayerMsg index, "You're injured by a trap.", BrightRed
  601. Call SendVital(index, HP)
  602. ' Send vitals to party if in one
  603. If TempPlayer(index).InParty > 0 Then SendPartyVitals TempPlayer(index).InParty, index
  604. End If
  605. Moved = YES
  606. End If
  607. ' Checkpoint
  608. If .Type = TILE_TYPE_CHECKPOINT Then
  609. SetCheckpoint index, .Data1, .Data2, .Data3
  610. Moved = YES
  611. End If
  612. ' Slide
  613. If .Type = TILE_TYPE_SLIDE Then
  614. ForcePlayerMove index, MOVING_WALKING, GetPlayerDir(index)
  615. Moved = YES
  616. End If
  617. End With
  618. ' They tried to hack
  619. If Moved = NO Then
  620. Call PlayerWarp(index, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))
  621. Else
  622. X = GetPlayerX(index)
  623. Y = GetPlayerY(index)
  624. If Trim$(Account(index).Chars(GetPlayerChar(index)).Status) = "AFK" Then
  625. Account(index).Chars(GetPlayerChar(index)).Status = vbNullString
  626. Call SendPlayerStatus(index)
  627. End If
  628. ' Check to see if events are touched
  629. EventTouch index, X, Y
  630. End If
  631. End Sub
  632. Sub EventTouch(ByVal index As Long, ByVal X As Long, ByVal Y As Long)
  633. Dim EventTouched As Boolean, i As Long
  634. If TempPlayer(index).EventMap.CurrentEvents > 0 Then
  635. For i = 1 To TempPlayer(index).EventMap.CurrentEvents
  636. If Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Global = 1 Then
  637. If Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).X = X And Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Y = Y And Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Pages(TempPlayer(index).EventMap.EventPages(i).PageID).Trigger = 1 And TempPlayer(index).EventMap.EventPages(i).Visible = 1 Then EventTouched = True
  638. Else
  639. If TempPlayer(index).EventMap.EventPages(i).X = X And TempPlayer(index).EventMap.EventPages(i).Y = Y And Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Pages(TempPlayer(index).EventMap.EventPages(i).PageID).Trigger = 1 And TempPlayer(index).EventMap.EventPages(i).Visible = 1 Then EventTouched = True
  640. End If
  641. If EventTouched Then
  642. ' Process this event, it is on-touch and everything checks out.
  643. If Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Pages(TempPlayer(index).EventMap.EventPages(i).PageID).CommandListCount > 0 Then
  644. TempPlayer(index).EventProcessingCount = TempPlayer(index).EventProcessingCount + 1
  645. ReDim Preserve TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount)
  646. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).ActionTimer = timeGetTime
  647. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).CurList = 1
  648. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).CurSlot = 1
  649. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).eventID = TempPlayer(index).EventMap.EventPages(i).eventID
  650. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).PageID = TempPlayer(index).EventMap.EventPages(i).PageID
  651. TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).WaitingForResponse = 0
  652. ReDim TempPlayer(index).EventProcessing(TempPlayer(index).EventProcessingCount).ListLeftOff(0 To Map(GetPlayerMap(index)).Events(TempPlayer(index).EventMap.EventPages(i).eventID).Pages(TempPlayer(index).EventMap.EventPages(i).PageID).CommandListCount)
  653. End If
  654. EventTouched = False
  655. End If
  656. Next
  657. End If
  658. End Sub
  659. Sub ForcePlayerMove(ByVal index As Long, ByVal movement As Long, ByVal Direction As Long)
  660. If Direction < DIR_UP Or Direction > DIR_DOWNRIGHT Then Exit Sub
  661. If movement < 1 Or movement > 2 Then Exit Sub
  662. Select Case Direction
  663. Case DIR_UP
  664. If GetPlayerY(index) = 0 Then Exit Sub
  665. Case DIR_LEFT
  666. If GetPlayerX(index) = 0 Then Exit Sub
  667. Case DIR_DOWN
  668. If GetPlayerY(index) = Map(GetPlayerMap(index)).MaxY Then Exit Sub
  669. Case DIR_RIGHT
  670. If GetPlayerX(index) = Map(GetPlayerMap(index)).MaxX Then Exit Sub
  671. Case DIR_UPLEFT
  672. If GetPlayerY(index) = 0 And GetPlayerX(index) = 0 Then Exit Sub
  673. Case DIR_UPRIGHT
  674. If GetPlayerY(index) = 0 And GetPlayerX(index) = Map(GetPlayerMap(index)).MaxX Then Exit Sub
  675. Case DIR_DOWNLEFT
  676. If GetPlayerY(index) = Map(GetPlayerMap(index)).MaxY And GetPlayerX(index) = 0 Then Exit Sub
  677. Case DIR_DOWNRIGHT
  678. If GetPlayerY(index) = Map(GetPlayerMap(index)).MaxY And GetPlayerX(index) = Map(GetPlayerMap(index)).MaxX Then Exit Sub
  679. End Select
  680. PlayerMove index, Direction, movement, True
  681. End Sub
  682. Sub CheckEquippedItems(ByVal index As Long)
  683. Dim Slot As Long
  684. Dim ItemNum As Integer
  685. Dim i As Long
  686. ' We want to check incase an admin takes away an object but they had it equipped
  687. For i = 1 To Equipment.Equipment_Count - 1
  688. ItemNum = GetPlayerEquipment(index, i)
  689. If ItemNum > 0 Then
  690. If Not Item(ItemNum).Type = ITEM_TYPE_EQUIPMENT Or Not Item(ItemNum).EquipSlot = i Then SetPlayerEquipment index, 0, i
  691. Else
  692. SetPlayerEquipment index, 0, i
  693. End If
  694. Next
  695. End Sub
  696. Function FindOpenInvSlot(ByVal index As Long, ByVal ItemNum As Long) As Long
  697. Dim i As Long
  698. ' Check for subscript out of range
  699. If IsPlaying(index) = False Or ItemNum <= 0 Or ItemNum > MAX_ITEMS Then Exit Function
  700. If Item(ItemNum).Stackable = 1 Then
  701. ' If currency then check to see if they already have an instance of the item and add it to that
  702. For i = 1 To MAX_INV
  703. If GetPlayerInvItemNum(index, i) = ItemNum Then
  704. FindOpenInvSlot = i
  705. Exit Function
  706. End If
  707. Next
  708. End If
  709. For i = 1 To MAX_INV
  710. ' Try to find an open free slot
  711. If GetPlayerInvItemNum(index, i) = 0 Then
  712. FindOpenInvSlot = i
  713. Exit Function
  714. End If
  715. Next
  716. End Function
  717. Function FindOpenBankSlot(ByVal index As Long, ByVal ItemNum As Integer) As Byte
  718. Dim i As Long
  719. ' Check for subscript out of range
  720. If Not IsPlaying(index) Or ItemNum < 1 Or ItemNum > MAX_ITEMS Then Exit Function
  721. If Not Item(ItemNum).Type = ITEM_TYPE_EQUIPMENT Then
  722. For i = 1 To MAX_BANK
  723. If GetPlayerBankItemNum(index, i) = ItemNum Then
  724. FindOpenBankSlot = i
  725. Exit Function
  726. End If
  727. Next
  728. End If
  729. For i = 1 To MAX_BANK
  730. If GetPlayerBankItemNum(index, i) = 0 Then
  731. FindOpenBankSlot = i
  732. Exit Function
  733. End If
  734. Next
  735. End Function
  736. Function HasItem(ByVal index As Long, ByVal ItemNum As Integer) As Long
  737. Dim i As Long
  738. ' Check for subscript out of range
  739. If IsPlaying(index) = False Or ItemNum < 1 Or ItemNum > MAX_ITEMS Then Exit Function
  740. For i = 1 To MAX_INV
  741. ' Check to see if the player has the item
  742. If GetPlayerInvItemNum(index, i) = ItemNum Then
  743. If Item(ItemNum).Stackable = 1 Then
  744. HasItem = GetPlayerInvItemValue(index, i)
  745. Exit Function
  746. End If
  747. End If
  748. Next
  749. End Function
  750. Function TakeInvItem(ByVal index As Long, ByVal ItemNum As Integer, ByVal ItemVal As Long, Optional Update As Boolean = True) As Boolean
  751. Dim i As Long, II As Long, NPCNum As Long
  752. Dim n As Long
  753. Dim Parse() As String
  754. ' Check for subscript out of range
  755. If IsPlaying(index) = False Or ItemNum <= 0 Or ItemNum > MAX_ITEMS Then Exit Function
  756. For i = 1 To MAX_INV
  757. ' Check to see if the player has the item
  758. If GetPlayerInvItemNum(index, i) = ItemNum Then
  759. If Item(ItemNum).Stackable = 1 Then
  760. ' Is what we are trying to take away more then what they have? If so just set it to zero
  761. If ItemVal >= GetPlayerInvItemValue(index, i) Then
  762. TakeInvItem = True
  763. Else
  764. Call SetPlayerInvItemValue(index, i, GetPlayerInvItemValue(index, i) - ItemVal)
  765. If Update Then Call SendInventoryUpdate(index, i)
  766. 'check quests
  767. For II = 1 To MAX_QUESTS
  768. Parse() = Split(HasQuestItems(index, II, True), "|")
  769. If UBound(Parse()) > 0 Then
  770. NPCNum = Parse(0)
  771. If NPCNum > 0 Then
  772. Call SendShowTaskCompleteOnNPC(index, NPCNum, False)
  773. End If
  774. End If
  775. Next II
  776. Exit Function
  777. End If
  778. Else
  779. TakeInvItem = True
  780. End If
  781. If TakeInvItem Then
  782. Call SetPlayerInvItemNum(index, i, 0)
  783. Call SetPlayerInvItemValue(index, i, 0)
  784. Call SetPlayerInvItemDur(index, i, 0)
  785. Call SetPlayerInvItemBind(index, i, 0)
  786. End If
  787. End If
  788. Next
  789. 'check quests
  790. For II = 1 To MAX_QUESTS
  791. Parse() = Split(HasQuestItems(index, II, True), "|")
  792. If UBound(Parse()) > 0 Then
  793. NPCNum = Parse(0)
  794. If NPCNum > 0 Then
  795. Call SendShowTaskCompleteOnNPC(index, NPCNum, False)
  796. End If
  797. End If
  798. Next II
  799. ' Send the inventory update
  800. If Update Then Call SendInventory(index)
  801. End Function
  802. Function TakeInvSlot(ByVal index As Long, ByVal InvSlot As Byte, ByVal ItemVal As Long, Optional ByVal Update As Boolean = True) As Boolean
  803. Dim i As Long
  804. Dim n As Long
  805. Dim ItemNum As Integer
  806. ' Check for subscript out of range
  807. If IsPlaying(index) = False Or InvSlot < 1 Or InvSlot > MAX_ITEMS Then Exit Function
  808. ItemNum = GetPlayerInvItemNum(index, InvSlot)
  809. ' Prevent subscript out of range
  810. If ItemNum < 1 Then Exit Function
  811. If Item(ItemNum).Stackable = 1 Then
  812. ' Is what we are trying to take away more then what they have? If so just set it to zero
  813. If ItemVal >= GetPlayerInvItemValue(index, InvSlot) Then
  814. TakeInvSlot = True
  815. Else
  816. Call SetPlayerInvItemValue(index, InvSlot, GetPlayerInvItemValue(index, InvSlot) - ItemVal)
  817. ' Send the inventory update
  818. If Update Then
  819. Call SendInventoryUpdate(index, InvSlot)
  820. End If
  821. Exit Function
  822. End If
  823. Else
  824. TakeInvSlot = True
  825. End If
  826. If TakeInvSlot Then
  827. Call SetPlayerInvItemNum(index, InvSlot, 0)
  828. Call SetPlayerInvItemValue(index, InvSlot, 0)
  829. Call SetPlayerInvItemDur(index, InvSlot, 0)
  830. Call SetPlayerInvItemBind(index, InvSlot, 0)
  831. ' Send the inventory update
  832. If Update Then
  833. Call SendInventoryUpdate(index, InvSlot)
  834. End If
  835. End If
  836. End Function
  837. Function GiveInvItem(ByVal index As Long, ByVal ItemNum As Integer, ByVal ItemVal As Long, Optional ByVal ItemDur As Integer = -1, Optional ByVal ItemBind As Integer = 0, Optional ByVal SendUpdate As Boolean = True) As Byte
  838. Dim i As Long, II As Long, NPCNum As Long
  839. ' Check for subscript out of range
  840. If IsPlaying(index) = False Or ItemNum <= 0 Or ItemNum > MAX_ITEMS Then Exit Function
  841. i = FindOpenInvSlot(index, ItemNum)
  842. ' Check to see if inventory is full
  843. If i > 0 And i <= MAX_INV Then
  844. If CDec(GetPlayerInvItemValue(index, i)) + CDec(ItemVal) > 2147483468 Then
  845. Call PlayerMsg(index, "Cannot give it to you - it exceeds maximum limit!", BrightRed)
  846. GiveInvItem = 0
  847. Exit Function
  848. Else
  849. Call SetPlayerInvItemNum(index, i, ItemNum)
  850. Call SetPlayerInvItemValue(index, i, GetPlayerInvItemValue(index, i) + ItemVal)
  851. End If
  852. If Item(GetPlayerInvItemNum(index, i)).Type = ITEM_TYPE_EQUIPMENT Then
  853. If ItemDur = -1 Then
  854. Call SetPlayerInvItemDur(index, i, Item(ItemNum).Data1)
  855. Else
  856. Call SetPlayerInvItemDur(index, i, ItemDur)
  857. End If
  858. End If
  859. If ItemBind = BIND_ON_PICKUP Or Item(GetPlayerInvItemNum(index, i)).BindType = BIND_ON_PICKUP Then
  860. Call SetPlayerInvItemBind(index, i, BIND_ON_PICKUP)
  861. ElseIf ItemBind = BIND_ON_EQUIP Or Item(GetPlayerInvItemNum(index, i)).BindType = BIND_ON_EQUIP Then
  862. Call SetPlayerInvItemBind(index, i, BIND_ON_EQUIP)
  863. Else
  864. Call SetPlayerInvItemBind(index, i, 0)
  865. End If
  866. If SendUpdate Then Call SendInventoryUpdate(index, i)
  867. GiveInvItem = True
  868. 'check quests
  869. For II = 1 To MAX_QUESTS
  870. NPCNum = HasQuestItems(index, II)
  871. If NPCNum > 0 Then
  872. Call SendShowTaskCompleteOnNPC(index, NPCNum, True)
  873. End If
  874. Next II
  875. Else
  876. Call PlayerMsg(index, "Your inventory is full!", BrightRed)
  877. End If
  878. GiveInvItem = i
  879. End Function
  880. Function HasSpell(ByVal index As Long, ByVal SpellNum As Long) As Boolean
  881. Dim i As Long
  882. For i = 1 To MAX_PLAYER_SPELLS
  883. If GetPlayerSpell(index, i) = SpellNum Then
  884. HasSpell = True
  885. Exit Function
  886. End If
  887. Next
  888. End Function
  889. Function FindOpenSpellSlot(ByVal index As Long) As Long
  890. Dim i As Long
  891. For i = 1 To MAX_PLAYER_SPELLS
  892. If GetPlayerSpell(index, i) = 0 Then
  893. FindOpenSpellSlot = i
  894. Exit Function
  895. End If
  896. Next
  897. End Function
  898. Sub PlayerMapGetItem(ByVal index As Long, ByVal i As Long)
  899. Dim n As Long
  900. Dim MapNum As Integer
  901. Dim Msg As String
  902. Dim tempVal As Variant
  903. Dim ItemNum As Long, Value As Long, Dur As Long, Bind As Long
  904. ' Check for subscript out of range
  905. If Not IsPlaying(index) Then Exit Sub
  906. MapNum = GetPlayerMap(index)
  907. ' See if there's even an item here
  908. If (MapItem(MapNum, i).Num > 0) And (MapItem(MapNum, i).Num <= MAX_ITEMS) Then
  909. ' Can we pick the item up?
  910. If CanPlayerPickupItem(index, i) Then
  911. ' Check if item is at the same location as the player
  912. If (MapItem(MapNum, i).X = GetPlayerX(index)) Then
  913. If (MapItem(MapNum, i).Y = GetPlayerY(index)) Then
  914. ItemNum = MapItem(MapNum, i).Num
  915. Value = MapItem(MapNum, i).Value
  916. Dur = MapItem(MapNum, i).Durability
  917. Bind = Item(ItemNum).BindType
  918. If Value > 0 Then
  919. Msg = Value & " " & Trim$(Item(ItemNum).Name)
  920. Else
  921. Msg = Trim$(Item(ItemNum).Name)
  922. End If
  923. 'sure made this a lot simpler than it was, removing roughly 30 lines of code in exchange for 5. It could be done in 1 line
  924. 'but I chose to make it pretty and easy to debug had something went wrong.
  925. Call GiveInvItem(index, ItemNum, Value, Dur, Bind, True)
  926. ' Erase the item from the map
  927. MapItem(MapNum, i).Num = 0
  928. MapItem(MapNum, i).Value = 0
  929. MapItem(MapNum, i).Durability = 0
  930. MapItem(MapNum, i).X = 0
  931. MapItem(MapNum, i).Y = 0
  932. Call SendInventoryUpdate(index, n)
  933. Call SpawnItemSlot(i, 0, 0, 0, GetPlayerMap(index), 0, 0)
  934. SendActionMsg GetPlayerMap(index), Msg, Yellow, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  935. End If
  936. End If
  937. End If
  938. End If
  939. End Sub
  940. Function CanPlayerPickupItem(ByVal index As Long, ByVal MapItemNum As Integer)
  941. Dim MapNum As Integer
  942. MapNum = GetPlayerMap(index)
  943. ' Check for subscript out of range
  944. If MapNum < 1 Or MapNum > MAX_MAPS Then Exit Function
  945. If Moral(Map(MapNum).Moral).CanPickupItem = 1 Then
  946. ' No lock or locked to player?
  947. If Trim$(MapItem(MapNum, MapItemNum).playerName) = vbNullString Or Trim$(MapItem(MapNum, MapItemNum).playerName) = GetPlayerName(index) Then
  948. CanPlayerPickupItem = True
  949. Exit Function
  950. End If
  951. End If
  952. End Function
  953. Sub PlayerMapDropItem(ByVal index As Long, ByVal InvNum As Byte, ByVal Amount As Long)
  954. Dim i As Long
  955. Dim Msg As String
  956. If (GetPlayerInvItemNum(index, InvNum) <= MAX_ITEMS) Then
  957. i = FindOpenMapItemSlot(GetPlayerMap(index))
  958. If Not i = 0 Then
  959. MapItem(GetPlayerMap(index), i).Num = GetPlayerInvItemNum(index, InvNum)
  960. MapItem(GetPlayerMap(index), i).X = GetPlayerX(index)
  961. MapItem(GetPlayerMap(index), i).Y = GetPlayerY(index)
  962. MapItem(GetPlayerMap(index), i).playerName = Trim$(GetPlayerName(index))
  963. MapItem(GetPlayerMap(index), i).PlayerTimer = timeGetTime + ITEM_SPAWN_TIME
  964. MapItem(GetPlayerMap(index), i).CanDespawn = True
  965. MapItem(GetPlayerMap(index), i).DespawnTimer = timeGetTime + ITEM_DESPAWN_TIME
  966. If Item(GetPlayerInvItemNum(index, InvNum)).Type = ITEM_TYPE_EQUIPMENT Then
  967. MapItem(GetPlayerMap(index), i).Durability = GetPlayerInvItemDur(index, InvNum)
  968. Else
  969. MapItem(GetPlayerMap(index), i).Durability = 0
  970. End If
  971. If Item(GetPlayerInvItemNum(index, InvNum)).Stackable = 1 Then
  972. ' Check if its more then they have and if so drop it all
  973. If Amount >= GetPlayerInvItemValue(index, InvNum) Then
  974. MapItem(GetPlayerMap(index), i).Value = GetPlayerInvItemValue(index, InvNum)
  975. Msg = GetPlayerInvItemValue(index, InvNum) & " " & Trim$(Item(GetPlayerInvItemNum(index, InvNum)).Name)
  976. Call TakeInvSlot(index, InvNum, GetPlayerInvItemValue(index, InvNum), True)
  977. Else
  978. MapItem(GetPlayerMap(index), i).Value = Amount
  979. Msg = Amount & " " & Trim$(Item(GetPlayerInvItemNum(index, InvNum)).Name)
  980. Call TakeInvSlot(index, InvNum, Amount, True)
  981. End If
  982. Else
  983. ' It's not a currency object so this is easy
  984. Msg = Trim$(Item(GetPlayerInvItemNum(index, InvNum)).Name)
  985. MapItem(GetPlayerMap(index), i).Value = 0
  986. Call TakeInvSlot(index, InvNum, Amount, True)
  987. End If
  988. ' Send message
  989. SendActionMsg GetPlayerMap(index), Msg, BrightRed, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  990. ' Spawn the item before we set the num or we'll get a different free map item slot
  991. Call SpawnItemSlot(i, MapItem(GetPlayerMap(index), i).Num, Amount, MapItem(GetPlayerMap(index), i).Durability, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))
  992. Else
  993. Call PlayerMsg(index, "There are too many items on the ground to drop anything else.", BrightRed)
  994. End If
  995. End If
  996. End Sub
  997. Sub CheckPlayerLevelUp(ByVal index As Long)
  998. Dim i As Long
  999. Dim ExpRollOver As Long
  1000. Dim Level_Count As Long
  1001. If GetPlayerLevel(index) > 0 And GetPlayerLevel(index) < MAX_LEVEL Then
  1002. Do While GetPlayerExp(index) >= GetPlayerNextLevel(index)
  1003. ExpRollOver = GetPlayerExp(index) - GetPlayerNextLevel(index)
  1004. Call SetPlayerLevel(index, GetPlayerLevel(index) + 1)
  1005. Call SetPlayerPoints(index, GetPlayerPoints(index) + STATS_LEVEL)
  1006. Call SetPlayerExp(index, ExpRollOver)
  1007. Level_Count = Level_Count + 1
  1008. Loop
  1009. If Level_Count > 0 Then
  1010. SendActionMsg GetPlayerMap(index), "Level Up", Yellow, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  1011. SendPlayerExp index
  1012. If Level_Count > 1 Then
  1013. Call GlobalMsg(GetPlayerName(index) & " has gained " & Level_Count & " levels!", Yellow)
  1014. Else
  1015. Call GlobalMsg(GetPlayerName(index) & " has gained a level!", Yellow)
  1016. End If
  1017. ' Restore and send vitals
  1018. For i = 1 To Vitals.Vital_Count - 1
  1019. Call SetPlayerVital(index, i, GetPlayerMaxVital(index, i))
  1020. Call SendVital(index, i)
  1021. Next
  1022. ' Check for new title
  1023. Call CheckPlayerNewTitle(index)
  1024. ' Check if any of the player's spells can rank up
  1025. For i = 1 To MAX_PLAYER_SPELLS
  1026. If GetPlayerSpell(index, i) > 0 Then
  1027. If Spell(GetPlayerSpell(index, i)).NewSpell > 0 Then
  1028. If Spell(Spell(GetPlayerSpell(index, i)).NewSpell).CastRequired > 0 Then
  1029. Call CheckSpellRankUp(index, GetPlayerSpell(index, i), i)
  1030. End If
  1031. End If
  1032. End If
  1033. Next
  1034. ' Send other data
  1035. Call SendPlayerStats(index)
  1036. Call SendPlayerPoints(index)
  1037. Call SendPlayerLevel(index)
  1038. End If
  1039. End If
  1040. End Sub
  1041. Sub CheckPlayerSkillLevelUp(ByVal index As Long, ByVal SkillNum As Byte)
  1042. Dim ExpRollOver As Long
  1043. Dim Level_Count As Long
  1044. Level_Count = 0
  1045. If GetPlayerSkill(index, SkillNum) > 0 And GetPlayerSkill(index, SkillNum) < MAX_LEVEL Then
  1046. Do While GetPlayerSkillExp(index, SkillNum) >= GetPlayerNextSkillLevel(index, SkillNum)
  1047. ExpRollOver = GetPlayerSkillExp(index, SkillNum) - GetPlayerNextSkillLevel(index, SkillNum)
  1048. Call SetPlayerSkill(index, GetPlayerSkill(index, SkillNum) + 1, SkillNum)
  1049. Call SetPlayerSkillExp(index, ExpRollOver, SkillNum)
  1050. Level_Count = Level_Count + 1
  1051. Loop
  1052. If Level_Count > 0 Then
  1053. SendActionMsg GetPlayerMap(index), "Level Up", Yellow, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  1054. Call PlayerMsg(index, "Your " & CheckGrammar(GetSkillName(SkillNum)) & " level is now " & GetPlayerSkill(index, SkillNum) & ".", BrightGreen)
  1055. End If
  1056. End If
  1057. End Sub
  1058. Private Function AutoLife(ByVal index As Long) As Boolean
  1059. Dim i As Byte
  1060. For i = 1 To MAX_INV
  1061. If GetPlayerInvItemNum(index, i) > 0 Then
  1062. If Item(GetPlayerInvItemNum(index, i)).Type = ITEM_TYPE_AUTOLIFE Then
  1063. If CanPlayerUseItem(index, GetPlayerInvItemNum(index, i), False) Then
  1064. ' HP
  1065. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddHP > 0 Then
  1066. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddHP > GetPlayerMaxVital(index, HP) Then
  1067. SendActionMsg GetPlayerMap(index), "+" & GetPlayerMaxVital(index, HP), BrightGreen, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1068. Else
  1069. SendActionMsg GetPlayerMap(index), "+" & Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddHP, BrightGreen, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1070. End If
  1071. Call SetPlayerVital(index, Vitals.HP, GetPlayerVital(index, Vitals.HP) + Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddHP)
  1072. Call SendVital(index, Vitals.HP)
  1073. End If
  1074. ' MP
  1075. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddMP > 0 Then
  1076. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddMP > GetPlayerMaxVital(index, MP) Then
  1077. SendActionMsg GetPlayerMap(index), "+" & GetPlayerMaxVital(index, MP), BrightBlue, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1078. Else
  1079. SendActionMsg GetPlayerMap(index), "+" & Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddMP, BrightBlue, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1080. End If
  1081. Call SendVital(index, Vitals.MP)
  1082. Call SetPlayerVital(index, Vitals.MP, GetPlayerVital(index, Vitals.MP) + Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).AddMP)
  1083. End If
  1084. ' If it is not reusable then take the item away
  1085. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).IsReusable = False Then
  1086. Call TakeInvItem(index, Account(index).Chars(GetPlayerChar(index)).Inv(i).Num, 0)
  1087. End If
  1088. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, i)).Animation, 0, 0, TARGET_TYPE_PLAYER, index)
  1089. ' Warp player away
  1090. If Item(Account(index).Chars(GetPlayerChar(index)).Inv(i).Num).Data1 = 1 Then
  1091. Call WarpPlayer(index)
  1092. End If
  1093. Call PlayerMsg(index, "You have been given another life!", Yellow)
  1094. AutoLife = True
  1095. Exit Function
  1096. End If
  1097. End If
  1098. End If
  1099. Next
  1100. End Function
  1101. Sub OnDeath(ByVal index As Long, Optional ByVal Attacker As Long)
  1102. Dim i As Long, RemoveItem As Boolean
  1103. ' Set HP to 0
  1104. Call SetPlayerVital(index, Vitals.HP, 0)
  1105. ' Exit out if they were saved
  1106. If AutoLife(index) Then Exit Sub
  1107. ' If map moral can drop items or not
  1108. If Moral(Map(GetPlayerMap(index)).Moral).DropItems = 1 Or GetPlayerPK(index) = PLAYER_KILLER Or (GetPlayerPK(index) = PLAYER_DEFENDER And GetPlayerPK(Attacker) = PLAYER_KILLER) Then
  1109. If GetPlayerPK(index) <> NO Then
  1110. Call SetPlayerPK(index, NO)
  1111. Call SendPlayerPK(index)
  1112. End If
  1113. ' Drop all worn items
  1114. For i = 1 To Equipment.Equipment_Count - 1
  1115. RemoveItem = False
  1116. If GetPlayerEquipment(index, i) > 0 Then
  1117. If TempPlayer(index).InParty > 0 Then
  1118. Call Party_GetLoot(TempPlayer(Attacker).InParty, GetPlayerEquipment(index, i), 1, GetPlayerX(index), GetPlayerY(index))
  1119. RemoveItem = True
  1120. Else
  1121. If Moral(GetPlayerMap(index)).CanDropItem = 1 Then
  1122. If Attacker > 0 Then
  1123. Call SpawnItem(GetPlayerEquipment(index, i), 1, 0, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index), GetPlayerName(Attacker))
  1124. RemoveItem = True
  1125. Else
  1126. Call SpawnItem(GetPlayerEquipment(index, i), 1, 0, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index))
  1127. RemoveItem = True
  1128. End If
  1129. Else
  1130. If Attacker > 0 Then
  1131. Call GiveInvItem(Attacker, GetPlayerEquipment(index, i), 1)
  1132. RemoveItem = True
  1133. End If
  1134. End If
  1135. End If
  1136. ' Remove equipment item
  1137. If RemoveItem Then
  1138. ' Send a message to the world indicating that they dropped an item
  1139. Call GlobalMsg(GetPlayerName(index) & " drops " & CheckGrammar(Trim$(Item(GetPlayerEquipment(index, i)).Name)) & "!", Yellow)
  1140. SetPlayerEquipment index, 0, i
  1141. SetPlayerEquipmentDur index, 0, i
  1142. SetPlayerEquipmentBind index, 0, i
  1143. End If
  1144. End If
  1145. Next
  1146. ' Drop 10% of their Gold
  1147. For i = 1 To MAX_INV
  1148. If GetPlayerInvItemNum(index, i) = 1 Then
  1149. If Round(GetPlayerInvItemValue(index, i) / 10) > 0 Then
  1150. Call TakeInvItem(index, GetPlayerInvItemNum(index, i), Round(GetPlayerInvItemValue(index, i) / 10))
  1151. Call SpawnItem(1, Round(GetPlayerInvItemValue(index, i) / 10), 0, GetPlayerMap(index), GetPlayerX(index), GetPlayerY(index), GetPlayerName(Attacker))
  1152. Exit For
  1153. End If
  1154. End If
  1155. Next
  1156. ' Add the player kill
  1157. If Attacker > 0 Then Account(FindPlayer(GetPlayerName(Attacker))).Chars(GetPlayerChar(i)).PlayerKills = Account(FindPlayer(GetPlayerName(Attacker))).Chars(GetPlayerChar(i)).PlayerKills + 1
  1158. ' Check for new title
  1159. Call CheckPlayerNewTitle(index)
  1160. End If
  1161. ' Loop through entire map and purge npc targets from player
  1162. For i = 1 To Map(GetPlayerMap(index)).NPC_HighIndex
  1163. If MapNPC(GetPlayerMap(index)).NPC(i).Num > 0 Then
  1164. If MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_PLAYER Then
  1165. If MapNPC(GetPlayerMap(index)).NPC(i).target = index Then
  1166. MapNPC(GetPlayerMap(index)).NPC(i).target = 0
  1167. MapNPC(GetPlayerMap(index)).NPC(i).targetType = TARGET_TYPE_NONE
  1168. Call SendMapNPCTarget(GetPlayerMap(index), i, 0, 0)
  1169. End If
  1170. End If
  1171. End If
  1172. Next
  1173. ' Set player direction
  1174. Call SetPlayerDir(index, DIR_DOWN)
  1175. ' Warp away player
  1176. Call WarpPlayer(index)
  1177. ' Clear all DoTs and HoTs
  1178. For i = 1 To MAX_DOTS
  1179. With TempPlayer(index).DoT(i)
  1180. .Used = False
  1181. .Spell = 0
  1182. .Timer = 0
  1183. .Caster = 0
  1184. .StartTime = 0
  1185. End With
  1186. With TempPlayer(index).HoT(i)
  1187. .Used = False
  1188. .Spell = 0
  1189. .Timer = 0
  1190. .Caster = 0
  1191. .StartTime = 0
  1192. End With
  1193. Next
  1194. ' Clear spell casting
  1195. Call ClearAccountSpellBuffer(index)
  1196. ' Restore vitals
  1197. Call SetPlayerVital(index, Vitals.HP, GetPlayerMaxVital(index, Vitals.HP))
  1198. Call SetPlayerVital(index, Vitals.MP, GetPlayerMaxVital(index, Vitals.MP))
  1199. ' Send vitals to party if in one
  1200. If TempPlayer(index).InParty > 0 Then SendPartyVitals TempPlayer(index).InParty, index
  1201. ' Send vitals
  1202. For i = 1 To Vitals.Vital_Count - 1
  1203. Call SendVital(index, i)
  1204. Next
  1205. End Sub
  1206. Private Sub WarpPlayer(ByVal index As Long)
  1207. With Map(GetPlayerMap(index))
  1208. If .BootMap = 0 Then
  1209. ' Warp to the checkpoint
  1210. Call WarpToCheckPoint(index)
  1211. Else
  1212. ' Warp to the boot map
  1213. If .BootMap > 0 And .BootMap <= MAX_MAPS Then
  1214. PlayerWarp index, .BootMap, .BootX, .BootY
  1215. Else
  1216. ' Warp to the start map
  1217. Call PlayerWarp(index, Class(GetPlayerClass(index)).Map, Class(GetPlayerClass(index)).X, Class(GetPlayerClass(index)).Y, False, Class(GetPlayerClass(index)).Dir)
  1218. End If
  1219. End If
  1220. End With
  1221. End Sub
  1222. Sub CheckResource(ByVal index As Long, ByVal X As Long, ByVal Y As Long)
  1223. Dim Resource_Num As Long
  1224. Dim Resource_Index As Long
  1225. Dim rX As Long, rY As Long
  1226. Dim i As Long
  1227. Dim Damage As Long
  1228. Dim RndNum As Long
  1229. If Map(GetPlayerMap(index)).Tile(X, Y).Type = TILE_TYPE_RESOURCE Then
  1230. Resource_Num = 0
  1231. Resource_Index = Map(GetPlayerMap(index)).Tile(X, Y).Data1
  1232. ' Get the cache number
  1233. For i = 0 To ResourceCache(GetPlayerMap(index)).Resource_Count
  1234. If ResourceCache(GetPlayerMap(index)).ResourceData(i).X = X Then
  1235. If ResourceCache(GetPlayerMap(index)).ResourceData(i).Y = Y Then
  1236. Resource_Num = i
  1237. End If
  1238. End If
  1239. Next
  1240. If Resource_Num > 0 Then
  1241. ' Check if they meet the level required
  1242. If Resource(Resource_Index).LevelReq > 0 Then
  1243. If GetPlayerSkill(index, Resource(Resource_Index).Skill) < Resource(Resource_Index).LevelReq Then
  1244. Call PlayerMsg(index, "Your " & CheckGrammar(GetSkillName(Resource(Resource_Index).LevelReq)) & " skill level does not meet the requirement to use this resource!", BrightRed)
  1245. Exit Sub
  1246. End If
  1247. End If
  1248. ' Check if they have the right tool
  1249. If Resource(Resource_Index).ToolRequired > 0 Then
  1250. If GetPlayerEquipment(index, Weapon) < 1 Then
  1251. PlayerMsg index, "You need a tool to interact with this resource!", BrightRed
  1252. Exit Sub
  1253. End If
  1254. If Item(GetPlayerEquipment(index, Weapon)).Tool <> Resource(Resource_Index).ToolRequired Then
  1255. PlayerMsg index, "You have the wrong type of item equipped to use this resource!", BrightRed
  1256. Exit Sub
  1257. End If
  1258. End If
  1259. ' Enough space in inventory?
  1260. If Resource(Resource_Index).ItemReward > 0 Then
  1261. If FindOpenInvSlot(index, Resource(Resource_Index).ItemReward) = 0 Then
  1262. PlayerMsg index, "You do not have enough inventory space!", BrightRed
  1263. Exit Sub
  1264. End If
  1265. End If
  1266. ' Check if the resource has already been deplenished
  1267. If ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).ResourceState = 0 Then
  1268. rX = ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).X
  1269. rY = ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).Y
  1270. ' Reduce weapon's durability
  1271. Call DamagePlayerEquipment(index, Equipment.Weapon)
  1272. ' Give the reward random when they deal damage
  1273. RndNum = Random(Resource(Resource_Index).LowChance, Resource(Resource_Index).HighChance)
  1274. If Not RndNum = Resource(Resource_Index).LowChance Then
  1275. ' Subtract the RndNum by the random value of the weapon's chance modifier
  1276. RndNum = RndNum - Round(Random((Item(GetPlayerEquipment(index, Weapon)).ChanceModifier / 2), Item(GetPlayerEquipment(index, Weapon)).ChanceModifier))
  1277. ' If value is less than the resource low chance then set it to it
  1278. If RndNum < Resource(Resource_Index).LowChance Then
  1279. RndNum = Resource(Resource_Index).LowChance
  1280. End If
  1281. End If
  1282. If RndNum = Resource(Resource_Index).LowChance Then
  1283. ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).Cur_Reward = ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).Cur_Reward - 1
  1284. GiveInvItem index, Resource(Resource_Index).ItemReward, 1
  1285. If GetPlayerSkill(index, Resource(Resource_Index).Skill) < MAX_LEVEL Then
  1286. ' Add the experience to the skill
  1287. Call SetPlayerSkillExp(index, GetPlayerSkillExp(index, Resource(Resource_Index).Skill) + Resource(Resource_Index).Exp * EXP_RATE, Resource(Resource_Index).Skill)
  1288. ' Check for skill level up
  1289. Call CheckPlayerSkillLevelUp(index, Resource(Resource_Index).Skill)
  1290. End If
  1291. ' Send message if it exists
  1292. If Len(Trim$(Resource(Resource_Index).SuccessMessage)) > 0 Then
  1293. SendActionMsg GetPlayerMap(index), Trim$(Resource(Resource_Index).SuccessMessage), BrightGreen, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  1294. End If
  1295. ' If the resource is empty then clear it
  1296. If ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).Cur_Reward = 0 Then
  1297. ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).ResourceState = 1
  1298. ResourceCache(GetPlayerMap(index)).ResourceData(Resource_Num).ResourceTimer = timeGetTime
  1299. SendResourceCacheToMap GetPlayerMap(index), Resource_Num
  1300. End If
  1301. Else
  1302. ' Send message if it exists
  1303. If Len(Trim$(Resource(Resource_Index).FailMessage)) > 0 Then
  1304. SendActionMsg GetPlayerMap(index), Trim$(Resource(Resource_Index).FailMessage), BrightRed, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  1305. End If
  1306. End If
  1307. SendAnimation GetPlayerMap(index), Resource(Resource_Index).Animation, rX, rY
  1308. ' Send the sound
  1309. SendMapSound GetPlayerMap(index), index, rX, rY, SoundEntity.seResource, Resource_Index
  1310. Else
  1311. ' Send message if it exists
  1312. If Len(Trim$(Resource(Resource_Index).EmptyMessage)) > 0 Then
  1313. SendActionMsg GetPlayerMap(index), Trim$(Resource(Resource_Index).EmptyMessage), BrightRed, 1, (GetPlayerX(index) * 32), (GetPlayerY(index) * 32)
  1314. Exit Sub
  1315. End If
  1316. End If
  1317. End If
  1318. End If
  1319. End Sub
  1320. Sub GiveBankItem(ByVal index As Long, ByVal InvSlot As Byte, ByVal Amount As Long, Optional ByVal Durability As Integer = 0)
  1321. Dim BankSlot
  1322. BankSlot = FindOpenBankSlot(index, GetPlayerInvItemNum(index, InvSlot))
  1323. If BankSlot > 0 Then
  1324. If Item(GetPlayerInvItemNum(index, InvSlot)).Stackable = 1 Then
  1325. If GetPlayerBankItemNum(index, BankSlot) = GetPlayerInvItemNum(index, InvSlot) Then
  1326. Call SetPlayerBankItemValue(index, BankSlot, GetPlayerBankItemValue(index, BankSlot) + Amount)
  1327. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvSlot), Amount)
  1328. Else
  1329. Call SetPlayerBankItemNum(index, BankSlot, GetPlayerInvItemNum(index, InvSlot))
  1330. Call SetPlayerBankItemValue(index, BankSlot, Amount)
  1331. Call SetPlayerBankItemBind(index, BankSlot, GetPlayerInvItemBind(index, InvSlot))
  1332. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvSlot), Amount)
  1333. End If
  1334. Else
  1335. If GetPlayerBankItemNum(index, BankSlot) = GetPlayerInvItemNum(index, InvSlot) And Not Item(GetPlayerInvItemNum(index, InvSlot)).Type = ITEM_TYPE_EQUIPMENT Then
  1336. Call SetPlayerBankItemValue(index, BankSlot, GetPlayerBankItemValue(index, BankSlot) + 1)
  1337. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvSlot), 0)
  1338. Else
  1339. Call SetPlayerBankItemNum(index, BankSlot, GetPlayerInvItemNum(index, InvSlot))
  1340. Call SetPlayerBankItemValue(index, BankSlot, 1)
  1341. Call SetPlayerBankItemBind(index, BankSlot, GetPlayerInvItemBind(index, InvSlot))
  1342. Call SetPlayerBankItemDur(index, BankSlot, Durability)
  1343. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvSlot), 0)
  1344. End If
  1345. End If
  1346. End If
  1347. ' Send update
  1348. SaveAccount index
  1349. SendBank index
  1350. End Sub
  1351. Sub TakeBankItem(ByVal index As Long, ByVal BankSlot As Byte, ByVal Amount As Long)
  1352. Dim InvSlot
  1353. If BankSlot < 1 Or BankSlot > MAX_BANK Then Exit Sub
  1354. ' Hack prevention
  1355. If Item(GetPlayerBankItemNum(index, BankSlot)).Stackable = 1 Then
  1356. If GetPlayerBankItemValue(index, BankSlot) < Amount Then Amount = GetPlayerBankItemValue(index, BankSlot)
  1357. If Amount < 1 Then Exit Sub
  1358. Else
  1359. If Not Amount = 1 Then Exit Sub
  1360. End If
  1361. InvSlot = FindOpenInvSlot(index, GetPlayerBankItemNum(index, BankSlot))
  1362. If InvSlot > 0 Then
  1363. If Item(GetPlayerBankItemNum(index, BankSlot)).Stackable = 1 Then
  1364. Call GiveInvItem(index, GetPlayerBankItemNum(index, BankSlot), Amount)
  1365. Call SetPlayerBankItemValue(index, BankSlot, GetPlayerBankItemValue(index, BankSlot) - Amount)
  1366. If GetPlayerBankItemValue(index, BankSlot) <= 0 Then
  1367. Call SetPlayerBankItemNum(index, BankSlot, 0)
  1368. Call SetPlayerBankItemValue(index, BankSlot, 0)
  1369. Call SetPlayerBankItemBind(index, BankSlot, 0)
  1370. End If
  1371. Else
  1372. If GetPlayerBankItemValue(index, BankSlot) > 1 Then
  1373. Call GiveInvItem(index, GetPlayerBankItemNum(index, BankSlot), 0)
  1374. Call SetPlayerBankItemValue(index, BankSlot, GetPlayerBankItemValue(index, BankSlot) - 1)
  1375. Else
  1376. Call GiveInvItem(index, GetPlayerBankItemNum(index, BankSlot), 0, GetPlayerBankItemDur(index, BankSlot), GetPlayerBankItemBind(index, BankSlot))
  1377. Call SetPlayerBankItemNum(index, BankSlot, 0)
  1378. Call SetPlayerBankItemValue(index, BankSlot, 0)
  1379. Call SetPlayerBankItemDur(index, BankSlot, 0)
  1380. Call SetPlayerBankItemBind(index, BankSlot, 0)
  1381. End If
  1382. End If
  1383. End If
  1384. SaveAccount index
  1385. SendBank index
  1386. End Sub
  1387. Public Sub KillPlayer(ByVal index As Long)
  1388. Dim Exp As Long
  1389. ' Calculate exp to give to attacker
  1390. Exp = GetPlayerExp(index) \ 4
  1391. ' Randomize
  1392. Exp = Random(Exp * 0.95, Exp * 1.05)
  1393. ' Make sure the exp we get isn't less than 0
  1394. If Exp < 0 Then Exp = 0
  1395. If Exp = 0 Or Moral(Map(GetPlayerMap(index)).Moral).LoseExp = 0 Then
  1396. Call PlayerMsg(index, "You did not lose any experience.", Grey)
  1397. ElseIf GetPlayerLevel(index) < MAX_LEVEL Then
  1398. Call SetPlayerExp(index, GetPlayerExp(index) - Exp)
  1399. SendPlayerExp index
  1400. Call PlayerMsg(index, "You lost " & Exp & " experience.", Grey)
  1401. End If
  1402. Call OnDeath(index)
  1403. End Sub
  1404. Public Sub UseItem(ByVal index As Long, ByVal InvNum As Byte)
  1405. Dim n As Long, i As Long, X As Long, Y As Long, TotalPoints As Integer, EquipSlot As Byte
  1406. Dim Item1 As Long
  1407. Dim Item2 As Long
  1408. Dim Result As Long
  1409. Dim Skill As Byte
  1410. Dim SkillExp As Integer
  1411. Dim SkillLevelReq As Byte
  1412. Dim ToolReq As Long
  1413. ' Check subscript out of range
  1414. If InvNum < 1 Or InvNum > MAX_INV Then Exit Sub
  1415. ' Check if they can use the item
  1416. If Not CanPlayerUseItem(index, GetPlayerInvItemNum(index, InvNum)) Then Exit Sub
  1417. n = Item(GetPlayerInvItemNum(index, InvNum)).Data2
  1418. ' Set the bind
  1419. If Item(GetPlayerInvItemNum(index, InvNum)).Type = ITEM_TYPE_EQUIPMENT Then
  1420. If Item(GetPlayerInvItemNum(index, InvNum)).BindType = BIND_ON_EQUIP Then
  1421. Call SetPlayerInvItemBind(index, InvNum, BIND_ON_PICKUP)
  1422. End If
  1423. End If
  1424. ' Find out what kind of item it is
  1425. Select Case Item(GetPlayerInvItemNum(index, InvNum)).Type
  1426. Case ITEM_TYPE_EQUIPMENT
  1427. EquipSlot = Item(GetPlayerInvItemNum(index, InvNum)).EquipSlot
  1428. If EquipSlot >= 1 And EquipSlot <= Equipment_Count - 1 Then
  1429. If GetPlayerInvItemDur(index, InvNum) > 0 Or Item(GetPlayerInvItemNum(index, InvNum)).Indestructable = 1 Then
  1430. Call PlayerUnequipItem(index, EquipSlot, False, False, True)
  1431. PlayerMsg index, "You equip " & CheckGrammar(Trim$(Item(GetPlayerInvItemNum(index, InvNum)).Name)) & ".", BrightGreen
  1432. SetPlayerEquipment index, GetPlayerInvItemNum(index, InvNum), EquipSlot
  1433. SetPlayerEquipmentDur index, GetPlayerInvItemDur(index, InvNum), EquipSlot
  1434. SetPlayerEquipmentBind index, GetPlayerInvItemBind(index, InvNum), EquipSlot
  1435. TakeInvSlot index, InvNum, 0, True
  1436. ' Send update
  1437. SendInventoryUpdate index, InvNum
  1438. Call SendWornEquipment(index)
  1439. Call SendMapEquipment(index)
  1440. SendPlayerStats index
  1441. ' Send vitals
  1442. For i = 1 To Vitals.Vital_Count - 1
  1443. Call SendVital(index, i)
  1444. Next
  1445. ' Send vitals to party if in one
  1446. If TempPlayer(index).InParty > 0 Then SendPartyVitals TempPlayer(index).InParty, index
  1447. ' Send the sound
  1448. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1449. Else
  1450. Call PlayerMsg(index, "The item you are trying to equip is broken!", 12)
  1451. End If
  1452. End If
  1453. Case ITEM_TYPE_CONSUME
  1454. If GetPlayerLevel(index) = MAX_LEVEL And Item(GetPlayerInvItemNum(index, InvNum)).AddEXP > 0 Then
  1455. Call PlayerMsg(index, "You can't use items which modify your experience when your at the max level!", BrightRed)
  1456. Exit Sub
  1457. End If
  1458. ' Add HP
  1459. If Item(GetPlayerInvItemNum(index, InvNum)).AddHP > 0 Then
  1460. If Not GetPlayerVital(index, HP) = GetPlayerMaxVital(index, HP) Then
  1461. If TempPlayer(index).VitalPotionTimer(HP) > timeGetTime Then
  1462. Call PlayerMsg(index, "You must wait before you can use another potion that modifies your health!", BrightRed)
  1463. Exit Sub
  1464. Else
  1465. If Item(GetPlayerInvItemNum(index, InvNum)).HoT = 1 Then
  1466. TempPlayer(index).VitalCycle(HP) = Item(GetPlayerInvItemNum(index, InvNum)).Data1
  1467. TempPlayer(index).VitalPotion(HP) = GetPlayerInvItemNum(index, InvNum)
  1468. TempPlayer(index).VitalPotionTimer(HP) = timeGetTime + (Item(GetPlayerInvItemNum(index, InvNum)).Data1 * 1000)
  1469. Else
  1470. Account(index).Chars(GetPlayerChar(index)).Vital(Vitals.HP) = Account(index).Chars(GetPlayerChar(index)).Vital(Vitals.HP) + Item(GetPlayerInvItemNum(index, InvNum)).AddHP
  1471. SendActionMsg GetPlayerMap(index), "+" & Item(GetPlayerInvItemNum(index, InvNum)).AddHP, BrightGreen, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1472. SendVital index, HP
  1473. TempPlayer(index).VitalPotionTimer(HP) = timeGetTime + PotionWaitTimer
  1474. End If
  1475. End If
  1476. ElseIf Item(GetPlayerInvItemNum(index, InvNum)).AddMP < 1 Then
  1477. Call PlayerMsg(index, "Using this item will have no effect!", BrightRed)
  1478. Exit Sub
  1479. End If
  1480. End If
  1481. ' Add MP
  1482. If Item(GetPlayerInvItemNum(index, InvNum)).AddMP > 0 Then
  1483. If Not GetPlayerVital(index, MP) = GetPlayerMaxVital(index, MP) Then
  1484. If TempPlayer(index).VitalPotionTimer(MP) > timeGetTime And Item(GetPlayerInvItemNum(index, InvNum)).AddHP < 1 Then
  1485. Call PlayerMsg(index, "You must wait before you can use another potion that modifies your mana!", BrightRed)
  1486. Exit Sub
  1487. Else
  1488. If Item(GetPlayerInvItemNum(index, InvNum)).HoT = 1 Then
  1489. TempPlayer(index).VitalCycle(MP) = Item(GetPlayerInvItemNum(index, InvNum)).Data1
  1490. TempPlayer(index).VitalPotion(MP) = GetPlayerInvItemNum(index, InvNum)
  1491. TempPlayer(index).VitalPotionTimer(MP) = timeGetTime + (Item(GetPlayerInvItemNum(index, InvNum)).Data1 * 1000)
  1492. Else
  1493. Account(index).Chars(GetPlayerChar(index)).Vital(Vitals.MP) = Account(index).Chars(GetPlayerChar(index)).Vital(Vitals.MP) + Item(GetPlayerInvItemNum(index, InvNum)).AddMP
  1494. SendActionMsg GetPlayerMap(index), "+" & Item(GetPlayerInvItemNum(index, InvNum)).AddMP, BrightBlue, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1495. SendVital index, MP
  1496. TempPlayer(index).VitalPotionTimer(MP) = timeGetTime + PotionWaitTimer
  1497. End If
  1498. End If
  1499. ElseIf Item(GetPlayerInvItemNum(index, InvNum)).AddHP < 1 Then
  1500. Call PlayerMsg(index, "Using this item will have no effect!", BrightRed)
  1501. Exit Sub
  1502. End If
  1503. End If
  1504. ' Add exp
  1505. If Item(GetPlayerInvItemNum(index, InvNum)).AddEXP > 0 Then
  1506. SetPlayerExp index, GetPlayerExp(index) + Item(GetPlayerInvItemNum(index, InvNum)).AddEXP
  1507. SendPlayerExp index
  1508. CheckPlayerLevelUp index
  1509. SendActionMsg GetPlayerMap(index), "+" & Item(GetPlayerInvItemNum(index, InvNum)).AddEXP & " Exp", White, ACTIONMSG_SCROLL, GetPlayerX(index) * 32, GetPlayerY(index) * 32
  1510. End If
  1511. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1512. ' Send the sound
  1513. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1514. ' Is it reusable, if not take the item away
  1515. If Item(GetPlayerInvItemNum(index, InvNum)).IsReusable = False Then
  1516. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvNum), 0)
  1517. End If
  1518. Case ITEM_TYPE_SPELL
  1519. ' Get the spell number
  1520. n = Item(GetPlayerInvItemNum(index, InvNum)).Data1
  1521. If n > 0 Then
  1522. i = FindOpenSpellSlot(index)
  1523. ' Make sure they have an open spell slot
  1524. If i > 0 Then
  1525. ' Make sure they don't already have the spell
  1526. If Not HasSpell(index, n) Then
  1527. ' Make sure it's a valid name and their is an icon
  1528. If Not Trim$(Spell(n).Name) = vbNullString And Not Spell(n).Icon = 0 Then
  1529. ' Send the sound
  1530. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1531. Call SetPlayerSpell(index, i, n)
  1532. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1533. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvNum), 0)
  1534. Call PlayerMsg(index, "You have learned a new spell!", BrightGreen)
  1535. Call SendPlayerSpell(index, i)
  1536. Else
  1537. Call PlayerMsg(index, "This spell either does not have a name or icon, report this to a staff member.", BrightRed)
  1538. Exit Sub
  1539. End If
  1540. Else
  1541. Call PlayerMsg(index, "You have already learned this spell!", BrightRed)
  1542. Exit Sub
  1543. End If
  1544. Else
  1545. Call PlayerMsg(index, "You have learned all that you can learn!", BrightRed)
  1546. Exit Sub
  1547. End If
  1548. Else
  1549. Call PlayerMsg(index, "This item does not have a spell, please inform a staff member!", BrightRed)
  1550. Exit Sub
  1551. End If
  1552. Case ITEM_TYPE_TELEPORT
  1553. If Moral(Map(GetPlayerMap(index)).Moral).CanPK = 1 Then
  1554. Call PlayerMsg(index, "You can't teleport while in a PvP area!", BrightRed)
  1555. Exit Sub
  1556. End If
  1557. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1558. Call PlayerWarp(index, Item(GetPlayerInvItemNum(index, InvNum)).Data1, Item(GetPlayerInvItemNum(index, InvNum)).Data2, Item(GetPlayerInvItemNum(index, InvNum)).Data3)
  1559. ' Send the sound
  1560. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1561. ' Is it reusable, if not take item away
  1562. If Item(GetPlayerInvItemNum(index, InvNum)).IsReusable = False Then
  1563. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvNum), 1)
  1564. End If
  1565. Case ITEM_TYPE_RESETSTATS
  1566. TotalPoints = GetPlayerPoints(index)
  1567. For i = 1 To Stats.Stat_count - 1
  1568. TotalPoints = TotalPoints + (GetPlayerRawStat(index, i) - Class(GetPlayerClass(index)).Stat(i))
  1569. Call SetPlayerStat(index, i, Class(GetPlayerClass(index)).Stat(i))
  1570. Next
  1571. ' Send the sound
  1572. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1573. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1574. Call SetPlayerPoints(index, TotalPoints)
  1575. Call SendPlayerStats(index)
  1576. Call SendPlayerPoints(index)
  1577. Call PlayerMsg(index, "Your stats have been reset!", Yellow)
  1578. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvNum), 1)
  1579. Case ITEM_TYPE_SPRITE
  1580. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1581. Call SetPlayerSprite(index, Item(GetPlayerInvItemNum(index, InvNum)).Data1)
  1582. Call SendPlayerSprite(index)
  1583. ' Send the sound
  1584. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1585. ' Is it reusable, if not take item away
  1586. If Item(GetPlayerInvItemNum(index, InvNum)).IsReusable = False Then
  1587. Call TakeInvItem(index, GetPlayerInvItemNum(index, InvNum), 1)
  1588. End If
  1589. Case ITEM_TYPE_TITLE
  1590. Call SendAnimation(GetPlayerMap(index), Item(GetPlayerInvItemNum(index, InvNum)).Animation, GetPlayerX(index), GetPlayerY(index))
  1591. Call AddPlayerTitle(index, Item(GetPlayerInvItemNum(index, InvNum)).Data1, InvNum)
  1592. ' Send the sound
  1593. SendPlayerSound index, GetPlayerX(index), GetPlayerY(index), SoundEntity.seItem, GetPlayerInvItemNum(index, InvNum)
  1594. Case ITEM_TYPE_RECIPE
  1595. ' Get the recipe information
  1596. Item1 = Item(GetPlayerInvItemNum(index, InvNum)).Data1
  1597. Item2 = Item(GetPlayerInvItemNum(index, InvNum)).Data2
  1598. Result = Item(GetPlayerInvItemNum(index, InvNum)).Data3
  1599. Skill = Item(GetPlayerInvItemNum(index, InvNum)).Skill
  1600. SkillExp = Item(GetPlayerInvItemNum(index, InvNum)).SkillExp
  1601. SkillLevelReq = Item(GetPlayerInvItemNum(index, InvNum)).SkillLevelReq
  1602. ToolReq = Item(GetPlayerInvItemNum(index, InvNum)).ToolRequired
  1603. ' Perform Recipe checks
  1604. If Item1 <= 0 Or Item2 <= 0 Or Result <= 0 Or Skill <= 0 Then
  1605. Call PlayerMsg(index, "This is an incomplete recipe...", BrightRed)
  1606. Exit Sub
  1607. End If
  1608. If GetPlayerEquipment(index, Weapon) <> ToolReq And HasItem(index, ToolReq) = 0 And ToolReq <> 0 Then
  1609. Call PlayerMsg(index, "You don't have the proper tool required to craft this item!", BrightRed)
  1610. Exit Sub
  1611. End If
  1612. If GetPlayerSkill(index, Skill) < SkillLevelReq Then
  1613. Call PlayerMsg(index, "Your " & GetSkillName(Skill) & " skill isn't high enough to craft this item (" & SkillLevelReq & ")!", BrightRed)
  1614. Exit Sub
  1615. End If
  1616. ' Give the resulting item
  1617. If HasItem(index, Item1) Then
  1618. If HasItem(index, Item2) Then
  1619. Call TakeInvItem(index, Item1, 1)
  1620. Call TakeInvItem(index, Item2, 1)
  1621. Call GiveInvItem(index, Result, 1)
  1622. Call PlayerMsg(index, "You have successfully created " & Trim(Item(Result).Name) & " and earned " & SkillExp & " experience for the skill " & GetSkillName(Skill) & ".", BrightGreen)
  1623. If GetPlayerSkill(index, Skill) < MAX_LEVEL Then
  1624. ' Add the experience to the skill
  1625. Call SetPlayerSkillExp(index, GetPlayerSkillExp(index, Skill) + SkillExp, Skill)
  1626. ' Check for skill level up
  1627. Call CheckPlayerSkillLevelUp(index, Skill)
  1628. End If
  1629. Call SendPlayerData(index)
  1630. Else
  1631. Call PlayerMsg(index, "You do not have all of the ingredients.", BrightRed)
  1632. Exit Sub
  1633. End If
  1634. Else
  1635. Call PlayerMsg(index, "You do not have all of the ingredients.", BrightRed)
  1636. Exit Sub
  1637. End If
  1638. End Select
  1639. End Sub
  1640. Public Sub SetCheckpoint(ByVal index As Long, ByVal MapNum As Integer, ByVal X As Long, ByVal Y As Long)
  1641. ' Check if their checkpoint is already set here
  1642. If Account(index).Chars(GetPlayerChar(index)).CheckPointMap = MapNum And Account(index).Chars(GetPlayerChar(index)).CheckPointX = X And Account(index).Chars(GetPlayerChar(index)).CheckPointY = Y Then
  1643. Call PlayerMsg(index, "Your checkpoint is already saved here!", BrightRed)
  1644. Exit Sub
  1645. End If
  1646. PlayerMsg index, "Your checkpoint has been saved.", BrightGreen
  1647. ' Save the Checkpoint
  1648. Account(index).Chars(GetPlayerChar(index)).CheckPointMap = MapNum
  1649. Account(index).Chars(GetPlayerChar(index)).CheckPointX = X
  1650. Account(index).Chars(GetPlayerChar(index)).CheckPointY = Y
  1651. End Sub
  1652. Public Sub UpdatePlayerEquipmentItems(ByVal index As Long)
  1653. Dim i As Long
  1654. If GetPlayerEquipment(index, Shield) > 0 And GetPlayerEquipment(index, Weapon) > 0 Then
  1655. If Item(GetPlayerEquipment(index, Weapon)).TwoHanded = 1 Then
  1656. Call PlayerUnequipItem(index, Weapon, True, True, True)
  1657. End If
  1658. End If
  1659. For i = 1 To Equipment_Count - 1
  1660. If GetPlayerEquipment(index, i) > 0 Then
  1661. If Item(GetPlayerEquipment(index, i)).EquipSlot <> i Then
  1662. Call PlayerUnequipItem(index, i, True, True, True)
  1663. End If
  1664. End If
  1665. Next
  1666. End Sub
  1667. Public Sub UpdateAllPlayerEquipmentItems()
  1668. Dim n As Long, i As Long
  1669. For n = 1 To Player_HighIndex
  1670. If IsPlaying(n) Then
  1671. If GetPlayerEquipment(n, Shield) > 0 And GetPlayerEquipment(n, Weapon) > 0 Then
  1672. If Item(GetPlayerEquipment(n, Weapon)).TwoHanded = 1 Then
  1673. Call PlayerUnequipItem(n, Weapon, True, True, True)
  1674. End If
  1675. End If
  1676. For i = 1 To Equipment_Count - 1
  1677. If GetPlayerEquipment(n, i) > 0 Then
  1678. If Item(GetPlayerEquipment(n, i)).EquipSlot <> i Then
  1679. Call PlayerUnequipItem(n, i, True, True, True)
  1680. End If
  1681. End If
  1682. Next
  1683. End If
  1684. Next
  1685. End Sub
  1686. Public Sub UpdatePlayerItems(ByVal index As Long)
  1687. Dim TmpItem As Long
  1688. Dim i As Byte, X As Byte
  1689. ' Make sure the inventory items are not cached as a currency
  1690. For i = 1 To MAX_INV
  1691. If GetPlayerInvItemNum(index, i) > 0 And GetPlayerInvItemNum(index, i) <= MAX_INV Then
  1692. If Not Item(GetPlayerInvItemNum(index, i)).Stackable = 1 Then
  1693. If GetPlayerInvItemValue(index, i) > 1 Then
  1694. TmpItem = GetPlayerInvItemNum(index, i)
  1695. Call TakeInvItem(index, TmpItem, 1)
  1696. Call GiveInvItem(index, TmpItem, 1)
  1697. End If
  1698. End If
  1699. If GetPlayerInvItemNum(index, i) > 0 And GetPlayerInvItemNum(index, i) <= MAX_INV Then
  1700. If Item(GetPlayerInvItemNum(index, i)).Stackable = 1 Then
  1701. If GetPlayerInvItemValue(index, i) = 0 Then
  1702. TmpItem = GetPlayerInvItemNum(index, i)
  1703. Call TakeInvItem(index, TmpItem, 1)
  1704. X = X + 1
  1705. End If
  1706. End If
  1707. End If
  1708. End If
  1709. Next
  1710. If X > 0 Then
  1711. Call GiveInvItem(index, TmpItem, X)
  1712. End If
  1713. X = 0
  1714. ' Make sure the bank items are not cached as a currency
  1715. For i = 1 To MAX_BANK
  1716. If GetPlayerBankItemNum(index, i) > 0 And GetPlayerBankItemNum(index, i) <= MAX_BANK Then
  1717. If Not Item(GetPlayerBankItemNum(index, i)).Stackable = 1 Then
  1718. If GetPlayerBankItemValue(index, i) > 1 Then
  1719. TmpItem = GetPlayerBankItemNum(index, i)
  1720. Call TakeBankItem(index, TmpItem, 1)
  1721. Call GiveBankItem(index, TmpItem, 1)
  1722. End If
  1723. End If
  1724. If GetPlayerBankItemNum(index, i) > 0 And GetPlayerBankItemNum(index, i) <= MAX_BANK Then
  1725. If Item(GetPlayerBankItemNum(index, i)).Stackable = 1 Then
  1726. If GetPlayerBankItemValue(index, i) = 0 Then
  1727. TmpItem = GetPlayerBankItemNum(index, i)
  1728. Call TakeBankItem(index, TmpItem, 1)
  1729. X = X + 1
  1730. End If
  1731. End If
  1732. End If
  1733. End If
  1734. Next
  1735. If X > 0 Then
  1736. Call GiveBankItem(index, TmpItem, X)
  1737. End If
  1738. End Sub
  1739. Public Sub UpdateAllPlayerItems(ByVal ItemNum As Integer)
  1740. Dim TmpItem As Long
  1741. Dim n As Long, i As Byte, X As Byte
  1742. For n = 1 To Player_HighIndex
  1743. If IsPlaying(n) Then
  1744. ' Make sure the inv items are not cached as a currency
  1745. For i = 1 To MAX_INV
  1746. If GetPlayerInvItemNum(n, i) > 0 And GetPlayerInvItemNum(n, i) <= MAX_INV Then
  1747. If GetPlayerInvItemNum(n, i) = ItemNum Then
  1748. TmpItem = GetPlayerInvItemNum(n, i)
  1749. If Not Item(GetPlayerInvItemNum(n, i)).Stackable = 1 Then
  1750. If GetPlayerInvItemValue(n, i) > 1 Then
  1751. Call TakeInvItem(n, TmpItem, 1)
  1752. Call GiveInvItem(n, TmpItem, 1)
  1753. End If
  1754. End If
  1755. If GetPlayerInvItemNum(n, i) > 0 And GetPlayerInvItemNum(n, i) <= MAX_INV Then
  1756. If Item(GetPlayerInvItemNum(n, i)).Stackable = 1 Then
  1757. If GetPlayerInvItemValue(n, i) = 0 Then
  1758. Call TakeInvItem(n, TmpItem, 1)
  1759. X = X + 1
  1760. End If
  1761. End If
  1762. End If
  1763. End If
  1764. End If
  1765. Next
  1766. If X > 0 Then
  1767. Call GiveInvItem(n, TmpItem, X)
  1768. End If
  1769. X = 0
  1770. ' Make sure the Bank items are not cached as a currency
  1771. For i = 1 To MAX_BANK
  1772. If GetPlayerBankItemNum(n, i) > 0 And GetPlayerBankItemNum(n, i) <= MAX_BANK Then
  1773. If GetPlayerBankItemNum(n, i) = ItemNum Then
  1774. TmpItem = GetPlayerBankItemNum(n, i)
  1775. If Not Item(GetPlayerBankItemNum(n, i)).Stackable = 1 Then
  1776. If GetPlayerBankItemValue(n, i) > 1 Then
  1777. Call TakeBankItem(n, TmpItem, 1)
  1778. Call GiveBankItem(n, TmpItem, 1)
  1779. End If
  1780. End If
  1781. If GetPlayerBankItemNum(n, i) > 0 And GetPlayerBankItemNum(n, i) <= MAX_BANK Then
  1782. If Item(GetPlayerBankItemNum(n, i)).Stackable = 1 Then
  1783. If GetPlayerBankItemValue(n, i) = 0 Then
  1784. Call TakeBankItem(n, TmpItem, 1)
  1785. X = X + 1
  1786. End If
  1787. End If
  1788. End If
  1789. End If
  1790. End If
  1791. Next
  1792. If X > 0 Then
  1793. Call GiveBankItem(n, TmpItem, X)
  1794. End If
  1795. End If
  1796. Next
  1797. End Sub
  1798. Public Sub UpdateClassData(ByVal index As Long)
  1799. Dim i As Long
  1800. Dim TotalPoints As Long
  1801. Dim TotalPoints2 As Long
  1802. For i = 1 To Stats.Stat_count - 1
  1803. TotalPoints = TotalPoints + Class(GetPlayerClass(index)).Stat(i)
  1804. TotalPoints2 = TotalPoints2 + GetPlayerRawStat(index, i)
  1805. Next
  1806. TotalPoints = TotalPoints + ((GetPlayerLevel(index) - 1) * STATS_LEVEL)
  1807. TotalPoints2 = TotalPoints2 + GetPlayerPoints(index)
  1808. ' Verify incorrect class data
  1809. If TotalPoints <> TotalPoints2 Then
  1810. For i = 1 To Stats.Stat_count - 1
  1811. Call SetPlayerStat(index, i, Class(GetPlayerClass(index)).Stat(i))
  1812. Next
  1813. Call SetPlayerPoints(index, (GetPlayerLevel(index) - 1) * STATS_LEVEL)
  1814. End If
  1815. If GetPlayerSprite(index) = 0 Then
  1816. If GetPlayerGender(index) = GENDER_MALE Then
  1817. Call SetPlayerSprite(index, Class(GetPlayerClass(index)).MaleSprite)
  1818. Else
  1819. Call SetPlayerSprite(index, Class(GetPlayerClass(index)).FemaleSprite)
  1820. End If
  1821. ' Sprite still nothing?
  1822. If GetPlayerSprite(index) = 0 Then
  1823. Call SetPlayerSprite(index, 1)
  1824. End If
  1825. End If
  1826. If GetPlayerFace(index) = 0 Then
  1827. If GetPlayerGender(index) = GENDER_MALE Then
  1828. Call SetPlayerFace(index, Class(GetPlayerClass(index)).MaleFace)
  1829. Else
  1830. Call SetPlayerFace(index, Class(GetPlayerClass(index)).FemaleFace)
  1831. End If
  1832. ' Face still nothing?
  1833. If GetPlayerFace(index) = 0 Then
  1834. Call SetPlayerFace(index, 1)
  1835. End If
  1836. End If
  1837. End Sub
  1838. Public Sub UpdateAllClassData()
  1839. Dim i, X As Long
  1840. For X = 1 To Player_HighIndex
  1841. ' Verify incorrect class data
  1842. For i = 1 To Stats.Stat_count - 1
  1843. If Not Class(GetPlayerClass(X)).Stat(i) = GetPlayerStat(X, i) - ((GetPlayerLevel(X) - 1) * 5) Then
  1844. Call SetPlayerStat(X, i, Class(GetPlayerClass(X)).Stat(i) + ((GetPlayerLevel(X) - 1) * 5))
  1845. End If
  1846. Next
  1847. If GetPlayerSprite(X) = 0 Then
  1848. If GetPlayerGender(X) = GENDER_MALE Then
  1849. Call SetPlayerSprite(X, Class(GetPlayerClass(X)).MaleSprite)
  1850. Else
  1851. Call SetPlayerSprite(X, Class(GetPlayerClass(X)).FemaleSprite)
  1852. End If
  1853. ' Sprite still nothing?
  1854. If GetPlayerSprite(X) = 0 Then
  1855. Call SetPlayerSprite(X, 1)
  1856. End If
  1857. End If
  1858. If GetPlayerFace(X) = 0 Then
  1859. If GetPlayerGender(X) = GENDER_MALE Then
  1860. Call SetPlayerFace(X, Class(GetPlayerClass(X)).MaleFace)
  1861. Else
  1862. Call SetPlayerFace(X, Class(GetPlayerClass(X)).FemaleFace)
  1863. End If
  1864. ' Face still nothing?
  1865. If GetPlayerFace(X) = 0 Then
  1866. Call SetPlayerFace(X, 1)
  1867. End If
  1868. End If
  1869. Next
  1870. End Sub
  1871. Function CanPlayerTrade(ByVal index As Long, ByVal TradeTarget As Long) As Boolean
  1872. Dim sX As Long, sY As Long, tX As Long, tY As Long
  1873. ' Can't trade with yourself
  1874. If TradeTarget = index Then
  1875. PlayerMsg index, "You can't trade with yourself.", BrightRed
  1876. Exit Function
  1877. End If
  1878. ' Make sure they're on the same map
  1879. If Not Account(TradeTarget).Chars(GetPlayerChar(TradeTarget)).Map = Account(index).Chars(GetPlayerChar(index)).Map Then Exit Function
  1880. ' Make sure they are allowed to trade
  1881. If Account(TradeTarget).Chars(GetPlayerChar(index)).CanTrade = False Then
  1882. PlayerMsg index, Trim$(GetPlayerName(TradeTarget)) & " has their trading turned off.", BrightRed
  1883. Exit Function
  1884. End If
  1885. ' Make sure they're stood next to each other
  1886. tX = Account(TradeTarget).Chars(GetPlayerChar(TradeTarget)).X
  1887. tY = Account(TradeTarget).Chars(GetPlayerChar(TradeTarget)).Y
  1888. sX = Account(index).Chars(GetPlayerChar(index)).X
  1889. sY = Account(index).Chars(GetPlayerChar(index)).Y
  1890. ' Within range?
  1891. If tX < sX - 1 Or tX > sX + 1 And tY < sY - 1 Or tY > sY + 1 Then
  1892. PlayerMsg index, "You need to be standing next to someone to request or accept a trade.", BrightRed
  1893. Exit Function
  1894. End If
  1895. CanPlayerTrade = True
  1896. End Function
  1897. Function CanPlayerUseItem(ByVal index As Long, ByVal ItemNum As Integer, Optional Message As Boolean = True) As Boolean
  1898. Dim LevelReq As Byte
  1899. Dim AccessReq As Byte
  1900. Dim ClassReq As Byte
  1901. Dim GenderReq As Byte
  1902. Dim i As Long
  1903. ' Can't use items while in a map that doesn't allow it
  1904. If Moral(Map(GetPlayerMap(index)).Moral).CanUseItem = 0 Then
  1905. Call PlayerMsg(index, "You can't use items here!", BrightRed)
  1906. Exit Function
  1907. End If
  1908. LevelReq = Item(ItemNum).LevelReq
  1909. ' Make sure they are the right level
  1910. If LevelReq > GetPlayerLevel(index) Then
  1911. If Message Then
  1912. Call PlayerMsg(index, "You must be level " & LevelReq & " to use this item.", BrightRed)
  1913. End If
  1914. Exit Function
  1915. End If
  1916. AccessReq = Item(ItemNum).AccessReq
  1917. ' Make sure they have the right access
  1918. If AccessReq > GetPlayerAccess(index) Then
  1919. If Message Then
  1920. Call PlayerMsg(index, "You must be a staff member to use this item.", BrightRed)
  1921. End If
  1922. Exit Function
  1923. End If
  1924. ClassReq = Item(ItemNum).ClassReq
  1925. ' Make sure the Classes req > 0
  1926. If ClassReq > 0 Then ' 0 = no req
  1927. If Not ClassReq = GetPlayerClass(index) Then
  1928. If Message Then
  1929. Call PlayerMsg(index, "You must be " & CheckGrammar(Trim$(Class(ClassReq).Name)) & " can use this item!", BrightRed)
  1930. End If
  1931. Exit Function
  1932. End If
  1933. End If
  1934. GenderReq = Item(ItemNum).GenderReq
  1935. ' Make sure the Gender req > 0
  1936. If GenderReq > 0 Then ' 0 = no req
  1937. If Not GenderReq - 1 = GetPlayerGender(index) Then
  1938. If Message Then
  1939. If GetPlayerGender(index) = 0 Then
  1940. Call PlayerMsg(index, "You need to be a female to use this item!", BrightRed)
  1941. Else
  1942. Call PlayerMsg(index, "You need to be a male to use this item!", BrightRed)
  1943. End If
  1944. End If
  1945. Exit Function
  1946. End If
  1947. End If
  1948. ' Check if they have the stats required to use this item
  1949. For i = 1 To Stats.Stat_count - 1
  1950. If GetPlayerRawStat(index, i) < Item(ItemNum).Stat_Req(i) Then
  1951. If Message Then
  1952. PlayerMsg index, "You do not meet the stat requirements to use this item.", BrightRed
  1953. End If
  1954. Exit Function
  1955. End If
  1956. Next
  1957. ' Check if they have the proficiency required to use this item
  1958. If Item(ItemNum).ProficiencyReq > 0 Then
  1959. If GetPlayerProficiency(index, Item(ItemNum).ProficiencyReq) = 0 Then
  1960. If Message Then
  1961. PlayerMsg index, "You lack the proficiency to use this item!", BrightRed
  1962. End If
  1963. Exit Function
  1964. End If
  1965. End If
  1966. ' Don't let them equip a two handed weapon if they have a shield on
  1967. If Item(ItemNum).TwoHanded = 1 Then
  1968. If GetPlayerEquipment(index, Shield) > 0 Then
  1969. PlayerMsg index, "You must unequip your shield before equipping a two-handed weapon!", BrightRed
  1970. Exit Function
  1971. End If
  1972. End If
  1973. ' Don't let them use a tool they don't meet the level requirement to
  1974. If Item(ItemNum).SkillReq > 0 Then
  1975. If GetPlayerSkill(index, Item(ItemNum).SkillReq) < Item(ItemNum).LevelReq Then
  1976. PlayerMsg index, "Your " & CheckGrammar(GetSkillName(Item(ItemNum).SkillReq)) & " skill level does not meet the requirement to use this item!", BrightRed
  1977. Exit Function
  1978. End If
  1979. End If
  1980. CanPlayerUseItem = True
  1981. End Function
  1982. Public Function CanPlayerCastSpell(ByVal index As Long, ByVal SpellNum As Long) As Boolean
  1983. ' Check if they have enough MP
  1984. If GetPlayerVital(index, Vitals.MP) < Spell(SpellNum).MPCost Then
  1985. Call PlayerMsg(index, "Not enough mana!", BrightRed)
  1986. Exit Function
  1987. End If
  1988. ' Make sure they are the right level
  1989. If Spell(SpellNum).LevelReq > GetPlayerLevel(index) Then
  1990. Call PlayerMsg(index, "You must be level " & Spell(SpellNum).LevelReq & " to cast this spell.", BrightRed)
  1991. Exit Function
  1992. End If
  1993. ' Make sure they have the right access
  1994. If Spell(SpellNum).AccessReq > GetPlayerAccess(index) Then
  1995. Call PlayerMsg(index, "You must be a staff member to cast this spell.", BrightRed)
  1996. Exit Function
  1997. End If
  1998. ' Make sure the ClassReq > 0
  1999. If Spell(SpellNum).ClassReq > 0 Then ' 0 = no req
  2000. If Spell(SpellNum).ClassReq <> GetPlayerClass(index) Then
  2001. Call PlayerMsg(index, "Only " & CheckGrammar(Trim$(Class(Spell(SpellNum).ClassReq).Name)) & " can use this spell.", BrightRed)
  2002. Exit Function
  2003. End If
  2004. End If
  2005. CanPlayerCastSpell = True
  2006. End Function
  2007. Public Sub DamagePlayerEquipment(ByVal index As Long, ByVal EquipmentSlot As Byte)
  2008. Dim ItemNum As Long, RandomNum As Byte
  2009. ItemNum = GetPlayerEquipment(index, EquipmentSlot)
  2010. If ItemNum = 0 Then Exit Sub
  2011. ' Make sure the item isn't indestructable
  2012. If Item(ItemNum).Indestructable = 1 Then Exit Sub
  2013. ' Don't subtract past 0
  2014. If GetPlayerEquipmentDur(index, EquipmentSlot) = 0 Then Exit Sub
  2015. RandomNum = Random(1, 7)
  2016. ' 1 in 7 chance it will actually damage the equipment if it's not a shield type item
  2017. If RandomNum = 1 Or EquipmentSlot = Shield Then
  2018. If Item(ItemNum).Type = ITEM_TYPE_EQUIPMENT Then
  2019. ' Take away 1 durability
  2020. Call SetPlayerEquipmentDur(index, GetPlayerEquipmentDur(index, EquipmentSlot) - 1, EquipmentSlot)
  2021. Call SendWornEquipment(index)
  2022. Call SendMapEquipment(index)
  2023. If GetPlayerEquipmentDur(index, EquipmentSlot) < 1 Then
  2024. Call PlayerMsg(index, "Your " & Trim$(Item(ItemNum).Name) & " has broken.", BrightRed)
  2025. Call PlayerUnequipItem(index, EquipmentSlot, True, True, True)
  2026. ElseIf GetPlayerEquipmentDur(index, EquipmentSlot) = 10 Then
  2027. Call PlayerMsg(index, "Your " & Trim$(Item(ItemNum).Name) & " is about to break!", BrightRed)
  2028. End If
  2029. End If
  2030. End If
  2031. End Sub
  2032. Public Sub WarpToCheckPoint(index As Long)
  2033. Dim MapNum As Integer
  2034. Dim X As Long, Y As Long
  2035. MapNum = Account(index).Chars(GetPlayerChar(index)).CheckPointMap
  2036. X = Account(index).Chars(GetPlayerChar(index)).CheckPointX
  2037. Y = Account(index).Chars(GetPlayerChar(index)).CheckPointY
  2038. PlayerWarp index, MapNum, X, Y
  2039. End Sub
  2040. Function IsAFriend(ByVal index As Long, ByVal OtherPlayer As Long) As Boolean
  2041. Dim i As Long
  2042. ' Are they on the user's friend list
  2043. For i = 1 To Account(OtherPlayer).Friends.AmountOfFriends
  2044. If Trim$(Account(OtherPlayer).Friends.Members(i)) = GetPlayerName(index) Then
  2045. IsAFriend = True
  2046. Exit Function
  2047. End If
  2048. Next
  2049. End Function
  2050. Function IsAFoe(ByVal index As Long, ByVal OtherPlayer As Long) As Boolean
  2051. Dim i As Long
  2052. ' Are they on the user's foe list
  2053. For i = 1 To Account(OtherPlayer).Foes.Amount
  2054. If Trim$(Account(OtherPlayer).Foes.Members(i)) = GetPlayerName(index) Then
  2055. Call PlayerMsg(index, "You are being ignored by " & GetPlayerName(OtherPlayer) & "!", BrightRed)
  2056. IsAFoe = True
  2057. Exit Function
  2058. End If
  2059. Next
  2060. End Function
  2061. Function IsPlayerBusy(ByVal index As Long, ByVal OtherPlayer As Long) As Boolean
  2062. ' Make sure they're not busy doing something else
  2063. If IsPlaying(OtherPlayer) Then
  2064. If TempPlayer(OtherPlayer).InBank Or TempPlayer(OtherPlayer).InShop > 0 Or TempPlayer(OtherPlayer).InTrade > 0 Or (TempPlayer(OtherPlayer).PartyInvite > 0 And TempPlayer(OtherPlayer).PartyInvite <> index) Or (TempPlayer(OtherPlayer).TradeRequest > 0 And TempPlayer(OtherPlayer).TradeRequest <> index) Or (TempPlayer(OtherPlayer).GuildInvite > 0 And TempPlayer(OtherPlayer).GuildInvite <> index) Then
  2065. IsPlayerBusy = True
  2066. PlayerMsg index, GetPlayerName(OtherPlayer) & " is busy!", BrightRed
  2067. Exit Function
  2068. End If
  2069. End If
  2070. End Function