--[[ $Id$ Memory table struct for client database NB, Added memoryReadStringPtr to pawn.lua, in function memoryReadRepeat --]] require "classes" -- -- Implement '__next' metamethod (Lua 5.1) -- local rawnext = next -- Fully compatible with original 'next' function next(t, k) local m = getmetatable(t) local n = m and m.__next or rawnext return n(t, k) end -- Fully compatible with original 'pairs' function pairs(t) return next, t, nil end -- -- A structure in memory -- CMemoryStruct = class() function CMemoryStruct.constructor(self, proc, addr) rawset(self, '_order', {}) rawset(self, '_size', 0) rawset(self, '_address', addr) rawset(self, '_index', 1) local mt = getmetatable(self) -- Make iteration handle fields only mt.__next = function(self, key) if key == nil then self._index = 0 end self._index = self._index + 1 if self._order[self._index] then local name = self._order[self._index] return name, self[name] end return nil end -- Insert fields into order table mt.__newindex = function(t, name, value) table.insert(t._order, name) rawset(t, name, value) end end function CMemoryStruct:Size(nsize) if nsize then self._size = nsize end return self._size end function CMemoryStruct:SizePad(n) local n = n or 4 return self._size + ((n - self._size % n) % n) end -- -- An enum, we would like to instanciate with a direct value as well -- -- val = CMagicCheckFunctionENUM(value) -- I.E. addr is nil -- val = CMagicCheckFunctionENUM(proc, addr) -- CEnum = class(CMemoryStruct, nil, false) function CEnum.constructor(self, proc, addr, map) local value = proc CMemoryStruct.constructor(self, nil, nil) if addr ~= nil then value = tonumber(memoryReadRepeat("int", proc, addr)) end self:Size(4) -- CMemoryStruct uses metamethods, ie set local field w. rawset rawset(self, 'value', value) -- Make ourself printable mt = getmetatable(self) mt.__tostring = function(self) if map[self.value] then return string.format("%s", map[self.value]) else return self.value end end end function CEnum:Set(value) self.value = value end -- -- Bitflags -- CBitFlags = class(CMemoryStruct, nil, false) function CBitFlags.constructor(self, proc, addr, flags) local offset = 0 local res = {} local value CMemoryStruct.constructor(self, proc, addr) for i, flag in pairs(flags) do local shift = (i-1)%32 if shift == 0 then value = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 end if bit32.band(value, bit32.lrotate (0x1, shift)) > 0 then self[flag] = true end end self:Size(offset) return res end -- -- Substruct of the GameObjDbStruct -- CLimitStruct = class(CMemoryStruct, nil, false) function CLimitStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Voc = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Race = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Sex = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Level = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.STR = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.STA = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.INT = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MND = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.AGI = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end -- -- ENUMs of GameObjectMagicCollectStruct, TODO: Make better ENUM class -- CGameObjectClassificationENUM = class(CEnum, nil, false) function CGameObjectClassificationENUM.constructor(self, proc, addr) local enum_map = { [-1] = "None", [0] = "Player", "NPC", "Item", "MagicBase", "BodyObj", "Attribute", "QuestCollect", "QuestDetail", "Title", "KeyItem", "Recipe", "Mine", "Flag", "Image", "QuestNPC", "LearNMagic", "Shop", "Suit", "LuaScript", "Camp", "Treasure", "MagicCollect", "EqRefineAbility", "Zone", "CreateRole", "PE" } CEnum.constructor(self, proc, addr, enum_map) end CPriceTypeENUM = class(CEnum, nil, false) local CPriceTypeENUM_Map = { [-1] = "None", [0] = "GameMoney", "AccountMoney", "BonusMoney", "ItemMoney1", "Honor", "ItemMoney2", "GuildWarEnergy", "GuildWarHonor", "TrialBadge", "Relics" } function CPriceTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CPriceTypeENUM_Map) end CMagicorPhyENUM = class(CEnum, nil, false) local CMagicorPhyENUM_Map = { [0] = "Magical", "Physical", "Equipment", "PetEquipment" } function CMagicorPhyENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicorPhyENUM_Map) end CGameObjectRelationENUM = class(CEnum, nil, false) local CGameObjectRelationENUM_Map = { [0] = "Self", "Member", "SelfPet", "MemberPet", "Friend", "FriendNPC", "Enemy", "Player", "All", "GuildPlayer", "NotGuildPlayer", "CountryPlayer", "NotCountryPlayer", "Corpse", "NPCCorpse", "PlayerCorpse", "Location", "PetOwner", "Wagon", "Plot" } function CGameObjectRelationENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CGameObjectRelationENUM_Map) end CGameObjectMagicEffectRangeENUM = class(CEnum, nil, false) local CGameObjectMagicEffectRangeENUM_Map = { [0] = "Target", "GoodRange", "GoodMember", "BadRange", "AllObjects", "AllPlayers", "AllMonsters", "AllEnemyPlayers", "AllFriendlyPLayers", "Plot" } function CGameObjectMagicEffectRangeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CGameObjectMagicEffectRangeENUM_Map) end CMagicSpellSelectTypeENUM = class(CEnum, nil, false) local CMagicSpellSelectTypeENUM_Map = { [0] = "Circle", "Line1", "Line2", "Line3", "Fan", "Lightning1", "Lightning2", "Horizontal", "Box" } function CMagicSpellSelectTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicSpellSelectTypeENUM_Map) end CHitRateFuncENUM = class(CEnum, nil, false) local CHitRateFuncENUM_Map = { [0] = "Base", "DLV", "DLVxDLV", "DecPerPerson", "Shoot" } function CHitRateFuncENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CHitRateFuncENUM_Map) end CMagicSpellGroupTypeENUM = class(CEnum, nil, false) local CMagicSpellGroupTypeENUM_Map = { [0] = "Normal", "FirstGroupHit", "PrvGroupHit", "Vampire", "Vampire1" } function CMagicSpellGroupTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicSpellGroupTypeENUM_Map) end CMagicCollisionTypeENUM = class(CEnum, nil, false) local CMagicCollisionTypeENUM_Map = { [0] = "None", "Line", "TargetForward" } function CMagicCollisionTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicCollisionTypeENUM_Map) end CMagicComboTypeENUM = class(CEnum, nil, false) local CMagicComboTypeENUM_Map = { [-1] = "Null", [0] = "Earth", "Water", "Fire", "Wind", "Light", "Darkness", "Start" } function CMagicComboTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicComboTypeENUM_Map) end CMagicSpellCostTypeENUM = class(CEnum, nil, false) function CMagicSpellCostTypeENUM.constructor(self, proc, addr) local enum_map = { [0] = "None", "HP", "MP", "HP_Per", "MP_Per", "SP_Warrior", "SP_Ranger", "SP_Rogue", "StomachPoint", "Item", "Ammo_Gun", "Ammo_Bow", "Ammo_CrossBow", "Ammo_Throw", "Ammo_All", "SoulPoint" } CEnum.constructor(self, proc, addr, enum_map) end CMagicSpellNeedTypeENUM = class(CEnum, nil, false) local CMagicSpellNeedTypeENUM_Map = { [0] = "None", "Weapon", "Equipment", "Suit", "Buf", "BufTarget", "NoBuf", "NoBufTarget", "Unarmed", "Blade", "Dagger", "Wand", "Axe", "Bludgeon", "Claymore", "Staff", "2H_Axe", "2H_Hammer", "Polearm", "SwordType", "AxeType", "Shield", "Distance", "NotAttack", "Attack", "Critical", "BeCritical", "Dodge", "BeDodge", "Miss", "Parry", "BeParry", "NotAttackTarget", "AttackTarget", "SelfHP_Smaller_Per", "SelfHP_Greater_Per", "SelfClass", "LongDistanceWeapon", "2H_Weapon", "Hammer", "BuffGroup", "ShieldBlock", "BeShieldBlock", "1H_Weapon", "NoBuffGroup", "TargetBuffGroup", "TargetNoBuffGroup", "MagicalCritical", "BeMagicalCritical", "SelfMainClass", "SelfSoulPoint" } function CMagicSpellNeedTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicSpellNeedTypeENUM_Map) end CMagicColdownClassENUM = class(CEnum, nil, false) local CMagicColdownClassENUM_Map = { [0] = "None", "Job", "Equipment", "Item" } function CMagicColdownClassENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicColdownClassENUM_Map) end CMagicCheckFunctionENUM = class(CEnum, nil, false) local CMagicCheckFunctionENUM_Map = { [0] = "None", "Random", "SelfEqip", "TargetEquip", "SelfEqType", "TargetEqType", "SelfItem", "TargetItem", "SelfBuff", "TargetBuff", "SelfPosition", "TargetPosition", "SelfFight", "TargetFight", "SelfHP", "Time", "Weather", "SelfBuffGroup", "TargetBuffGroup", "SelfSkill", "BaseLV" } function CMagicCheckFunctionENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicCheckFunctionENUM_Map) end -- -- Substruct of GameObjectMagicCollectStruct -- CMagicCostStruct = class(CMemoryStruct, nil, false) function CMagicCostStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Type = CMagicSpellCostTypeENUM(proc, addr + offset); offset = offset + self.Type:Size() self.Value = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicNeedStruct = class(CMemoryStruct, nil, false) function CMagicNeedStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Type = CMagicSpellNeedTypeENUM(proc, addr + offset); offset = offset + self.Type:Size() self.Value = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicColdownBaseStruct = class(CMemoryStruct, nil, false) function CMagicColdownBaseStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Class = CMagicColdownClassENUM(proc, addr + offset); offset = offset + self.Class:Size() self.Type = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Time = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.TimeAllMagic = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicJobInfoStruct = class(CMemoryStruct, nil, false) function CMagicJobInfoStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Job = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.IsJobLimit = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 -- BOOL self:Size(offset) end CMagicCollectConditionStruct = class(CMemoryStruct, nil, false) function CMagicCollectConditionStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.FuncType = CMagicCheckFunctionENUM(proc, addr + offset); offset = offset + self.FuncType:Size() self.MagicBaseID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Arg1 = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Arg2 = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MagicBaseDB = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end -- -- Bitflags for GameObjectMagicCollectStruct -- CMagicItemRunPlotMode = class(CBitFlags, nil, false) local flags = { "Mark", "Fight", "NotShowHPMP", "EnemyHide", "NotRelyOwnerPower" } function CMagicItemRunPlotMode.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CMagicCollectFlagStruct = class(CBitFlags, nil, false) local flags = { "Interrupt_OnMove", "Interrupt_OnAttack", "Spell_Back", "Spell_Front", "Spell_LookAtTarget", "ReferenceWeapon_Bow", "ReferenceWeapon_Throw", "Dash", "AllColdown_Reference_Weapon", "NoInterrupt", "HideCastingBar", "Interrupt_SpellOtherMagic", "Ignore_Obstruct", "ReferenceWeapon_Bow_SpellTime", "ReferenceWeapon_Throw_SpellTime", "IgnoreFightingLog", "NoObjectInMagicEffectRange", "DescDurable", "forceDisplayEffect" } function CMagicCollectFlagStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CModeStruct = class(CBitFlags, nil, false) local flags = { "IsAutoAttack", "IsSwitchType", "IsRideEnable", "IsShowMagicName", "IsStopAttack", "IsLockTarget", "IsPetCycleMagic", "IsAutoSpell", "IsIgnoreInvincible", "IsIgnoreSilence", "IsWaterDisabled", "IsWaterEnabled", "IsRidePetSkill", "IsIgnoreTargetDead", "IsDiabledPvPRule", "IsIgnoreDmgEffect", "IsFixDmgEffect", "IsOnWagonEnabled", "IsDisableSpellBuffEffect", "IsShareDamage" } function CModeStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CEqWearSkillStruct = class(CBitFlags, nil, false) local flags = { "Unarmed", "Blade", "Dagger", "Wand", "Axe", "Bludgeon", "Claymore", "Staff", "Axe_2H", "Hammer_2H", "Polearm", "Bow", "CrossBow", "Gun", "Throw", "HeavyArmed", "LightArmed", "Leather", "Clothes", "Robe", "Shield", "Implement", "SecondHand" } function CEqWearSkillStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end -- -- Substructs for GameObjectMagicStruct -- CSpecailMagicEventTypeENUM = class(CEnum, nil, false) function CSpecailMagicEventTypeENUM.constructor(self, proc, addr) local enum_map = { [0] = "None","SelfCritial","TargetCritial","SelfDodge","TargetDodge","SelfMiss","TargetMiss", "ZoneDamage","Phy_SelfCritial","Phy_TargetCritial","Mag_SelfCritial","Mag_TargetCritial", "Cure_Self","Cure_Target","SelfParry","TargetParry" } CEnum.constructor(self, proc, addr, enum_map) end CMagicAttackCalBaseENUM = class(CEnum, nil, false) function CMagicAttackCalBaseENUM.constructor(self, proc, addr) local enum_map = { [0] = "MP", "Times", "Point", "Percent", "PointsByHealArg" } CEnum.constructor(self, proc, addr, enum_map) end CMagicShieldTypeENUM = class(CEnum, nil, false) local CMagicShieldTypeENUM_Map = { [0] = "MP", "Times", "Point", "Percent", "PointsByHealArg" } function CMagicShieldTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicShieldTypeENUM_Map) end CMagicShieldEffecENUM = class(CEnum, nil, false) local CMagicShieldEffecENUM_Map = { [0] = "All", "Phy", "Magic", "Earth", "Water", "Fire", "Wind", "Light", "Darkness" } function CMagicShieldEffecENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicShieldEffecENUM_Map) end CMagicSummonCreatureTypeENUM = class(CEnum, nil, false) local CMagicSummonCreatureTypeENUM_Map = { [0] = "Pet", "Guard", "GuardNoAttack" } function CMagicSummonCreatureTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicSummonCreatureTypeENUM_Map) end CMagicItemRunPlotENUM = class(CEnum, nil, false) local CMagicItemRunPlotENUM_Map = { [0] = "Plot", "Mine", "Staff" } function CMagicItemRunPlotENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicItemRunPlotENUM_Map) end CMagicItemRunPlotTargetTypeENUM = class(CEnum, nil, false) local CMagicItemRunPlotTargetTypeENUM_Map = { [0] = "Enemy", "Friend", "Player", "NPC", "All", "FriendNoSelf", "PlayerNoSelf", "AllNoSelf" } function CMagicItemRunPlotTargetTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicItemRunPlotTargetTypeENUM_Map) end CDotMagicTypeENUM = class(CEnum, nil, false) local CDotMagicTypeENUM_Map = { [0] = "HP","MP","WarriorSP","RangerSP","RogueSP","HP_Per","MP_Per" } function CDotMagicTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CDotMagicTypeENUM_Map) end CMagicAttackCalENUM = class(CEnum, nil, false) local CMagicAttackCalENUM_Map = { [0] = "None","MPow","Weapon","Shoot","Throw","INT","STR","AGI","STA","MND","LastSkillDmg","LastPhyDmg","ShieldDef" } function CMagicAttackCalENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicAttackCalENUM_Map) end CPhyResistTypeENUM = class(CEnum, nil, false) function CPhyResistTypeENUM.constructor(self, proc, addr) local enum_map = { [0] = "NULL", "Hit", "Cut", "Puncture" } CEnum.constructor(self, proc, addr, enum_map) end CMagicAttackTypeENUM = class(CEnum, nil, false) local CMagicAttackTypeENUM_Map = { [0] = "HP","MP","SP_Warrior","SP_Ranger","SP_Rogue","StomachPoint" } function CMagicAttackTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicAttackTypeENUM_Map) end CWearEqTypeENUM = class(CEnum, nil, false) local CWearEqTypeENUM_Map = { [0] = "None","Durable","STR","STA","INT","MND","AGI","AllState","MaxHP","MaxMP","ReHP","ReMP","ATK","DEF","MDEF", "MATK","HitPoint","DodgePoint","CritRate","CritPower","MagicCritRate","MagicCritPower","ParryRate","AtkSpeed", "MoveSpeed","DMG","AllResist","Resist_Earth","Resist_Water","Resist_Fire","Resist_Wind","Resist_Light","Resist_Darkness", "ManaDecrease","Exp","Treasure","SecHand_HitRate","SecHand_DMG_Per","DEF_HeavyArmed","DEF_LightArmed","DEF_Leather", "DEF_Clothes","DEF_Robe","DEF_Shield","MagicPow_AllMagic","MagicPow_Earth","MagicPow_Water","MagicPow_Fire","MagicPow_Wind", "MagicPow_Light","MagicPow_Darkness","SpellSpeed_AllMagic","DMG_AllRange","DMG_Bow","DMG_Cossbow","DMG_Gun","DMG_AllWeapon", "DMG_Unarmed","DMG_Blade","DMG_Dagger","DMG_Wand","DMG_Axe","DMG_Bludgeon","DMG_Claymore","DMG_Staff","DMG_2H_Axe","DMG_2H_Hammer", "DMG_Polearm","AttackSpeed_AllRange","AttackSpeed_Bow","AttackSpeed_Cossbow","AttackSpeed_Gun","AttackSpeed_AllWeapon","AttackSpeed_Unarmed", "AttackSpeed_Blade","AttackSpeed_Dagger","AttackSpeed_Wand","AttackSpeed_Axe","AttackSpeed_Bludgeon","AttackSpeed_Claymore", "AttackSpeed_Staff","AttackSpeed_2H_Axe","AttackSpeed_2H_Hammer","AttackSpeed_Polearm","WearEqAbility_Unarmed","WearEqAbility_Blade", "WearEqAbility_Dagger","WearEqAbility_Wand","WearEqAbility_Axe","WearEqAbility_Bludgeon","WearEqAbility_Claymore","WearEqAbility_Staff", "WearEqAbility_Axe_2H","WearEqAbility_Hammer_2H","WearEqAbility_Polearm","WearEqAbility_Bow","WearEqAbility_CossBow","WearEqAbility_Gun", "WearEqAbility_Throw","WearEqAbility_HeavyArmed","WearEqAbility_LightArmed","WearEqAbility_Leather","WearEqAbility_Clothes","WearEqAbility_Robe", "WearEqAbility_Shield","WearEqAbility_Implement","WearEqAbility_SecondHand","SkillValue_Unarmed","SkillValue_Blade","SkillValue_Dagger", "SkillValue_Wand","SkillValue_Axe","SkillValue_Bludgeon","SkillValue_Claymore","SkillValue_Staff","SkillValue_2H_Axe","SkillValue_2H_Hammer", "SkillValue_Polearm","SkillValue_Bow","SkillValue_CossBow","SkillValue_Gun","SkillValue_Define","SkillValue_BlackSmith","SkillValue_Carpenter", "SkillValue_MakeArmor","SkillValue_Tailor","SkillValue_Cook","SkillValue_Alchemy","HQ_BlackSmith","HQ_Carpenter","HQ_MakeArmor", "HQ_Tailor","HQ_Cook","HQ_Alchemy","ATK_Per","DEF_Per","StealRate","DropMoneyRate","HateRate","ReSP_Per_Warrior","ReSP_Per_Ranger", "ReSP_Per_Rogue","MAbsorbRate","AbsorbRate","HealAbsorbRate","MAbsorb","Absorb","HealAbsorb","MDmgPoint","HealPowerRate","HealPoint", "RangeAttackRange","SkillValue_Lumbering","SkillValue_Herbalism","SkillValue_Mining","SkillValue_Fishing","HQ_Lumbering","HQ_Herbalism", "HQ_Mining","HQ_Fishing","SkillValue_GatherRate","STR_Rate","STA_Rate","INT_Rate","MND_Rate","AGI_Rate","AllState_Rate","MaxHP_Rate", "MaxMP_Rate","RideSpeed","MDEF_Rate","MATK_Rate","ShieldBlockRate","DMG_Per","Exp_SubJob","TP_Rate","SkillValue_LumberingRate", "SkillValue_HerbalismRate","SkillValue_MiningRate","SkillValue_FishingRate","Gravity","DoubleAttack","ResistCritRate","ResistMagicCritRate", "Magic_EarthPower","Magic_WaterhPower","Magic_FirePower","Magic_WindhPower","Magic_LightPower","Magic_DarkPower","JumpRate", "MDMG","MDMG_Per","ResistShieldBlock","ResistParry","MagicHitPoint","MagicDodgePoint","PhyHitRate","PhyDodgeRate","MagicHitRate", "MagicDodgeRate","GatherGenerateRate","GatherSpeedRate","GatherExpRate","AttackPlayerPowerRate","AttackNPCPowerRate","PlayerDefRate", "NPCDefRate","AEMagicPowerRate","AEMagicDefRate","CraftSpeedRate","CraftExpRate","AddPlotExpRate","AddPlotTPRate","SP_Warrior_Consume", "SP_Rogue_Consume","SP_Ranger_Consume","NPC_EXP_Rate","NPC_TP_Rate","AttackRange","AllResist_Per","Resist_Earth_Per","Resist_Water_Per", "Resist_Fire_Per","Resist_Wind_Per","Resist_Light_Per","Resist_Darkness_Per","ParryRate_Per" } function CWearEqTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CWearEqTypeENUM_Map) end CMagicTeleport = class(CMemoryStruct, nil, false) function CMagicTeleport.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.ZoneID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.X = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Y = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Z = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Dir = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicRaise = class(CMemoryStruct, nil, false) function CMagicRaise.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.ExpPrecnt = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicSummonCreature = class(CMemoryStruct, nil, false) function CMagicSummonCreature.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.ObjID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Level = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.RangeLevel = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.LiveTime = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.SkillLvArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.Type = CMagicSummonCreatureTypeENUM(proc, addr + offset); offset = offset + self.Type:Size() self.GroupID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OwnerPowerRate = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.SkillType = {} for i=1,3 do self.SkillType[i] = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 end self.InitLua = tonumber(memoryReadRepeat("string", proc, addr + offset));offset = offset + 32 self:Size(offset) end CMagicSummonItem = class(CMemoryStruct, nil, false) function CMagicSummonItem.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.ObjID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicSteal = class(CMemoryStruct, nil, false) function CMagicSteal.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.SuccessRate = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicItemRunPlot = class(CMemoryStruct, nil, false) function CMagicItemRunPlot.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Type = CMagicItemRunPlotENUM(proc, addr + offset); offset = offset + self.Type:Size() self.ObjID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.PlotName = tonumber(memoryReadRepeat("string", proc, addr + offset)); offset = offset + 64 self.LiveTime = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.UseMagic = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnDeadMagic = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.GroupID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Mode = CMagicItemRunPlotMode(proc, addr + offset); offset = offset + self.Mode:Size() self.TargetType = CMagicItemRunPlotTargetTypeENUM(proc, addr + offset); offset = offset + self.TargetType:Size() self:Size(offset) end CMagicRunPlot = class(CMemoryStruct, nil, false) function CMagicRunPlot.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.PlotName = tonumber(memoryReadRepeat("string", proc, addr + offset)); offset = offset + 64 self:Size(offset) end CMagicShieldStruct = class(CMemoryStruct, nil, false) function CMagicShieldStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Type = CMagicShieldTypeENUM(proc, addr + offset); offset = offset + self.Type:Size() self.Effect = CMagicShieldEffecENUM(proc, addr + offset); offset = offset + self.Type:Size() self.Point = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.SkillLvArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CGameObjectWearEqStruct = class(CMemoryStruct, nil, false) function CGameObjectWearEqStruct.constructor(self, proc, addr) local Max_WearEqType_Count = 10 local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.EqType = {} for i=1,Max_WearEqType_Count do local eqtype = CWearEqTypeENUM(proc, addr + offset) offset = offset + eqtype:Size() self.EqType[i] = eqtype end self.EqTypeValue = {} for i=1,Max_WearEqType_Count do self.EqTypeValue[i] = tonumber(memoryReadRepeat("int", proc, addr + offset)) offset = offset + 4 end self.OnAttackMagicRate = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnAttackMagicRank = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnAttackMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CDotMagicStruct = class(CMemoryStruct, nil, false) function CDotMagicStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.Time = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Type = CDotMagicTypeENUM(proc, addr + offset); offset = offset + self.Type:Size() self.Base = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.DotSkillLVArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicAttackStruct = class(CMemoryStruct, nil, false) function CMagicAttackStruct.constructor(self, proc, addr) local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.AtkType = CMagicAttackTypeENUM(proc, addr + offset); offset = offset + self.AtkType:Size() self.DmgPower = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.DmgPower_SkillLVArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.FixValue = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.FixType = CMagicAttackCalENUM(proc, addr + offset); offset = offset + self.FixType:Size() self.FixDmg_SkillLVArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.Rand = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.CritialRate = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.HateRate = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self:Size(offset) end CMagicFuncENUM = class(CEnum, nil, false) local CMagicFuncENUM_Map = { [0] = "HPMP", "Assist", "Teleport", "SummonCreature", "SummonItem", "Steal", "RunPlot", "Raise" } function CMagicFuncENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicFuncENUM_Map) end CMagicResistENUM = class(CEnum, nil, false) local CMagicResistENUM_Map = { [-1] = "None", [0] = "Earth", "Water", "Fire", "Wind", "Light", "Darkness" } function CMagicResistENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CMagicResistENUM_Map) end CGameObjectWeaponENUM = class(CEnum, nil, false) function CGameObjectWeaponENUM.constructor(self, proc, addr) local enum_map = { [-1] = "None", [0] = "Unarmed", "Blade", "Dagger", "Wand", "Axe", "Bludgeon", "Claymore", "Staff", "2H_Axe", "2H_Hammer", "Polearm", "Bow", "Crossbow", "Gun", "AmmoBow", "AmmoGun", "Throw", "Lumbering", "Herbalism", "Mining", "Fishing" } CEnum.constructor(self, proc, addr, enum_map) end CGameObjectMagicTypeENUM = class(CEnum, nil, false) local CGameObjectMagicTypeENUM_Map = { [-1] = "NULL", [0] = "Type0", "Type1", "Type2", "Type3", "Type4", "Type5", "Type6", "Type7", "Type8", "Type9", "Type10", "Type11", "Type12", "Type13", "Type14", "Type15" } function CGameObjectMagicTypeENUM.constructor(self, proc, addr) CEnum.constructor(self, proc, addr, CGameObjectMagicTypeENUM_Map) end CMagicSpellFlagStruct = class(CBitFlags, nil, false) local flags = { "GoodMagic", "ShowBuf", "ContinueMagic", "DotMagic", "FaceOffMagic", "CancelBuff", "ShowBuffTime", "SpecialMagic", "MagicShield", "DeadNotClear", "OfflineBuffTime", "OnPlayerAttackAddTime", "OnKillAddTime", "SelfBuff", "FaceOffMagic_ShowEq", "ShowPowerLv", "DotMagicNoKill", "BuffSkill", "MaxMagicLvEquRoleLv", "DisableShowMagicInfo", "RideCanAttack", "RidePetAttack", "CancelBadMagic", "NpcEndFight_NotClearBuff", "Dual_NoClearBuff", "IgnoreSpellCureMagicClear", "IgnoreSpellAttackMagicClear", "IgnoreBuffMessage", "OnlyYouCanSee", "NoEffect", "forceDisplayEffect" } function CMagicSpellFlagStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CMagicAttackSpecialAction = class(CBitFlags, nil, false) local flags = { "None", "StrikeBack", "SpellInterrupt", "IgnoreDefine", "EraseHate", "HateOnePoint", "Bomb" } function CMagicAttackSpecialAction.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CMagicEffectStruct = class(CBitFlags, nil, false) local flags = { "UseMagicDisable", "UsePhyDisable", "BadMagicInvincible", "BadPhyInvincible", "UseItemDisable", "SearchEmenyDisable", "Stop", "Cover", "DetectCover", "Sneak", "DetectSneak", "Blind", "HitDown", "Trace", "PlayDead", "Insure", "Chaos", "Fear", "LockTarget", "WeaponIgnore", "ArmorIgnore", "Ride", "Raise", "ExpProtect", "Client_Dizzy", "Client_Sleep", "PKFlag", "TeleportDisable", "GPS", "PKFlag_Disabled", "AI_LowAttackPriority", "StopOntimeCure", "Silence", "CliOutofContorl", "Freeze", "GoodMagicInvincible", "GoodPhyInvincible", "Guilty", "Critial", "Hunter", "NoEscape", "DisableJobSkill", "IgnoreDeadGoodEvil", "ExchangeZoneDamageEvent", "Fly", "WaterWalk", "GravityDisable", "DisableStrikeBack", "DisableWagon", "IgnoreInstancePlayer", "TitleSysPowerUp", "MagicSpell_ZeroTime", "MagicSpell_Moveable","MagicSpell_NoCost" } function CMagicEffectStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end CMagicClearTimeStruct = class(CBitFlags, nil, false) local flags = { "Attack", "UnderAtk", "Move", "Spell", "ChangeZone", "Logout", "Random", "WarriorSP0", "RangerSP0", "RogueSP0", "HP0","MP0", "Spell_MagicAttack", "Spell_PhyAttack", "Spell_Cure", "TargetOnAttack", "OnStopAttackMode", "OnWater", "OnNoWater", "Spell_Magic", "Spell_Phy" } function CMagicClearTimeStruct.constructor(self, proc, addr) CBitFlags.constructor(self, proc, addr, flags) end -- -- Generic table entry (GameObjDbStruct) -- CTableStruct = class(CMemoryStruct, nil, false) function CTableStruct.constructor(self, proc, addr) assert(type(proc) == "userdata", "No process given!") assert(type(addr) == "number", "No address given!") local offset = 0 CMemoryStruct.constructor(self, proc, addr) self.GUID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Classification = CGameObjectClassificationENUM(proc, addr + offset); offset = offset + self.Classification:Size() self.LanguageSet = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 local laddr = memoryReadRepeat("int", proc, addr + offset); offset = offset + 4 self.Name = memoryReadRepeat("string", proc, laddr) local laddr = memoryReadRepeat("int", proc, addr + offset); offset = offset + 4 self.NamePlural = memoryReadRepeat("string", proc, laddr) self.ImageID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 offset = offset + 8 -- Skipping two 4B fields (ImageObj_Backup, MaxHeap) local laddr = memoryReadRepeat("int", proc, addr + offset); offset = offset + 4 self.Note = memoryReadRepeat("string", proc, laddr) local laddr = memoryReadRepeat("int", proc, addr + offset); offset = offset + 4 self.ShortNote = memoryReadRepeat("string", proc, laddr) self.Mode = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 -- ObjectModeStruct (int) self.PricesType = CPriceTypeENUM(proc, addr + offset); offset = offset + self.PricesType:Size() self.SellType = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Cost = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuyUnit = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.ReviveTime = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Rare = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.GenerateRate = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.MaxWorldCount = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.Limit = CLimitStruct(proc, addr + offset); offset = offset + self.Limit:Size() self.LiveTimeType = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.LiveTime = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 offset = offset + 12 -- Skipping 'int ACSearchType[3]' self.ItemEqType = CEqWearSkillStruct(proc, addr + offset); offset = offset + self.ItemEqType:Size() self.SpecialMoneyCost = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.iTagID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end -- -- A skill collection (GameObjectMagicCollectStruct, inherits GameObjDbStruct) -- CSkillCollectionEntry = class(CTableStruct, nil, false) function CSkillCollectionEntry.constructor(self, proc, addr) assert(type(proc) == "userdata", "No process given!") assert(type(addr) == "number", "No address given!") CTableStruct.constructor(self, proc, addr) -- This struct starts at end of GameObjDbStruct (4 byte aligned) local offset = self:SizePad() self.MagicLV = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.EffectType = CMagicorPhyENUM(proc, addr + offset); offset = offset + self.EffectType:Size() self.TargetType = CGameObjectRelationENUM(proc, addr + offset); offset = offset + self.TargetType:Size() self.AttackDistance = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.EffectRange = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.RangeType = CGameObjectMagicEffectRangeENUM(proc, addr + offset); offset = offset + self.RangeType:Size() self.RangeSelectType = CMagicSpellSelectTypeENUM(proc, addr + offset); offset = offset + self.RangeSelectType:Size() self.EffectCount = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.DecreaseArg = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.HitRateFunc = CHitRateFuncENUM(proc, addr + offset); offset = offset + self.HitRateFunc:Size() self.HitRateArg1 = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.HitRateArg2 = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 -- Cost is a table of two entries self.SkillCost = {} for i=1,2 do local cost = CMagicCostStruct(proc, addr + offset) table.insert(self.SkillCost, cost) offset = offset + cost:Size() end -- Need is a table of two entries self.SkillNeed = {} for i=1,2 do local need = CMagicNeedStruct(proc, addr + offset) table.insert(self.SkillNeed, need) offset = offset + need:Size() end self.Cooldown = CMagicColdownBaseStruct(proc, addr + offset); offset = offset + self.Cooldown:Size() self.Flag = CMagicCollectFlagStruct(proc, addr + offset); offset = offset + self.Flag:Size() self.SpellTime = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.MagicAttackDelay = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.SpellCount = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.NextSpellTime = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.LUAScript = memoryReadRepeat("string", proc, addr + offset); offset = offset + 128 -- Read in the table[3][4] of MagicCollectCondition's -- Entry[0][0] is the base skill, rest is enabled by MagicProc.MagicEnabled[GroupID][i] self.MagicCollectCondition = {} for i=1,12 do local collection = CMagicCollectConditionStruct(proc, addr + offset) offset = offset + collection:Size() table.insert(self.MagicCollectCondition, collection) end self.SpellGroupType = CMagicSpellGroupTypeENUM(proc, addr + offset); offset = offset + self.SpellGroupType:Size() self.CheckUseScript = memoryReadRepeat("string", proc, addr + offset); offset = offset + 128 self.MaxSkillLv = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.ExpTableRate = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.IsMagicAttackDelay = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 -- BOOL self.JobInfo = CMagicJobInfoStruct(proc, addr + offset); offset = offset + self.JobInfo:Size() self.ComboType = CMagicComboTypeENUM(proc, addr + offset); offset = offset + self.ComboType:Size() self.NextMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Mode = CModeStruct(proc, addr + offset); offset = offset + self.Mode:Size() self.PetSkillType = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MoveDelayTime = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.CliCollisionType = CMagicCollisionTypeENUM(proc, addr + offset); offset = offset + self.CliCollisionType:Size() self.CliCollisionValue = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.LimitLv = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.SelectTargetScript = memoryReadRepeat("string", proc, addr + offset); offset = offset + 64 self.ShootTargetScript = memoryReadRepeat("string", proc, addr + offset); offset = offset + 64 self.AddSoulPoint = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end -- -- A skill entry (GameObjectMagicStruct) -- CMagicEntry = class(CTableStruct, nil, false) function CMagicEntry.constructor(self, proc, addr) assert(type(proc) == "userdata", "No process given!") assert(type(addr) == "number", "No address given!") CTableStruct.constructor(self, proc, addr) -- This struct starts at end of GameObjDbStruct (4 byte aligned) local offset = self:SizePad() self.MagicFunc = CMagicFuncENUM(proc, addr + offset); offset = offset + self.MagicFunc:Size() self.MagicType = CMagicResistENUM(proc, addr + offset); offset = offset + self.MagicType:Size() self.EffectType = CMagicorPhyENUM(proc, addr + offset); offset = offset + self.EffectType:Size() self.EffectTime = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 -- Effective time (0.1 seconds) self.DLV_EffectTime = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.EffectTime_Arg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.HateCost = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MaxBuffLv_Base = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MaxBuffLv_Arg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.MagicGroupSet = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Setting = CMagicSpellFlagStruct(proc, addr + offset); offset = offset + self.Setting:Size() self.SpecialAction = CMagicAttackSpecialAction(proc, addr + offset); offset = offset + self.SpecialAction:Size() self.AssistType = CGameObjectMagicTypeENUM(proc, addr + offset); offset = offset + self.AssistType:Size() -- Spell type ( primarily for auxiliary spells exclusive processing) self.EffectLV = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.EffectAddonType = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.Effect = CMagicEffectStruct(proc, addr + offset); offset = offset + self.Effect:Size() self.ClearTime = CMagicClearTimeStruct(proc, addr + offset); offset = offset + self.ClearTime:Size() self.Ability = CGameObjectWearEqStruct(proc, addr + offset); offset = offset + self.Ability:Size() self.Ability_SkillLVArg = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.OnTimeMagic_Magic = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnTimeMagic_Time = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.FaceOffID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.RideID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnAttackMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnBuffTimeOutMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnAttackReboundMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnMagicAttackReboundMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnDeadMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.TempHateCost = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.ClearMagicGroupSet = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.DotMagic = CDotMagicStruct(proc, addr + offset); offset = offset + self.DotMagic:Size() self.Attack = CMagicAttackStruct(proc, addr + offset); offset = offset + self.Attack:Size() self.Teleport = CMagicTeleport(proc, addr + offset); offset = offset + self.Teleport:Size() self.Raise = CMagicRaise(proc, addr + offset); offset = offset + self.Raise:Size() self.SummonCreature = CMagicSummonCreature(proc, addr + offset); offset = offset + self.SummonCreature:Size() self.SummonItem = CMagicSummonItem(proc, addr + offset); offset = offset + self.SummonItem:Size() self.Steal = CMagicSteal(proc, addr + offset); offset = offset + self.Steal:Size() self.ItemRunPlot = CMagicItemRunPlot(proc, addr + offset); offset = offset + self.ItemRunPlot:Size() self.RunPlot = CMagicRunPlot(proc, addr + offset); offset = offset + self.RunPlot:Size() self.MagicShield = CMagicShieldStruct(proc, addr + offset); offset = offset + self.MagicShield:Size() self.AtkCalType = CMagicAttackCalBaseENUM(proc, addr + offset); offset = offset + self.AtkCalType:Size() self.MagicGroupID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuffCount = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.PhyAttackType = CPhyResistTypeENUM(proc, addr + offset); offset = offset + self.PhyAttackType:Size() self.IsStandard_Attack = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 -- BOOL self.RefPowerLv_Attack = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.RefPowerRate_Attack= tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.ModelSize = tonumber(memoryReadRepeat("float", proc, addr + offset)); offset = offset + 4 self.Revive_SkillLVArg = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.AddBuffTime = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnKillMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.CheckUseLua = tonumber(memoryReadRepeat("string", proc, addr + offset)); offset = offset + 64 self.SpecialMagicEventType = CSpecailMagicEventTypeENUM(proc, addr + offset); offset = offset + self.SpecialMagicEventType:Size() self.OnSpecialMagicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuffTimeDesc_Type = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuffTimeDesc_Time = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuffSkill = {} for i=1,6 do self.BuffSkill[i] = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 end self.EndUseLua = tonumber(memoryReadRepeat("string", proc, addr + offset)); offset = offset + 64 self.HitBackDist = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.CarryCount = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.MusicID = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.BuffMaxLv = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self.OnBuffTimeOutMagicIDEx = tonumber(memoryReadRepeat("int", proc, addr + offset)); offset = offset + 4 self:Size(offset) end -- -- An item entry (GameObjectItemStruct) [TODO] -- CItemEntry = class(CTableStruct, nil, false) function CItemEntry.constructor(self, proc, addr) end -- -- Parse a memory entry and return corresponding entry -- function GetTableEntry(proc, addr) local entry = CTableStruct(proc, addr) -- EM_ObjectClass_Item if entry.Classification.value == 2 then entry = CItemEntry(proc, addr) -- EM_ObjectClass_MagicBase elseif entry.Classification.value == 3 then entry = CMagicEntry(proc, addr) -- EM_ObjectClass_MagicCollect elseif entry.Classification.value == 21 then entry = CSkillCollectionEntry(proc, addr) -- Unknown classification else --cprintf(cli.yellow, "Unknown table classification (%s)\n", entry.Classification) entry = nil end return entry end function DumpTableEntry(entry, level) local level = level or 0 function vprintf(spacer, fmt, ...) for i = 1,spacer do printf(" ") end printf(fmt, ...) end assert(type(entry) == "table") for k,v in pairs(entry) do if type(v) == "table" then local mt = getmetatable(v) if mt and mt.__tostring then vprintf(level, "%s = %s\n", k, tostring(v)) else vprintf(level, "%s =>\n", k) DumpTableEntry(v, level + 1) end else if type(v) == "string" then vprintf(level, "%s = '%s'\n", k, tostring(v)) elseif k == "_address" then vprintf(level, "Address = '0x%x'\n", k, v) else vprintf(level, "%s = %s\n", k, tostring(v)) end end end end -- -- Print a skill -- function PrintSkill(Skill) cprintf(cli.yellow, "Skill name : %s\n", Skill.Name) cprintf(cli.lightblue, "Skill type : %s\n", Skill.EffectType) cprintf(cli.lightblue, "Target type : %s\n", Skill.TargetType) cprintf(cli.lightblue, "Attack distance : %s\n", Skill.AttackDistance) cprintf(cli.lightblue, "Area affected : %s\n", Skill.EffectRange) cprintf(cli.lightblue, "Cast time : %ds\n", Skill.SpellTime) cprintf(cli.lightblue, "Cooldown : %ds\n", Skill.Cooldown.Time) cprintf(cli.lightblue, "Global Cooldown : %ds\n", Skill.Cooldown.TimeAllMagic) print() cprintf(cli.lightblue, "Cost:\n") for i=1,2 do if Skill.SkillCost[i].Type.value > 0 then cprintf(cli.lightblue, "\t%s(%d)\n", Skill.SkillCost[i].Type, Skill.SkillCost[i].Value) end end cprintf(cli.lightblue, "Prereq:\n") for i=1,2 do if Skill.SkillNeed[i].Type.value > 0 then local reqtype = tostring(Skill.SkillNeed[i].Type) local reqvalue = tonumber(Skill.SkillNeed[i].Value) if reqtype == "BufTarget" or reqtype == "BufSelf" then reqvalue = string.format("'%s' [%d]", GetIdName(reqvalue), reqvalue) end cprintf(cli.lightblue, "\t%s(%s)\n", Skill.SkillNeed[i].Type, tostring(reqvalue)) end end cprintf(cli.lightblue, "Subskills: \n") for i=1,12 do local cond = Skill.MagicCollectCondition[i] if i==1 or cond.MagicBaseID > 0 then local magic = GetTableEntry(proc, GetItemAddress(cond.MagicBaseID)) local group, index = math.floor((i-1)/4), (i-1)%4 -- 3 groups of 4 skills each local value = cond.Arg2 local func = tostring(cond.FuncType) if func == "SelfEqType" then value = CGameObjectWeaponENUM(cond.Arg2) elseif func == "TargetBuff" then value = string.format("'%s' [%d]", GetIdName(tonumber(cond.Arg2)), cond.Arg2) end local MagicBaseName = GetIdName(cond.MagicBaseID) if MagicBaseName then MagicBaseName = string.format("%s [%d]", MagicBaseName, cond.MagicBaseID) else MagicBaseName = tostring(cond.MagicBaseID) end cprintf(cli.lightblue, "\t[%d, %d] %s", group, index, MagicBaseName) if func ~= "None" then cprintf(cli.lightblue, " if %s(%d, %s)", cond.FuncType, cond.Arg1, tostring(value)) end print() end end end function FindSkill(id) local proc = getProc() local addr = GetItemAddress(id) assert(addr, "Skill "..id.." not found") local Skill = GetTableEntry(proc, addr) assert(Skill, "Skill DB entry "..id.." not found") return Skill end function PrintMySkills(_tabs) local proc = getProc() local skillsTableTabSize = 0x10 local skillSize = 0x4c if type(_tabs) == "table" then -- do nothing elseif type(tonumber(_tabs)) == "number" then _tabs = {tonumber(_tabs)} else _tabs = {1,2,3,4,5} end for __, tab in pairs(_tabs) do local tabBaseAddress = memoryReadRepeat("uint", proc, addresses.skillsTableBase + skillsTableTabSize*(tab-1) + addresses.skillsTableTabStartAddress_offset) local tabEndAddress = memoryReadRepeat("uint", proc, addresses.skillsTableBase + skillsTableTabSize*(tab-1) + addresses.skillsTableTabEndAddress_offset) if tabBaseAddress ~= 0 and tabEndAddress ~= 0 then for num = 1, (tabEndAddress - tabBaseAddress) / skillSize do local skilladdress = tabBaseAddress + (num - 1) * skillSize local Id = tonumber(memoryReadRepeat("int", proc, skilladdress)) local BaseItemAddress = GetItemAddress(Id) local Skill = GetTableEntry(proc, BaseItemAddress) if Skill then PrintSkill(Skill) print() end end end end end