V-MonsterLoad.asm
资源名称:VeMU.rar [点击查看]
上传用户:santakups8
上传日期:2021-03-23
资源大小:544k
文件大小:30k
源码类别:
模拟服务器
开发平台:
Asm
- ;EasyCodeName=Module1,1
- ;-----------------------------------------------------------------------------------
- ; VeMU
- ; Its a package that allows the user to set his own server of the game
- ; "MuOnline", this is not an emulator since i am not "emulating"
- ; what the actual games does, i am "creating" a method for set a Server
- ; of this Game.
- ;
- ; Copyright (C) 2010 Felipe Ya馿z
- ;
- ; This program is free software: you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation, either version 3 of the License, or
- ; (at your option) any later version.
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program. If not, see http://www.gnu.org/licenses/.
- ;-----------------------------------------------------------------------------------
- ;-----------------------------------------------------------------------------------
- ; -----------------
- ; Coded /
- ; By /
- ; -={FeN$x)=-
- ; / Felipe Y.
- ; /
- ; -----------------
- ; Programming Lang: ASM
- ; Country: Chile
- ; My respect for all those who lost their lifes
- ; In the earthquake of my country...
- ; Let god take their spirits home...
- ;-----------------------------------------------------------------------------------
- ;////////////////////////////////////////////////////////////////////////////////////
- ; VeMU Project
- ; Monster Load !
- ;////////////////////////////////////////////////////////////////////////////////////
- .Const
- .Data?
- .Data
- szMonsterAttr DB ".DataGamePlayMonstersMonster.txt", 0
- szMonsterSetBase DB ".DataGamePlayMonstersMonsterSetBase.txt", 0
- .Code
- ;////////////////////////////////////////////////////////////////////////////////////
- ; Very complex procedure that loads MonsterSetBase in the same sintax has
- ; Webzen do, with the only difference this procedure is based in the loop system
- ; That define the style of this project. This allows to add new variables
- ; and edit limits without touching the procedure.
- ; TRY TO DONT EDIT THIS PROCEDURE !
- ;////////////////////////////////////////////////////////////////////////////////////
- V_MonsterSetBase_Load Proc
- local vMobTypeActivated:Dword ;Activate if we read a mobtype
- local vMobType:Dword
- local vMobCounter:Dword ;Counter for mobs in local mode
- local FilePosition:Dword ;File position
- local LoopCounter:Dword ;Loop counter for multiple uses
- Local pObject:Dword ;For dont calculate each time with macros
- local pBufferSpace:Dword
- local BytesReaded:Dword
- local StructFile:WIN32_FILE_ATTRIBUTE_DATA
- .Const
- RepTimesForSingles equ 6 ;Load 6 monster set base variables
- RepTimesForSpots equ 9 ;Load 9 monster set base variables
- .Code
- mov LoopCounter, 0
- mov FilePosition, 0
- mov vMobTypeActivated, 0
- rdtsc
- Invoke MRandomInit, Eax ;Initialize random number generator
- ;-------------------------------
- ;Load file into memory
- ;-------------------------------
- lea edx, StructFile
- GetFileLength addr szMonsterSetBase, edx
- mov eax, StructFile.nFileSizeLow
- fastalloc eax, 1 ;alloc space for file
- mov pBufferSpace, eax
- lea ecx, BytesReaded
- ReadThisFile Addr szMonsterSetBase, pBufferSpace, ecx ;read of file and handles the close
- mov ecx, StructFile.nFileSizeLow
- add eax, ecx
- mov dword ptr [eax], 0 ;Append to 00 byte in the end of file for prevent bugs
- xor ecx, ecx
- xor edx, edx
- assume eax:ptr MONSTER_SETBASE
- ;---------------------------------------------------------------------------------------------
- ; Begin of big loop for take data of all Monster bases
- ;---------------------------------------------------------------------------------------------
- .While (ecx != -1) ;Infinite loop
- ;---------------------------------------------------------------------------------------------
- ;CHECK IF WE CHANGE OF MOBTYPE OR IF WE CONTINUE WITH THE SAME !
- ;---------------------------------------------------------------------------------------------
- .If (vMobTypeActivated == 0)
- invoke GetToken, pBufferSpace, ecx, NULL ;Read MonsterType variable
- .If (edx == 1)
- xor eax, eax
- .break
- .Endif
- mov edx, eax
- pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
- mov pObject, eax
- mov [eax].MonsterType, dl
- mov vMobType, edx
- mov vMobTypeActivated, 1
- .Else
- pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
- mov pObject, eax
- mov edx, vMobType
- mov [eax].MonsterType, dl
- .Endif
- ;---------------------------------------------------------------------------------------------
- ;---------------------------------------------------------------------------------------------
- ;CHECK FOR NPC MONSTER TYPE OR SINGLE MONSTER TYPE
- ;---------------------------------------------------------------------------------------------
- .IF ([eax].MonsterType == NPCMONSTER) || ([eax].MonsterType == SINGLEMONSTER) || ([eax].MonsterType == BLOODMONSTER)
- mov vMobCounter, 0 ;Avoid bugs !
- mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore rewrite
- .Repeat
- push ebx ;Save EBX
- invoke GetToken, pBufferSpace, ecx, NULL
- pop ebx
- .if (edx == 1)
- xor eax, eax
- .break
- .endif
- mov edx, eax
- mov eax, pObject
- .if (LoopCounter == 0) ;If we reading variable "MobIndex"
- mov word ptr [eax + ebx], dx ;Save MobIndex that use 2 bytes
- add ebx, 2 ;Uses 2 bytes
- .else
- mov [eax + ebx], dl ;Save rest of variables that use 1 byte
- add ebx, 1
- .endif
- add LoopCounter, 1
- .until (LoopCounter == RepTimesForSingles)
- mov LoopCounter, 0
- mov FilePosition, ecx
- ;---------------------------------------------------------------------------------------------
- ;LETS DO SOME FIXES AND ADD NEW OPTIONS TO THE ALREADY EXISTING ONES !
- ;ONLY FOR NPCs TYPE MOB, SINGLE TYPE MOB, BLOOD CASTLE, GATES, EVENTS THAT
- ;NEED ANY SINGULARITY MOBS OR STATICS
- ;---------------------------------------------------------------------------------------------
- mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore it, it cant be random
- .repeat
- .if (LoopCounter == 0) && (word ptr [eax + ebx] == 0FFFFh)
- push eax
- push ebx
- Invoke MIRandom, 0, MonsterCounter ;Generate a random index based in the total ammount of MonstersAttr that we read
- mov edx, eax
- pop ebx
- pop eax
- mov word ptr [eax + ebx], dx
- add ebx, 2 ;uses 2 bytes
- .elseif (LoopCounter != 0) && (byte ptr [eax + ebx] == 0FFh)
- .if (LoopCounter == 1) ;If we are reading variable MapNumber then...
- push eax
- push ebx
- Invoke MIRandom, 0, MAPLIMIT ;Generate a random map
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .elseif (LoopCounter == 2) ;If we are reading variable Distance then
- push eax
- push ebx
- Invoke MIRandom, 0, 3 ;Generate a random distance
- shl eax, 4 ;Random number*10 = Final Distance
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .elseif (LoopCounter == 5) ;if we are reading variable Direction then
- push eax
- push ebx
- Invoke MIRandom, 0, 8 ;Generate a random direction
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .else ;For cords variable...
- push eax
- push ebx
- Invoke MIRandom, 0, 0FFh ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .endif
- .elseif (LoopCounter == 0) ;If we are reading MonsterIndex variable and dont found it randome then
- add ebx, 2 ;Add ebx 2 for not read his next byte
- .else ;In case that any other variable is not random just add 1 to avoid it
- add ebx, 1
- .endif
- add LoopCounter, 1
- .until (LoopCounter == RepTimesForSingles)
- mov LoopCounter, 0 ;Avoid bugs !
- .ELSEIF ([eax].MonsterType == SPOTSMONSTER) || ([eax].MonsterType == EVENTMONSTER) || ([eax].MonsterType == GOLDENMONSTER)
- ;---------------------------------------------------------------------------------------------
- ;CHECK FOR SPOTS MONSTERS, GOLDEN MONSTERS & DEVILSQUARE (possible kanturu)
- ;---------------------------------------------------------------------------------------------
- mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Ignore rewrite
- .Repeat
- push ebx ;Save EBX
- invoke GetToken, pBufferSpace, ecx, NULL
- pop ebx ;Return EBX
- .if (edx == 1)
- xor eax, eax
- .break
- .endif
- mov edx, eax
- mov eax, pObject
- .if (LoopCounter == 0) ;If we reading variable "MobIndex"
- mov word ptr [eax + ebx], dx ;Save MobIndex that use 2 bytes
- add ebx, 2 ;Uses 4 bytes
- .else
- mov [eax + ebx], dl ;Save rest of variables that use 1 byte
- add ebx, 1
- .endif
- add LoopCounter, 1
- .until (LoopCounter == RepTimesForSpots)
- mov LoopCounter, 0
- mov FilePosition, ecx
- ;---------------------------------------------------------------------------------------------
- ;LETS DO SOME FIXES AND ADD NEW OPTIONS TO THE ALREADY EXISTING ONES !
- ;ONLY FOR SPOTS MONSTERS, GOLDEN MONSTERS & DEVILSQUARE (possible kanturu)
- ;FOR ANY EVENT THAT NEEDS ALOT OF MONSTERS
- ;---------------------------------------------------------------------------------------------
- ; push eax
- ; invoke V_CMap_CheckValidMap, [eax].MapNumber ;Check if we put a valid map
- ; mov edx, eax
- ; pop eax
- .If (ecx != -1)
- .If ([eax].Quantity == -1) ;Means random
- push eax
- Invoke MIRandom, 1, MAX_SETBASE_RAND_MOBS ;Generate a random number of monster to be created
- mov edx, eax
- pop eax
- mov byte ptr [eax].Quantity, dl
- .Endif
- movsx edx, byte ptr [eax].Quantity
- .if (edx == 1) ;If quantity is 1 then i dont sub it
- .else
- sub edx, 1 ;Quantity - 1 caused we dont start reading from "1" we start reading from "0" (and thats considered has 1)
- .endif
- mov vMobCounter, edx
- mov ecx, SizeOf MONSTER_SETBASE
- xor ebx, ebx
- ;---------------------------------------------------------------------------------------------
- ;Copy the quantity of monsters and loop for fix all details !
- ;---------------------------------------------------------------------------------------------
- .Repeat
- push eax
- push ecx
- push ebx
- lea edx, [eax + ecx]
- invoke MemCopy, eax, edx, SizeOf MONSTER_SETBASE ;Copy Monster
- pop ebx
- pop ecx
- pop eax
- add ecx, SizeOf MONSTER_SETBASE
- add ebx, 1
- .Until (ebx == vMobCounter)
- add vMobCounter, 1 ;We restore the original value, for reading the buffers below
- ;---------------------------------------------------------------------------------------------
- mov ebx, SizeOf MONSTER_SETBASE.MonsterType ;Avoid checking if its random or not
- xor ecx, ecx
- ;---------------------------------------------------------------------------------------------
- ;Get all variables and check if they are random or not ! (FOR ALL MOBS)
- ;---------------------------------------------------------------------------------------------
- .Repeat
- push ecx ;Save it has a loop counter
- .Repeat
- .If (LoopCounter == 0) && (word ptr [eax + ebx] == 0FFFFh)
- push eax
- push ebx
- Invoke MIRandom, 0, MonsterCounter ;Generate a random index based in the total ammount of MonstersAttr that we read
- mov edx, eax
- pop ebx
- pop eax
- mov word ptr [eax + ebx], dx
- add ebx, 2 ;uses 2 bytes
- .Elseif (LoopCounter != 0) && (byte ptr [eax + ebx] == 0FFh)
- .if (LoopCounter == 1) ;If we are reading variable MapNumber then...
- push eax
- push ebx
- Invoke MIRandom, 0, MAPLIMIT ;Generate a random map
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .elseif (LoopCounter == 2) ;If we are reading variable Distance then
- push eax
- push ebx
- Invoke MIRandom, 0, 3 ;Generate a random distance
- shl eax, 4 ;Random number*10 = Final Distance
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .elseif (LoopCounter == 8) ;if we are reading variable Direction then
- push eax
- push ebx
- Invoke MIRandom, 0, 8 ;Generate a random direction
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .else ;For cords variable...
- push eax
- push ebx
- Invoke MIRandom, 0, 0FFh ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
- mov edx, eax
- pop ebx
- pop eax
- mov byte ptr [eax + ebx], dl
- add ebx, 1
- .endif
- .Elseif (LoopCounter == 0) ;If we are reading MonsterIndex variable and dont found it randome then
- add ebx, 2 ;Add ebx 2 for not read his next byte
- .Else ;In case that any other variable is not random just add 1 to avoid it
- add ebx, 1
- .Endif
- add LoopCounter, 1
- .Until (LoopCounter == RepTimesForSpots - 1) ;Avoid the variable "MonsterType"
- mov LoopCounter, 0
- pop ecx ;Return ecx
- add ebx, SizeOf MONSTER_SETBASE.MonsterType + SizeOf MONSTER_SETBASE.Quantity ;Avoid reading "MonsterType" & "Quantity" variable
- add ecx, 1
- .Until (ecx == vMobCounter)
- ;---------------------------------------------------------------------------------------------
- ;LETS ADJUST THE CORDX AND CORDY WITH WEBZEN CALCULATION TO ALL MOBS INPUT:
- ;(CordX-3) + (RandNumb[0 _ 7]) = FinalCordX
- ;(CordY-3) + (RandNumb[0 _ 7]) = FinalCordY
- ;---------------------------------------------------------------------------------------------
- xor ecx, ecx
- mov eax, pObject
- .Repeat
- push ecx ;Save has a loop counter
- movsx edx, byte ptr [eax].CordX
- sub edx, 3
- push eax
- push edx
- Invoke MIRandom, 0, 7h ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
- pop edx
- add edx, eax
- pop eax
- mov [eax].CordX, dl
- movsx edx, byte ptr [eax].CordY
- sub edx, 3
- push eax
- push edx
- Invoke MIRandom, 0, 7h ;Generate a random cord between 0 and 255, you can edit this if you think cord 0 is risky
- pop edx
- add edx, eax
- pop eax
- mov [eax].CordY, dl
- pop ecx ;Return ecx
- add eax, SizeOf MONSTER_SETBASE
- add ecx, 1
- .Until (ecx == vMobCounter)
- .Else ;If we have an error on Valid Map
- RGB 24, 116, 205
- Mov Edx, Eax
- pObj MonsterSetBaseCounter, SizeOf MONSTER_SETBASE, pObjMonsterSetBase
- movsx ecx, [eax].MapNumber
- movsx ebx, [eax].MonsterType
- Invoke vprint, $CTA0("MonsterSetBase:] Error, INVALID MAP : [%d] for MONSTER : [%d]"), Edx, 2, ecx, ebx
- mov ecx, FilePosition
- .Continue ;We ignore that mob request and dislay an error
- .Endif
- .ELSE
- .ENDIF
- .if (vMobCounter != 0) ;If we got more than 1 mob that we load
- mov edx, vMobCounter
- add MonsterSetBaseCounter, edx
- .else
- add MonsterSetBaseCounter, 1
- .endif
- .If (MonsterSetBaseCounter > MAX_SETBASE_MONSTERS)
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterSetBase:] Error you bypass the limit of monsters, modify MAX_SETBASE_MONSTERS constant"), Edx, 0
- .Break
- .endif
- mov ecx, FilePosition
- invoke GetString, pBufferSpace, ecx ;Try to search for "end" string
- push ecx
- invoke szCmp, $CTA0("end"), Addr StringToken ;If end string
- pop ecx
- .if (eax != 0) ;Founded
- mov edx, pBufferSpace
- .if (byte ptr [edx + ecx] == 0) ;If there are 00 byte then its end of file
- mov eax, 1
- .Break
- .endif
- mov vMobTypeActivated, 0 ;Its end of an mob type
- .Continue
- .endif ;If we dont found it
- mov ecx, FilePosition
- .Endw ;Continue the loop
- .if (eax == 0)
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterSetBase:] Unexpected error while loading monsters, last monster loaded : [%d]"), Edx, 1, MonsterSetBaseCounter
- .else
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterSetBase:] All monsters loeaded, total monsters : [%d]"), Edx, 1, MonsterSetBaseCounter
- .endif
- FastDeAlloc pBufferSpace, NULL, 0 ;Free the heap when we dont use it anymore
- assume eax:NOTHING
- Ret
- V_MonsterSetBase_Load EndP
- ;////////////////////////////////////////////////////////////////////////////////////
- ; Simple easy to understand procedure for load MonsterAttr in a new syntax
- ; And with one new option for mod the universal HP calculation of Webzen.
- ; Also this procedure is loop based system too.
- ;////////////////////////////////////////////////////////////////////////////////////
- V_MonsterAttr_Load Proc
- local LoopCounter:Dword
- local FilePosition:Dword
- local BytesReaded:Dword
- local pBufferSpace:Dword
- local StructFile:WIN32_FILE_ATTRIBUTE_DATA
- .Const
- RepTimesForResistance equ 4 ;Load 4 resistance types
- RepTimesForMonsterAttr equ 24 ;Load 24 monster attributes
- .Code
- And LoopCounter, 0
- And FilePosition, 0
- ;-------------------------------
- ;Load file into memory
- ;-------------------------------
- lea edx, StructFile
- GetFileLength addr szMonsterAttr, edx
- mov eax, StructFile.nFileSizeLow
- fastalloc eax, 1 ;alloc space for file
- mov pBufferSpace, eax
- lea ecx, BytesReaded
- ReadThisFile Addr szMonsterAttr, pBufferSpace, ecx ;read of file and handles the close
- mov ecx, StructFile.nFileSizeLow
- add eax, ecx
- mov dword ptr [eax], 0 ;Append to 00 byte in the end of file for prevent bugs
- xor ecx, ecx
- assume eax:ptr MONSTER_ATTRIBUTE
- ;---------------------------------------------------------------------------------------------
- ;Take UniversalModHP constant !
- ;---------------------------------------------------------------------------------------------
- invoke GetString, pBufferSpace, ecx ;Take the string "UniversalModHP"
- .if (edx == 1)
- xor eax, eax
- jmp TerminateRead
- .endif
- invoke GetToken, pBufferSpace, ecx, NULL
- .if (edx == 1)
- xor eax, eax
- jmp TerminateRead
- .endif
- mov UniversalModHP, eax
- ;---------------------------------------------------------------------------------------------
- ; Begin of big loop for take data of all Monster and make calculations
- ;---------------------------------------------------------------------------------------------
- .While (ecx != -1) ;Infinite loop
- ;---------------------------------------------------------------------------------------------
- ;If you like to put "end" string for terminate
- ;read in Monster.txt then comment the parts below
- ;---------------------------------------------------------------------------------------------
- invoke GetString, pBufferSpace, ecx ;Take monster name
- .if (edx == 1) ;If end of file (If you like to put END string comment this part)
- mov eax, 1 ;Comment this part
- .break ;Comment this part
- .endif ;Comment this part
- ;------------------------------------------------------------------
- ;---------------------------------------------------------------------------------------------
- ;If you like to put "end" string for terminate
- ;read in Monster.txt then unmark the commentaries below
- ;---------------------------------------------------------------------------------------------
- ; push ecx
- ; invoke szCmp, $CTA0("end"), Addr StringToken ;If end string
- ; pop ecx
- ; .if (eax == 1)
- ; mov eax, 1
- ; .break
- ; .endif
- ;----------------------------------------------------------------
- pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
- push ecx
- invoke lstrcat, addr [eax].MonsterName, addr StringToken
- pop ecx
- ;---------------------------------------------------------------------------------------------
- ;Optimised loop for load Monster attributes, that are 21 for now
- ;if you want to expand then expand also the constant and dont edit the loop.
- ;Dont forget to add the new atributes to the struct and Monster.txt file !
- ;---------------------------------------------------------------------------------------------
- mov ebx, SizeOf MONSTER_ATTRIBUTE.MonsterName ;Avoid rewritting in MonsterName
- .repeat
- push ebx ;Save EBX
- invoke GetToken, pBufferSpace, ecx, NULL
- pop ebx ;Return EBX
- .if (edx == 1)
- xor eax, eax
- .break
- .endif
- mov edx, eax
- pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
- mov [eax + ebx], edx
- add ebx, 4
- add LoopCounter, 1
- .Until (LoopCounter == RepTimesForMonsterAttr) ;Load from Index to MonsterSkill
- mov LoopCounter, 0
- ;---------------------------------------------------------------------------------------------
- ;Optimised loop for load Monster resistances, that are 4 for now
- ;if you want to expand then expand also the constant and dont edit the loop.
- ;Dont forget to add the new resistances to the struct and Monster.txt file !
- ;---------------------------------------------------------------------------------------------
- .repeat
- push ebx ;Save EBX
- invoke GetToken, pBufferSpace, ecx, NULL
- pop ebx ;Return EBX
- .if (edx == 1)
- xor eax, eax
- .break
- .endif
- mov edx, eax
- pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
- mov [eax + ebx], dl ;Save resistance byte
- add ebx, 1
- add LoopCounter, 1
- .until (LoopCounter == RepTimesForResistance)
- mov LoopCounter, 0
- mov FilePosition, ecx
- ;---------------------------------------------------------------------------------------------
- ;Some calcs for universal HP
- ;FinalHP = HP - (HP/100*100) (stupid but you can edit in file)
- ;---------------------------------------------------------------------------------------------
- pObj MonsterCounter, SizeOf MONSTER_ATTRIBUTE, pObjMonsterAttr
- push eax
- mov eax, [eax].HP
- xor edx, edx ;Optimised instead of CDQ
- imul eax, UniversalModHP
- mov ecx, 100
- idiv ecx
- mov edx, eax
- pop eax ;Return struct
- sub [eax].HP, edx ;(HP/100*UniversalModHP) - HP
- mov [eax].ScriptHP, edx
- .IF ([eax].Level < 19 && [eax].MonsterIndex < 50) || ([eax].Level < 24 && [eax].MonsterIndex < 50)
- .IF [eax].Level == 12 || [eax].Level == 13 || [eax].Level <= 17 || [eax].Level > 19 || [eax].Level == 24
- ;---------------------------------------------------------------------------------------------
- ;Edit HP depending of monster level
- ;FinalHP = HP - (HP*20/100)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- xor edx, edx ;Optimised instead of CDQ
- mov eax, [eax].HP
- imul eax, eax, 20
- mov ecx, 100
- idiv ecx ;NewHP == HP*20/100
- xor edx, edx ;Optimised instead of CDQ
- push eax
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
- pop edx ;Return NewHP
- sub edx, eax ; ModedHP = NewHP - NewHP2
- pop eax ;Return struct
- sub [eax].HP, edx ;FinalHP = ModedHP - HP
- ;---------------------------------------------------------------------------------------------
- ;Edit DamageMin depending of monster level
- ;DamageMin = DMGMin - (DMGMin*30/100)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- xor edx, edx ;Optimised instead of CDQ
- mov eax, [eax].DamageMin
- imul eax, eax, 30
- mov ecx, 100
- idiv ecx ; NewDMGMin = DamageMin*30/100
- xor edx, edx ;Optimised instead of CDQ
- push eax
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
- pop edx ;Return NewDMGMin
- sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
- pop eax ;Return struct
- sub [eax].DamageMin, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
- ;---------------------------------------------------------------------------------------------
- ;Edit DamageMax depending of monster level
- ;DamageMax = DMGMax - (DMGMax*30/100)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- xor edx, edx ;Optimised instead of CDQ
- mov eax, [eax].DamageMax
- imul eax, eax, 30
- mov ecx, 100
- idiv ecx ; NewDMGMin = DamageMin*30/100
- xor edx, edx ;Optimised instead of CDQ
- push eax
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
- pop edx ;Return NewDMGMin
- sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
- pop eax ;Return struct
- sub [eax].DamageMax, edx ;FinalDamgeMax = DamageMax - ModedDMGMax
- .ELSEIF ([eax].Level == 20) || ([eax].Level == 22)
- ;---------------------------------------------------------------------------------------------
- ;Edit HP calculation in base of level
- ;FinalHP = HP - (HP*30/100)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- xor edx, edx ;Optimised instead of CDQ
- mov eax, [eax].HP
- imul eax, eax, 30
- mov ecx, 100
- idiv ecx ;NewHP == HP*30/100
- xor edx, edx ;Optimised instead of CDQ
- push eax
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
- pop edx ;Return NewHP
- sub edx, eax ; ModedHP = NewHP - NewHP2
- pop eax ;Return struct
- sub [eax].HP, edx ;FinalHP = ModedHP - HP
- .ELSE
- ;---------------------------------------------------------------------------------------------
- ;Edit HP calculation in base of level
- ;---------------------------------------------------------------------------------------------
- push eax
- mov eax, [eax].HP
- shr eax, 1 ;optimisation of /2
- xor edx, edx ;Optimised instead of CDQ
- push eax ;NewHP
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ;NewHP2 == NewHP*100/100 (isnt that idiot, well for me it is, for Webzen i dont know...)
- pop edx ;Return NewHP
- sub edx, eax ; ModedHP = NewHP - NewHP2
- pop eax ;Return struct
- sub [eax].HP, edx ;FinalHP = ModedHP - HP
- ;---------------------------------------------------------------------------------------------
- ;Edit DamageMin depending of monster level
- ;DamageMin = DMGMin - (DMGMin/2)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- mov eax, [eax].DamageMin
- shr eax, 1 ;optimisation of /2
- xor edx, edx ;Optimised instead of CDQ
- push eax ;NewDMGMin
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
- pop edx ;Return NewDMGMin
- sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
- pop eax ;Return struct
- sub [eax].DamageMin, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
- ;---------------------------------------------------------------------------------------------
- ;Edit DamageMax depending of monster level
- ;DamageMax = DMGMax - (DMGMax/2)*100/100
- ;---------------------------------------------------------------------------------------------
- push eax
- mov eax, [eax].DamageMax
- shr eax, 1 ;optimisation of /2
- xor edx, edx ;Optimised instead of CDQ
- push eax ;NewDMGMin
- imul eax, MOD_HP_VALUE ;Change this value for change the "redundant" calculation
- mov ecx, 100
- idiv ecx ; NewDMGMin2 = NewDMGMin*100/100
- pop edx ;Return NewDMGMin
- sub edx, eax ;ModedDMGMin = NewDMGMin - NewDMGMin2
- pop eax ;Return struct
- sub [eax].DamageMax, edx ;FinalDamgeMin = DamageMin - ModedDMGMin
- .ENDIF
- .ENDIF
- mov ecx, FilePosition
- add MonsterCounter, 1
- .If (MonsterCounter > MAX_MONSTERS_ATTR)
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterAttr:] Error you bypass the limit of monsters, modify MAX_MONSTERS constant"), Edx, 0
- mov eax, 1
- .break
- .else
- .Continue ; Go back to the loop bitch !
- .endif
- .Endw
- TerminateRead:
- .if (eax == 0)
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterAttr:] Unexpected error while loading monsters, last monster loaded : [%d]"), Edx, 1, MonsterCounter
- .else
- RGB 24, 116, 205
- Mov Edx, Eax
- Invoke vprint, $CTA0("MonsterAttr:] All monsters loeaded, total monsters : [%d]"), Edx, 1, MonsterCounter
- .endif
- FastDeAlloc pBufferSpace, NULL, 0 ;Free the heap when we dont use it anymore
- assume eax:NOTHING
- Ret
- V_MonsterAttr_Load EndP