V-MonsterLoad.asm
上传用户:santakups8
上传日期:2021-03-23
资源大小:544k
文件大小:30k
源码类别:

模拟服务器

开发平台:

Asm

  1. ;EasyCodeName=Module1,1
  2. ;-----------------------------------------------------------------------------------
  3. ;    VeMU
  4. ;    Its a package that allows the user to set his own server of the game
  5. ;    "MuOnline", this is not an emulator since i am not "emulating"
  6. ;    what the actual games does, i am "creating" a method for set a Server
  7. ;    of this Game.
  8. ;
  9. ;    Copyright (C) 2010  Felipe Ya馿z
  10. ;
  11. ;    This program is free software: you can redistribute it and/or modify
  12. ;    it under the terms of the GNU General Public License as published by
  13. ;    the Free Software Foundation, either version 3 of the License, or
  14. ;    (at your option) any later version.
  15. ;
  16. ;    This program is distributed in the hope that it will be useful,
  17. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;    GNU General Public License for more details.
  20. ;
  21. ;    You should have received a copy of the GNU General Public License
  22. ;    along with this program.  If not, see http://www.gnu.org/licenses/.
  23. ;-----------------------------------------------------------------------------------
  24. ;-----------------------------------------------------------------------------------
  25. ;                        -----------------
  26. ;                             Coded     /
  27. ;                              By      /
  28. ;                           -={FeN$x)=-
  29. ;                         /  Felipe Y.  
  30. ;                        /               
  31. ;                        -----------------
  32. ; Programming Lang: ASM
  33. ; Country: Chile
  34. ;              My respect for all those who lost their lifes
  35. ;              In the earthquake of my country...
  36. ;              Let god take their spirits home...
  37. ;-----------------------------------------------------------------------------------
  38. ;////////////////////////////////////////////////////////////////////////////////////
  39. ;                       VeMU Project
  40. ;                       Monster Load !
  41. ;////////////////////////////////////////////////////////////////////////////////////
  42. .Const
  43. .Data?
  44. .Data
  45. szMonsterAttr DB ".DataGamePlayMonstersMonster.txt", 0
  46. szMonsterSetBase DB ".DataGamePlayMonstersMonsterSetBase.txt", 0
  47. .Code
  48. ;////////////////////////////////////////////////////////////////////////////////////
  49. ; Very complex procedure that loads MonsterSetBase in the same sintax has
  50. ; Webzen do, with the only difference this procedure is based in the loop system
  51. ; That define the style of this project. This allows to add new variables
  52. ; and edit limits without touching the procedure.
  53. ; TRY TO DONT EDIT THIS PROCEDURE !
  54. ;////////////////////////////////////////////////////////////////////////////////////
  55. V_MonsterSetBase_Load Proc
  56. local vMobTypeActivated:Dword ;Activate if we read a mobtype
  57. local vMobType:Dword
  58. local vMobCounter:Dword ;Counter for mobs in local mode
  59. local FilePosition:Dword ;File position
  60. local LoopCounter:Dword ;Loop counter for multiple uses
  61. Local pObject:Dword ;For dont calculate each time with macros
  62. local pBufferSpace:Dword
  63. local BytesReaded:Dword
  64. local StructFile:WIN32_FILE_ATTRIBUTE_DATA
  65. .Const
  66. RepTimesForSingles equ 6 ;Load 6 monster set base variables
  67. RepTimesForSpots equ 9 ;Load 9 monster set base variables
  68. .Code
  69. mov LoopCounter, 0
  70. mov FilePosition, 0
  71. mov vMobTypeActivated, 0
  72. rdtsc
  73. Invoke MRandomInit, Eax ;Initialize random number generator
  74. ;-------------------------------
  75. ;Load file into memory
  76. ;-------------------------------
  77. lea edx, StructFile
  78. GetFileLength addr szMonsterSetBase, edx
  79. mov eax, StructFile.nFileSizeLow
  80. fastalloc eax, 1 ;alloc space for file
  81. mov pBufferSpace, eax
  82. lea ecx, BytesReaded
  83. ReadThisFile Addr szMonsterSetBase, pBufferSpace, ecx ;read of file and handles the close
  84. mov ecx, StructFile.nFileSizeLow
  85. add eax, ecx
  86. mov dword ptr [eax], 0 ;Append to 00 byte in the end of file for prevent bugs
  87. xor ecx, ecx
  88. xor edx, edx
  89. assume eax:ptr MONSTER_SETBASE
  90. ;---------------------------------------------------------------------------------------------
  91. ; Begin of big loop for take data of all Monster bases
  92. ;---------------------------------------------------------------------------------------------
  93. .While (ecx != -1) ;Infinite loop
  94. ;---------------------------------------------------------------------------------------------
  95. ;CHECK IF WE CHANGE OF MOBTYPE OR IF WE CONTINUE WITH THE SAME !
  96. ;---------------------------------------------------------------------------------------------
  97.   .If (vMobTypeActivated == 0)
  98.     invoke GetToken, pBufferSpace, ecx, NULL ;Read MonsterType variable
  99.     .If (edx == 1)
  100.       xor eax, eax
  101.       .break
  102.     .Endif
  103.     mov edx, eax
  104.     pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
  105.     mov pObject, eax
  106.     mov [eax].MonsterType, dl
  107.     mov vMobType, edx
  108.     mov vMobTypeActivated, 1
  109.   .Else
  110.     pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
  111.     mov pObject, eax
  112.     mov edx, vMobType
  113.     mov [eax].MonsterType, dl
  114.   .Endif
  115. ;---------------------------------------------------------------------------------------------
  116. ;---------------------------------------------------------------------------------------------
  117. ;CHECK FOR NPC MONSTER TYPE OR SINGLE MONSTER TYPE
  118. ;---------------------------------------------------------------------------------------------
  119.   .IF ([eax].MonsterType == NPCMONSTER) || ([eax].MonsterType == SINGLEMONSTER) || ([eax].MonsterType == BLOODMONSTER)
  120.    mov vMobCounter, 0 ;Avoid bugs !
  121.    mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore rewrite
  122.    .Repeat
  123.      push ebx ;Save EBX
  124.      invoke GetToken, pBufferSpace, ecx, NULL
  125.      pop ebx
  126.      .if (edx == 1)
  127.        xor eax, eax
  128.        .break
  129.      .endif
  130.      mov edx, eax
  131.      mov eax, pObject
  132.      .if (LoopCounter == 0) ;If we reading variable "MobIndex"
  133.         mov word ptr [eax + ebx], dx ;Save MobIndex that use 2 bytes
  134.         add ebx, 2 ;Uses 2 bytes
  135.      .else
  136.        mov [eax + ebx], dl ;Save rest of variables that use 1 byte
  137.        add ebx, 1
  138.      .endif
  139.      add LoopCounter, 1
  140.    .until (LoopCounter == RepTimesForSingles)
  141.    mov LoopCounter, 0
  142.    mov FilePosition, ecx
  143. ;---------------------------------------------------------------------------------------------
  144. ;LETS DO SOME FIXES AND ADD NEW OPTIONS TO THE ALREADY EXISTING ONES !
  145. ;ONLY FOR NPCs TYPE MOB, SINGLE TYPE MOB, BLOOD CASTLE, GATES, EVENTS THAT
  146. ;NEED ANY SINGULARITY MOBS OR STATICS
  147. ;---------------------------------------------------------------------------------------------
  148.    mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore it, it cant be random
  149.    .repeat
  150.      .if (LoopCounter == 0) && (word ptr [eax + ebx] == 0FFFFh)
  151.          push eax
  152.          push ebx
  153.          Invoke MIRandom, 0, MonsterCounter   ;Generate a random index based in the total ammount of MonstersAttr that we read
  154.          mov edx, eax
  155.          pop ebx
  156.          pop eax
  157.          mov word ptr [eax + ebx], dx
  158.          add ebx, 2 ;uses 2 bytes
  159.      .elseif (LoopCounter != 0) && (byte ptr [eax + ebx] == 0FFh)
  160.        .if (LoopCounter == 1) ;If we are reading variable MapNumber then...
  161.          push eax
  162.          push ebx
  163.          Invoke MIRandom, 0, MAPLIMIT   ;Generate a random map
  164.          mov edx, eax
  165.          pop ebx
  166.          pop eax
  167.          mov byte ptr [eax + ebx], dl
  168.          add ebx, 1
  169.        .elseif (LoopCounter == 2) ;If we are reading variable Distance then
  170.          push eax
  171.          push ebx
  172.          Invoke MIRandom, 0, 3   ;Generate a random distance
  173.          shl eax, 4 ;Random number*10 = Final Distance
  174.          mov edx, eax
  175.          pop ebx
  176.          pop eax
  177.          mov byte ptr [eax + ebx], dl
  178.          add ebx, 1
  179.        .elseif (LoopCounter == 5) ;if we are reading variable Direction then
  180.          push eax
  181.          push ebx
  182.          Invoke MIRandom, 0, 8   ;Generate a random direction
  183.          mov edx, eax
  184.          pop ebx
  185.          pop eax
  186.          mov byte ptr [eax + ebx], dl
  187.          add ebx, 1
  188.        .else ;For cords variable...
  189.          push eax
  190.          push ebx
  191.          Invoke MIRandom, 0, 0FFh   ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
  192.          mov edx, eax
  193.          pop ebx
  194.          pop eax
  195.          mov byte ptr [eax + ebx], dl
  196.          add ebx, 1
  197.        .endif
  198.  .elseif (LoopCounter == 0) ;If we are reading MonsterIndex variable and dont found it randome then
  199.          add ebx, 2 ;Add ebx 2 for not read his next byte
  200.      .else ;In case that any other variable is not random just add 1 to avoid it
  201.          add ebx, 1
  202.      .endif
  203.      add LoopCounter, 1
  204.   .until (LoopCounter == RepTimesForSingles)
  205.   mov LoopCounter, 0 ;Avoid bugs !
  206.  .ELSEIF ([eax].MonsterType == SPOTSMONSTER) || ([eax].MonsterType == EVENTMONSTER) || ([eax].MonsterType == GOLDENMONSTER)
  207. ;---------------------------------------------------------------------------------------------
  208. ;CHECK FOR SPOTS MONSTERS, GOLDEN MONSTERS & DEVILSQUARE (possible kanturu)
  209. ;---------------------------------------------------------------------------------------------
  210.    mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore rewrite
  211.    .Repeat
  212.      push ebx ;Save EBX
  213.      invoke GetToken, pBufferSpace, ecx, NULL
  214.      pop ebx ;Return EBX
  215.      .if (edx == 1)
  216.        xor eax, eax
  217.        .break
  218.      .endif
  219.      mov edx, eax
  220.      mov eax, pObject
  221.      .if (LoopCounter == 0) ;If we reading variable "MobIndex"
  222.         mov word ptr [eax + ebx], dx ;Save MobIndex that use 2 bytes
  223.         add ebx, 2 ;Uses 4 bytes
  224.      .else
  225.        mov [eax + ebx], dl ;Save rest of variables that use 1 byte
  226.        add ebx, 1
  227.      .endif
  228.      add LoopCounter, 1
  229.    .until (LoopCounter == RepTimesForSpots)
  230.    mov LoopCounter, 0
  231.    mov FilePosition, ecx
  232. ;---------------------------------------------------------------------------------------------
  233. ;LETS DO SOME FIXES AND ADD NEW OPTIONS TO THE ALREADY EXISTING ONES !
  234. ;ONLY FOR SPOTS MONSTERS, GOLDEN MONSTERS & DEVILSQUARE (possible kanturu)
  235. ;FOR ANY EVENT THAT NEEDS ALOT OF MONSTERS
  236. ;---------------------------------------------------------------------------------------------
  237. ;   push eax
  238. ;   invoke V_CMap_CheckValidMap, [eax].MapNumber ;Check if we put a valid map
  239. ;   mov edx, eax
  240. ;   pop eax
  241.    .If (ecx != -1)
  242.     .If ([eax].Quantity == -1) ;Means random
  243.        push eax
  244.        Invoke MIRandom, 1, MAX_SETBASE_RAND_MOBS   ;Generate a random number of monster to be created
  245.        mov edx, eax
  246.        pop eax
  247.        mov byte ptr [eax].Quantity, dl
  248.     .Endif
  249.     movsx edx, byte ptr [eax].Quantity
  250.     .if (edx == 1) ;If quantity is 1 then i dont sub it
  251.     .else
  252.       sub edx, 1 ;Quantity - 1 caused we dont start reading from "1" we start reading from "0" (and thats considered has 1)
  253.     .endif
  254.     mov vMobCounter, edx
  255.     mov ecx, SizeOf MONSTER_SETBASE
  256.     xor ebx, ebx
  257. ;---------------------------------------------------------------------------------------------
  258. ;Copy the quantity of monsters and loop for fix all details !
  259. ;---------------------------------------------------------------------------------------------
  260.     .Repeat
  261.       push eax
  262.       push ecx
  263.       push ebx
  264.       lea edx, [eax + ecx]
  265.       invoke MemCopy, eax, edx, SizeOf MONSTER_SETBASE ;Copy Monster
  266.       pop ebx
  267.       pop ecx
  268.       pop eax
  269.       add ecx, SizeOf MONSTER_SETBASE
  270.       add ebx, 1
  271.     .Until (ebx == vMobCounter)
  272.     add vMobCounter, 1 ;We restore the original value, for reading the buffers below
  273. ;---------------------------------------------------------------------------------------------
  274.     mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Avoid checking if its random or not
  275.     xor ecx, ecx
  276. ;---------------------------------------------------------------------------------------------
  277. ;Get all variables and check if they are random or not ! (FOR ALL MOBS)
  278. ;---------------------------------------------------------------------------------------------
  279.     .Repeat
  280.      push ecx ;Save it has a loop counter
  281.       .Repeat
  282.          .If (LoopCounter == 0) && (word ptr [eax + ebx] == 0FFFFh)
  283.          push eax
  284.          push ebx
  285.          Invoke MIRandom, 0, MonsterCounter   ;Generate a random index based in the total ammount of MonstersAttr that we read
  286.          mov edx, eax
  287.          pop ebx
  288.          pop eax
  289.          mov word ptr [eax + ebx], dx
  290.          add ebx, 2 ;uses 2 bytes
  291.          .Elseif (LoopCounter != 0) && (byte ptr [eax + ebx] == 0FFh)
  292.      .if (LoopCounter == 1) ;If we are reading variable MapNumber then...
  293.          push eax
  294.          push ebx
  295.          Invoke MIRandom, 0, MAPLIMIT   ;Generate a random map
  296.          mov edx, eax
  297.          pop ebx
  298.          pop eax
  299.          mov byte ptr [eax + ebx], dl
  300.          add ebx, 1
  301.      .elseif (LoopCounter == 2) ;If we are reading variable Distance then
  302.          push eax
  303.          push ebx
  304.          Invoke MIRandom, 0, 3   ;Generate a random distance
  305.          shl eax, 4 ;Random number*10 = Final Distance
  306.          mov edx, eax
  307.          pop ebx
  308.          pop eax
  309.          mov byte ptr [eax + ebx], dl
  310.          add ebx, 1
  311.      .elseif (LoopCounter == 8) ;if we are reading variable Direction then
  312.          push eax
  313.          push ebx
  314.          Invoke MIRandom, 0, 8   ;Generate a random direction
  315.          mov edx, eax
  316.          pop ebx
  317.          pop eax
  318.          mov byte ptr [eax + ebx], dl
  319.          add ebx, 1
  320.      .else ;For cords variable...
  321.          push eax
  322.          push ebx
  323.          Invoke MIRandom, 0, 0FFh   ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
  324.          mov edx, eax
  325.          pop ebx
  326.          pop eax
  327.          mov byte ptr [eax + ebx], dl
  328.          add ebx, 1
  329.      .endif
  330.      .Elseif (LoopCounter == 0) ;If we are reading MonsterIndex variable and dont found it randome then
  331.             add ebx, 2 ;Add ebx 2 for not read his next byte
  332.          .Else ;In case that any other variable is not random just add 1 to avoid it
  333.             add ebx, 1
  334.          .Endif
  335.      add LoopCounter, 1
  336.    .Until (LoopCounter == RepTimesForSpots - 1) ;Avoid the variable "MonsterType"
  337.        mov LoopCounter, 0
  338.        pop ecx ;Return ecx
  339.        add ebx, SizeOf MONSTER_SETBASE.MonsterType + SizeOf MONSTER_SETBASE.Quantity ;Avoid reading "MonsterType" & "Quantity" variable
  340.        add ecx, 1
  341.     .Until (ecx == vMobCounter)
  342. ;---------------------------------------------------------------------------------------------
  343. ;LETS ADJUST THE CORDX AND CORDY WITH WEBZEN CALCULATION TO ALL MOBS INPUT:
  344. ;(CordX-3) + (RandNumb[0 _ 7]) = FinalCordX
  345. ;(CordY-3) + (RandNumb[0 _ 7]) = FinalCordY
  346. ;---------------------------------------------------------------------------------------------
  347.     xor ecx, ecx
  348.     mov eax, pObject
  349.    .Repeat
  350.        push ecx ;Save has a loop counter
  351.    movsx edx, byte ptr [eax].CordX
  352.    sub edx, 3
  353.    push eax
  354.    push edx
  355.    Invoke MIRandom, 0, 7h   ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
  356.    pop edx
  357.    add edx, eax
  358.    pop eax
  359.    mov [eax].CordX, dl
  360.    movsx edx, byte ptr [eax].CordY
  361.    sub edx, 3
  362.    push eax
  363.    push edx
  364.    Invoke MIRandom, 0, 7h   ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
  365.    pop edx
  366.    add edx, eax
  367.    pop eax
  368.    mov [eax].CordY, dl
  369.        pop ecx ;Return ecx
  370.        add eax, SizeOf MONSTER_SETBASE
  371.        add ecx, 1
  372.    .Until (ecx == vMobCounter)
  373.   .Else ;If we have an error on Valid Map
  374.     RGB 24, 116, 205
  375.     Mov Edx, Eax
  376.     pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
  377.     movsx ecx, [eax].MapNumber
  378.     movsx ebx, [eax].MonsterType
  379.     Invoke vprint, $CTA0("MonsterSetBase:] Error, INVALID MAP : [%d] for MONSTER : [%d]"), Edx, 2, ecx, ebx
  380.     mov ecx, FilePosition
  381.     .Continue ;We ignore that mob request and dislay an error
  382.   .Endif
  383.  .ELSE
  384.  .ENDIF
  385.  .if (vMobCounter != 0) ;If we got more than 1 mob that we load
  386.    mov edx, vMobCounter
  387.    add MonsterSetBaseCounter, edx
  388.  .else
  389.     add MonsterSetBaseCounter, 1
  390.  .endif
  391.  .If (MonsterSetBaseCounter > MAX_SETBASE_MONSTERS)
  392.     RGB 24, 116, 205
  393.     Mov Edx, Eax
  394.     Invoke vprint, $CTA0("MonsterSetBase:] Error you bypass the limit of monsters, modify MAX_SETBASE_MONSTERS constant"), Edx, 0
  395.     .Break
  396.  .endif
  397.  mov ecx, FilePosition
  398.  invoke GetString, pBufferSpace, ecx ;Try to search for "end" string
  399.  push ecx
  400.  invoke szCmp, $CTA0("end"), Addr StringToken ;If end string
  401.  pop ecx
  402.  .if (eax != 0) ;Founded
  403.     mov edx, pBufferSpace
  404.     .if (byte ptr [edx + ecx] == 0) ;If there are 00 byte then its end of file
  405.       mov eax, 1
  406.       .Break
  407.     .endif
  408.     mov vMobTypeActivated, 0 ;Its end of an mob type
  409.     .Continue
  410.  .endif ;If we dont found it
  411.  mov ecx, FilePosition
  412. .Endw ;Continue the loop
  413. .if (eax == 0)
  414.     RGB 24, 116, 205
  415.     Mov Edx, Eax
  416.     Invoke vprint, $CTA0("MonsterSetBase:] Unexpected error while loading monsters, last monster loaded : [%d]"), Edx, 1, MonsterSetBaseCounter
  417. .else
  418.     RGB 24, 116, 205
  419.     Mov Edx, Eax
  420.     Invoke vprint, $CTA0("MonsterSetBase:] All monsters loeaded, total monsters : [%d]"), Edx, 1, MonsterSetBaseCounter
  421. .endif
  422. FastDeAlloc pBufferSpace, NULL, 0 ;Free the heap when we dont use it anymore
  423. assume eax:NOTHING
  424. Ret
  425. V_MonsterSetBase_Load EndP
  426. ;////////////////////////////////////////////////////////////////////////////////////
  427. ; Simple easy to understand procedure for load MonsterAttr in a new syntax
  428. ; And with one new option for mod the universal HP calculation of Webzen.
  429. ; Also this procedure is loop based system too.
  430. ;////////////////////////////////////////////////////////////////////////////////////
  431. V_MonsterAttr_Load Proc
  432. local LoopCounter:Dword
  433. local FilePosition:Dword
  434. local BytesReaded:Dword
  435. local pBufferSpace:Dword
  436. local StructFile:WIN32_FILE_ATTRIBUTE_DATA
  437. .Const
  438. RepTimesForResistance equ 4 ;Load 4 resistance types
  439. RepTimesForMonsterAttr equ 24 ;Load 24 monster attributes
  440. .Code
  441. And LoopCounter, 0
  442. And FilePosition, 0
  443. ;-------------------------------
  444. ;Load file into memory
  445. ;-------------------------------
  446. lea edx, StructFile
  447. GetFileLength addr szMonsterAttr, edx
  448. mov eax, StructFile.nFileSizeLow
  449. fastalloc eax, 1 ;alloc space for file
  450. mov pBufferSpace, eax
  451. lea ecx, BytesReaded
  452. ReadThisFile Addr szMonsterAttr, pBufferSpace, ecx ;read of file and handles the close
  453. mov ecx, StructFile.nFileSizeLow
  454. add eax, ecx
  455. mov dword ptr [eax], 0 ;Append to 00 byte in the end of file for prevent bugs
  456. xor ecx, ecx
  457. assume eax:ptr MONSTER_ATTRIBUTE
  458. ;---------------------------------------------------------------------------------------------
  459. ;Take UniversalModHP constant !
  460. ;---------------------------------------------------------------------------------------------
  461. invoke GetString, pBufferSpace, ecx ;Take the string "UniversalModHP"
  462. .if (edx == 1)
  463.   xor eax, eax
  464.   jmp TerminateRead
  465. .endif
  466. invoke GetToken, pBufferSpace, ecx, NULL
  467. .if (edx == 1)
  468.   xor eax, eax
  469.  jmp TerminateRead
  470. .endif
  471. mov UniversalModHP, eax
  472. ;---------------------------------------------------------------------------------------------
  473. ; Begin of big loop for take data of all Monster and make calculations
  474. ;---------------------------------------------------------------------------------------------
  475. .While (ecx != -1) ;Infinite loop
  476. ;---------------------------------------------------------------------------------------------
  477. ;If you like to put "end" string for terminate
  478. ;read in Monster.txt then comment the parts below
  479. ;---------------------------------------------------------------------------------------------
  480.    invoke GetString, pBufferSpace, ecx ;Take monster name
  481.    .if (edx == 1) ;If end of file (If you like to put END string comment this part)
  482.      mov eax, 1 ;Comment this part
  483.      .break ;Comment this part
  484.    .endif ;Comment this part
  485. ;------------------------------------------------------------------
  486. ;---------------------------------------------------------------------------------------------
  487. ;If you like to put "end" string for terminate
  488. ;read in Monster.txt then unmark the commentaries below
  489. ;---------------------------------------------------------------------------------------------
  490. ;   push ecx
  491. ;   invoke szCmp, $CTA0("end"), Addr StringToken ;If end string
  492. ;   pop ecx
  493. ;   .if (eax == 1)
  494. ;    mov eax, 1
  495. ;    .break
  496. ;   .endif
  497. ;----------------------------------------------------------------
  498.    pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
  499.    push ecx
  500.    invoke lstrcat, addr [eax].MonsterName, addr StringToken
  501.    pop ecx
  502. ;---------------------------------------------------------------------------------------------
  503. ;Optimised loop for load Monster attributes, that are 21 for now
  504. ;if you want to expand then expand also the constant and dont edit the loop.
  505. ;Dont forget to add the new atributes to the struct and Monster.txt file !
  506. ;---------------------------------------------------------------------------------------------
  507.    mov ebx, SizeOf MONSTER_ATTRIBUTE.MonsterName ;Avoid rewritting in MonsterName
  508.    .repeat
  509.      push ebx ;Save EBX
  510.      invoke GetToken, pBufferSpace, ecx, NULL
  511.      pop ebx ;Return EBX
  512.      .if (edx == 1)
  513.        xor eax, eax
  514.        .break
  515.      .endif
  516.      mov edx, eax
  517.      pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
  518.      mov [eax + ebx], edx
  519.      add ebx, 4
  520.      add LoopCounter, 1
  521.    .Until (LoopCounter == RepTimesForMonsterAttr) ;Load from Index to MonsterSkill
  522.    mov LoopCounter, 0
  523. ;---------------------------------------------------------------------------------------------
  524. ;Optimised loop for load Monster resistances, that are 4 for now
  525. ;if you want to expand then expand also the constant and dont edit the loop.
  526. ;Dont forget to add the new resistances to the struct and Monster.txt file !
  527. ;---------------------------------------------------------------------------------------------
  528.    .repeat
  529.      push ebx ;Save EBX
  530.      invoke GetToken, pBufferSpace, ecx, NULL
  531.      pop ebx ;Return EBX
  532.      .if (edx == 1)
  533.        xor eax, eax
  534.        .break
  535.      .endif
  536.      mov edx, eax
  537.      pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
  538.      mov [eax + ebx], dl ;Save resistance byte
  539.      add ebx, 1
  540.      add LoopCounter, 1
  541.    .until (LoopCounter == RepTimesForResistance)
  542.    mov LoopCounter, 0
  543.    mov FilePosition, ecx
  544. ;---------------------------------------------------------------------------------------------
  545. ;Some calcs for universal HP
  546. ;FinalHP = HP - (HP/100*100) (stupid but you can edit in file)
  547. ;---------------------------------------------------------------------------------------------
  548.    pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
  549.    push eax
  550.    mov eax, [eax].HP
  551.    xor edx, edx ;Optimised instead of CDQ
  552.    imul eax, UniversalModHP
  553.    mov ecx, 100
  554.    idiv ecx
  555.    mov edx, eax
  556.    pop eax ;Return struct
  557.    sub [eax].HP, edx ;(HP/100*UniversalModHP) - HP
  558.    mov [eax].ScriptHP, edx
  559.    .IF ([eax].Level < 19 && [eax].MonsterIndex < 50) || ([eax].Level < 24 && [eax].MonsterIndex < 50)
  560.       .IF [eax].Level == 12 || [eax].Level == 13 || [eax].Level <= 17 || [eax].Level > 19 || [eax].Level == 24
  561. ;---------------------------------------------------------------------------------------------
  562. ;Edit HP depending of monster level
  563. ;FinalHP =  HP - (HP*20/100)*100/100
  564. ;---------------------------------------------------------------------------------------------
  565.         push eax
  566.         xor edx, edx ;Optimised instead of CDQ
  567.         mov eax, [eax].HP
  568.         imul eax, eax, 20
  569.         mov ecx, 100
  570.         idiv ecx ;NewHP == HP*20/100
  571.         xor edx, edx ;Optimised instead of CDQ
  572.         push eax
  573.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  574.         mov ecx, 100
  575.         idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
  576.         pop edx ;Return NewHP
  577.         sub edx, eax ; ModedHP = NewHP - NewHP2
  578.         pop eax ;Return struct
  579.         sub [eax].HP, edx ;FinalHP = ModedHP - HP
  580. ;---------------------------------------------------------------------------------------------
  581. ;Edit DamageMin depending of monster level
  582. ;DamageMin =  DMGMin - (DMGMin*30/100)*100/100
  583. ;---------------------------------------------------------------------------------------------
  584.         push eax
  585.         xor edx, edx ;Optimised instead of CDQ
  586.         mov eax, [eax].DamageMin
  587.         imul eax, eax, 30
  588.         mov ecx, 100
  589.         idiv ecx ; NewDMGMin = DamageMin*30/100
  590.         xor edx, edx ;Optimised instead of CDQ
  591.         push eax
  592.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  593.         mov ecx, 100
  594.         idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
  595.         pop edx ;Return NewDMGMin
  596.         sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
  597.         pop eax ;Return struct
  598.         sub [eax].DamageMin, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
  599. ;---------------------------------------------------------------------------------------------
  600. ;Edit DamageMax depending of monster level
  601. ;DamageMax =  DMGMax - (DMGMax*30/100)*100/100
  602. ;---------------------------------------------------------------------------------------------
  603.         push eax
  604.         xor edx, edx ;Optimised instead of CDQ
  605.         mov eax, [eax].DamageMax
  606.         imul eax, eax, 30
  607.         mov ecx, 100
  608.         idiv ecx ; NewDMGMin = DamageMin*30/100
  609.         xor edx, edx ;Optimised instead of CDQ
  610.         push eax
  611.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  612.         mov ecx, 100
  613.         idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
  614.         pop edx ;Return NewDMGMin
  615.         sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
  616.         pop eax ;Return struct
  617.         sub [eax].DamageMax, edx ;FinalDamgeMax = DamageMax - ModedDMGMax
  618.       .ELSEIF ([eax].Level == 20) || ([eax].Level == 22)
  619. ;---------------------------------------------------------------------------------------------
  620. ;Edit HP calculation in base of level
  621. ;FinalHP =  HP - (HP*30/100)*100/100
  622. ;---------------------------------------------------------------------------------------------
  623.         push eax
  624.         xor edx, edx ;Optimised instead of CDQ
  625.         mov eax, [eax].HP
  626.         imul eax, eax, 30
  627.         mov ecx, 100
  628.         idiv ecx ;NewHP == HP*30/100
  629.         xor edx, edx ;Optimised instead of CDQ
  630.         push eax
  631.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  632.         mov ecx, 100
  633.         idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
  634.         pop edx ;Return NewHP
  635.         sub edx, eax ; ModedHP = NewHP - NewHP2
  636.         pop eax ;Return struct
  637.         sub [eax].HP, edx ;FinalHP = ModedHP - HP
  638.      .ELSE
  639. ;---------------------------------------------------------------------------------------------
  640. ;Edit HP calculation in base of level
  641. ;---------------------------------------------------------------------------------------------
  642.         push eax
  643.         mov eax, [eax].HP
  644.         shr eax, 1 ;optimisation of /2
  645.         xor edx, edx ;Optimised instead of CDQ
  646.         push eax ;NewHP
  647.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  648.         mov ecx, 100
  649.         idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
  650.         pop edx ;Return NewHP
  651.         sub edx, eax ; ModedHP = NewHP - NewHP2
  652.         pop eax ;Return struct
  653.         sub [eax].HP, edx ;FinalHP = ModedHP - HP
  654. ;---------------------------------------------------------------------------------------------
  655. ;Edit DamageMin depending of monster level
  656. ;DamageMin =  DMGMin - (DMGMin/2)*100/100
  657. ;---------------------------------------------------------------------------------------------
  658.         push eax
  659.         mov eax, [eax].DamageMin
  660.         shr eax, 1 ;optimisation of /2
  661.         xor edx, edx ;Optimised instead of CDQ
  662.         push eax ;NewDMGMin
  663.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  664.         mov ecx, 100
  665.         idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
  666.         pop edx ;Return NewDMGMin
  667.         sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
  668.         pop eax ;Return struct
  669.         sub [eax].DamageMin, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
  670. ;---------------------------------------------------------------------------------------------
  671. ;Edit DamageMax depending of monster level
  672. ;DamageMax =  DMGMax - (DMGMax/2)*100/100
  673. ;---------------------------------------------------------------------------------------------
  674.         push eax
  675.         mov eax, [eax].DamageMax
  676.         shr eax, 1 ;optimisation of /2
  677.         xor edx, edx ;Optimised instead of CDQ
  678.         push eax ;NewDMGMin
  679.         imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
  680.         mov ecx, 100
  681.         idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
  682.         pop edx ;Return NewDMGMin
  683.         sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
  684.         pop eax ;Return struct
  685.         sub [eax].DamageMax, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
  686.      .ENDIF
  687.   .ENDIF
  688.   mov ecx, FilePosition
  689.   add MonsterCounter, 1
  690.   .If (MonsterCounter > MAX_MONSTERS_ATTR)
  691.     RGB 24, 116, 205
  692.     Mov Edx, Eax
  693.     Invoke vprint, $CTA0("MonsterAttr:] Error you bypass the limit of monsters, modify MAX_MONSTERS constant"), Edx, 0
  694.     mov eax, 1
  695.     .break
  696.   .else
  697.    .Continue ; Go back to the loop bitch !
  698.   .endif
  699. .Endw
  700. TerminateRead:
  701. .if (eax == 0)
  702.     RGB 24, 116, 205
  703.     Mov Edx, Eax
  704.     Invoke vprint, $CTA0("MonsterAttr:] Unexpected error while loading monsters, last monster loaded : [%d]"), Edx, 1, MonsterCounter
  705. .else
  706.     RGB 24, 116, 205
  707.     Mov Edx, Eax
  708.     Invoke vprint, $CTA0("MonsterAttr:] All monsters loeaded, total monsters : [%d]"), Edx, 1, MonsterCounter
  709. .endif
  710. FastDeAlloc pBufferSpace, NULL, 0 ;Free the heap when we dont use it anymore
  711. assume eax:NOTHING
  712. Ret
  713. V_MonsterAttr_Load EndP