**Also I will label Everything with comments so if your dont want a certain addon you dont have to add it =)its so easy to see but i will show you anyways!(if someone requests it)** **Not Tested on EO 3.0 yet(almost), works great on 2.0 and 2.3** Please note that you will have to delete you player accounts, your items, and even your maps to use this(sorry guys I dont have a converter or able to make one) Well this is something DJMaxus created for me after I ran into trouble doing it myself.. Basically Its a "dynamic" Crafting system that supports up to 5 items( you can add and remove more easily).. Also It has different crafting stations if you will.. For example if your making a sword you must be at an avil.. or if your making a potion you must be at a alchemy table and it wont work if your at the wrong station or not at a station at all. Also I have added a Level up system based on DJMaxus' other tutorial.. Means if you suck at blacksmithing you cant make good weapons.. This System reminds me a bit of skyrim yet it still uses the recipe item type for making stuff.. All credits go to DJMAXUS!! **How it Works:** Make a Recipe and set it up to make an item.. Next check a box for what type of item it is (smithy, alchemy, or enchant) You must select one of the boxes even if it doesnt have a level requirement. Next set what lv for the crafting skill they must have to make the item. Then in the map editor you can place multiple crafting tiles.. Place an anvil at the balcksmiths shop or an Alchemy lab at the spell shop ect.. **The Code:** **Server Side** **In modTypes** Find : **Private Type PlayerRec** Add this to the bottom before **End Type**: ``` Smith As Byte SmithExp As Long Alchemy As Byte AlchemyExp As Long Enchants As Long EnchantsExp As Long ``` Find : **Private Type ItemRec** Add this to the bottom of **Private Type ItemRec** (before End Type) ``` 'crafting Tool As Long ToolReq As Long Recipe(1 To MAX_RECIPE_ITEMS) As Long Smithy As Long SmithReq As Long Alchemist As Long AlchemyReq As Long Enchanter As Long EnchantReq As Long ``` **In modConstants** Find: ``` Public Const ITEM_TYPE_SPELL As Byte = 8 ``` Add this below: ``` Public Const ITEM_TYPE_RECIPE As Byte = 9 ``` Add this to the bottom of the tile constants also( note your number might be different from mine) ``` Public Const TILE_TYPE_CRAFT As Byte = 15 ``` Also Add this under the rest of the general constants: ``` ' max number of crafting items Public Const MAX_RECIPE_ITEMS As Long = 5 ``` **In modDatabase in Sub AddChar** Find: ``` Player(Index).Level = 1 ``` Under it add this ``` Player(Index).Smith = 1 Player(Index).Alchemy = 1 Player(Index).Enchants = 1 ``` **In modServerTCP** find :**Function PlayerData(ByVal Index As Long) As Byte()** Under this :**Buffer.WriteLong GetPlayerPK(Index)** Add this: ``` Buffer.WriteLong GetPlayerSmith(Index) Buffer.WriteLong GetPlayerAlchemy(Index) Buffer.WriteLong GetPlayerEnchants(Index) ``` **In modServerTCP** find: **Sub SendEXP(ByVal Index As Long)** In that sub under : **Buffer.WriteLong GetPlayerNextLevel(Index)** Add this: ``` Buffer.WriteLong GetPlayerSmithExp(Index) Buffer.WriteLong GetPlayerNextSmithLevel(Index) Buffer.WriteLong GetPlayerAlchemyExp(Index) Buffer.WriteLong GetPlayerNextAlchemyLevel(Index) Buffer.WriteLong GetPlayerEnchantsExp(Index) Buffer.WriteLong GetPlayerNextEnchantsLevel(Index) ``` **In modPlayer find this sub:** ``` Function GetPlayerNextLevel(ByVal Index As Long) As Long GetPlayerNextLevel = (50 / 3) * ((GetPlayerLevel(Index) + 1) ^ 3 - (6 * (GetPlayerLevel(Index) + 1) ^ 2) + 17 * (GetPlayerLevel(Index) + 1) - 12) End Function ``` under it add this: ``` ' Proficeicies '*************************************** ' BlackSmith Skill Level '*************************************** Function GetPlayerSmith(ByVal Index As Long) As Long If Index > MAX_PLAYERS Then Exit Function GetPlayerSmith = Player(Index).Smith End Function Function SetPlayerSmith(ByVal Index As Long, ByVal Smith As Long) SetPlayerSmith = False If Smith > MAX_SKILL_LEVEL Then Exit Function Player(Index).Smith = Smith SetPlayerSmith = True End Function Function GetPlayerSmithExp(ByVal Index As Long) As Long GetPlayerSmithExp = Player(Index).SmithExp End Function Sub SetPlayerSmithExp(ByVal Index As Long, ByVal SmithExp As Long) Player(Index).SmithExp = SmithExp SendEXP Index If GetPlayerSmithExp(Index) >= GetPlayerNextSmithLevel(Index) Then SmithLevelUp Index End Sub Public Function GetPlayerNextSmithLevel(ByVal Index As Long) As Long GetPlayerNextSmithLevel = (50 / 3) * ((GetPlayerSmith(Index) + 1) ^ 3 - (6 * (GetPlayerSmith(Index) + 1) ^ 2) + 17 * (GetPlayerSmith(Index) + 1) - 12) End Function ' Proficeicies '*************************************** ' Alchemy Skill Level '*************************************** Function GetPlayerAlchemy(ByVal Index As Long) As Long If Index > MAX_PLAYERS Then Exit Function GetPlayerAlchemy = Player(Index).Alchemy End Function Function SetPlayerAlchemy(ByVal Index As Long, ByVal Alchemy As Long) SetPlayerAlchemy = False If Alchemy > MAX_SKILL_LEVEL Then Exit Function Player(Index).Alchemy = Alchemy SetPlayerAlchemy = True End Function Function GetPlayerAlchemyExp(ByVal Index As Long) As Long GetPlayerAlchemyExp = Player(Index).AlchemyExp End Function Sub SetPlayerAlchemyExp(ByVal Index As Long, ByVal AlchemyExp As Long) Player(Index).AlchemyExp = AlchemyExp SendEXP Index If GetPlayerAlchemyExp(Index) >= GetPlayerNextAlchemyLevel(Index) Then AlchemyLevelUp Index End Sub Public Function GetPlayerNextAlchemyLevel(ByVal Index As Long) As Long GetPlayerNextAlchemyLevel = (50 / 3) * ((GetPlayerAlchemy(Index) + 1) ^ 3 - (6 * (GetPlayerAlchemy(Index) + 1) ^ 2) + 17 * (GetPlayerAlchemy(Index) + 1) - 12) End Function ' Proficeicies '*************************************** ' Enchanting Skill Level '*************************************** Function GetPlayerEnchants(ByVal Index As Long) As Long If Index > MAX_PLAYERS Then Exit Function GetPlayerEnchants = Player(Index).Enchants End Function Function SetPlayerEnchants(ByVal Index As Long, ByVal Enchants As Long) SetPlayerEnchants = False If Enchants > MAX_SKILL_LEVEL Then Exit Function Player(Index).Enchants = Enchants SetPlayerEnchants = True End Function Function GetPlayerEnchantsExp(ByVal Index As Long) As Long GetPlayerEnchantsExp = Player(Index).EnchantsExp End Function Sub SetPlayerEnchantsExp(ByVal Index As Long, ByVal EnchantsExp As Long) Player(Index).EnchantsExp = EnchantsExp SendEXP Index If GetPlayerEnchantsExp(Index) >= GetPlayerNextEnchantsLevel(Index) Then EnchantsLevelUp Index End Sub Public Function GetPlayerNextEnchantsLevel(ByVal Index As Long) As Long GetPlayerNextEnchantsLevel = (50 / 3) * ((GetPlayerEnchants(Index) + 1) ^ 3 - (6 * (GetPlayerEnchants(Index) + 1) ^ 2) + 17 * (GetPlayerEnchants(Index) + 1) - 12) End Function ``` **In modPlayer** Find the **UseItem** sub. Near the top of the sub, find: ``` Dim n As Long, i As Long, tempItem As Long, x As Long, y As Long, itemnum As Long ``` Add this below: ``` Dim MaxItems As Long Dim Result As Long ``` And add the following before the last End Select (Still in the same sub) ``` Case ITEM_TYPE_RECIPE ' Check if on crafting tile If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Type TILE_TYPE_CRAFT Then PlayerMsg Index, "You cannot craft this item here.", BrightRed Exit Sub End If ' Alchemy If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Data1 = 1 Then If Item(ItemNum).Alchemist 1 Then PlayerMsg Index, "You cannot craft this item here, find a place to cook the ingredents.", BrightRed Exit Sub End If End If ' Smithing If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Data1 = 2 Then If Item(ItemNum).Smithy 1 Then PlayerMsg Index, "You cannot craft this item here, find a toolbench or generator.", BrightRed Exit Sub End If End If ' Enchantment If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index)).Data1 = 3 Then If Item(ItemNum).Enchanter 1 Then PlayerMsg Index, "You cannot craft this item here, find a workbench.", BrightRed Exit Sub End If End If ' Get the recipe information Result = Item(GetPlayerInvItemNum(Index, invNum)).Data3 ' Perform Recipe checks If Result 0 Then If GetPlayerAlchemy(Index) < Item(ItemNum).AlchemyReq Then PlayerMsg Index, "You are not skilled enough in alchemy to craft this item.", BrightRed Exit Sub End If End If ' Enchant If Item(ItemNum).EnchantReq > 0 Then If GetPlayerEnchants(Index) < Item(ItemNum).EnchantReq Then PlayerMsg Index, "You are not skilled enough in enchantments to use this.", BrightRed Exit Sub End If End If For i = 1 To MAX_RECIPE_ITEMS If Item(ItemNum).Recipe(i) > 0 Then MaxItems = i End If Next ' Make sure there are at least two ingredients, and prevent subscript out of range If MaxItems < 2 Or MaxItems > MAX_RECIPE_ITEMS Then PlayerMsg Index, "This is an incomplete recipe.", BrightRed Exit Sub End If ' Proceed to craft the item CraftItem Index, ItemNum, MaxItems, Result End Select End If End Sub ``` At the bottom of **modPlayer** add this: ``` Sub CraftItem(ByVal Index As Long, ByVal ItemNum As Long, ByVal MaxItems As Long, ByVal Result As Long) Dim i As Long Dim SM As Long Dim AL As Long Dim EN As Long ' See what items are needed, and how many ' If requirements are met, craft the item, if not, show failure message Select Case MaxItems Case 1 PlayerMsg Index, "This is an incomplete recipe.", BrightRed Exit Sub Case 2 If HasItem(Index, Item(ItemNum).Recipe(1)) And HasItem(Index, Item(ItemNum).Recipe(2)) Then TakeInvItem Index, Item(ItemNum).Recipe(1), 1 TakeInvItem Index, Item(ItemNum).Recipe(2), 1 GoTo MakeItem Else PlayerMsg Index, "You do not have all of the ingredients needed in this recipe.", BrightRed Exit Sub End If Case 3 If HasItem(Index, Item(ItemNum).Recipe(1)) And HasItem(Index, Item(ItemNum).Recipe(2)) And HasItem(Index, Item(ItemNum).Recipe(3)) Then TakeInvItem Index, Item(ItemNum).Recipe(1), 1 TakeInvItem Index, Item(ItemNum).Recipe(2), 1 TakeInvItem Index, Item(ItemNum).Recipe(3), 1 GoTo MakeItem Else PlayerMsg Index, "You do not have all of the ingredients needed in this recipe.", BrightRed Exit Sub End If Case 4 If HasItem(Index, Item(ItemNum).Recipe(1)) And HasItem(Index, Item(ItemNum).Recipe(2)) And HasItem(Index, Item(ItemNum).Recipe(3)) And HasItem(Index, Item(ItemNum).Recipe(4)) Then TakeInvItem Index, Item(ItemNum).Recipe(1), 1 TakeInvItem Index, Item(ItemNum).Recipe(2), 1 TakeInvItem Index, Item(ItemNum).Recipe(3), 1 TakeInvItem Index, Item(ItemNum).Recipe(4), 1 GoTo MakeItem Else PlayerMsg Index, "You do not have all of the ingredients needed in this recipe.", BrightRed Exit Sub End If Case 5 If HasItem(Index, Item(ItemNum).Recipe(1)) And HasItem(Index, Item(ItemNum).Recipe(2)) And HasItem(Index, Item(ItemNum).Recipe(3)) And HasItem(Index, Item(ItemNum).Recipe(4)) And HasItem(Index, Item(ItemNum).Recipe(5)) Then TakeInvItem Index, Item(ItemNum).Recipe(1), 1 TakeInvItem Index, Item(ItemNum).Recipe(2), 1 TakeInvItem Index, Item(ItemNum).Recipe(3), 1 TakeInvItem Index, Item(ItemNum).Recipe(4), 1 TakeInvItem Index, Item(ItemNum).Recipe(5), 1 PlayerMsg Index, "You do not have all of the ingredients needed in this recipe.", BrightRed Exit Sub Else PlayerMsg Index, "You do not have all of the ingredients needed in this recipe.", BrightRed Exit Sub End If End Select MakeItem: GiveInvItem Index, Result, 1 TakeInvItem Index, ItemNum, 0 PlayerMsg Index, "You have successfully created a " & Trim(Item(Result).Name) & ".", White ' Give the Exp ' If the player has a recipe, determine what type it is... SM = Item(ItemNum).Smithy If SM > 0 Then SetPlayerSmithExp (Index), GetPlayerSmithExp(Index) + GetPlayerSmith(Index) * 2 + 5 SendEXP Index Exit Sub End If AL = Item(ItemNum).Alchemist If AL > 0 Then SetPlayerAlchemyExp (Index), GetPlayerAlchemyExp(Index) + GetPlayerAlchemy(Index) * 2 + 5 SendEXP Index Exit Sub End If EN = Item(ItemNum).Enchanter If EN > 0 Then SetPlayerEnchantsExp (Index), GetPlayerEnchantsExp(Index) + GetPlayerEnchants(Index) * 2 + 5 SendEXP Index Exit Sub End If End Sub ' Check Proficiency Level Up - BlackSmith Sub SmithLevelUp(ByVal Index As Long) Dim i As Long Dim expRollover As Long expRollover = GetPlayerSmithExp(Index) - GetPlayerNextSmithLevel(Index) If GetPlayerSmith(Index) >= MAX_SKILL_LEVEL Then Exit Sub ' Level up SetPlayerSmith Index, GetPlayerSmith(Index) + 1 Call SetPlayerSmithExp(Index, expRollover) SendPlayerData Index SendEXP Index ' Send messages PlayerMsg Index, "Your skill as a smith has increased!", BrightGreen End Sub ' Check Proficiency Level Up - Alchemy Sub AlchemyLevelUp(ByVal Index As Long) Dim i As Long Dim expRollover As Long expRollover = GetPlayerAlchemyExp(Index) - GetPlayerNextAlchemyLevel(Index) If GetPlayerAlchemy(Index) >= MAX_SKILL_LEVEL Then Exit Sub ' Level up SetPlayerAlchemy Index, GetPlayerAlchemy(Index) + 1 Call SetPlayerAlchemyExp(Index, expRollover) SendPlayerData Index SendEXP Index ' Send messages PlayerMsg Index, "Your skill in alchemy has increased!", BrightGreen End Sub ' Check Proficiency Level Up - Enchantor Sub EnchantsLevelUp(ByVal Index As Long) Dim i As Long Dim expRollover As Long expRollover = GetPlayerEnchantsExp(Index) - GetPlayerNextEnchantsLevel(Index) If GetPlayerEnchants(Index) >= MAX_SKILL_LEVEL Then Exit Sub ' Level up SetPlayerEnchants Index, GetPlayerEnchants(Index) + 1 Call SetPlayerEnchantsExp(Index, expRollover) SendPlayerData Index SendEXP Index ' Send messages PlayerMsg Index, "Your Enchanting skill has increased!", BrightGreen End Sub ``` **Client Side** **In modGlobals add this to the bottom:** ``` Public SkillType As Long ``` **In modTypes** Find : **Private Type PlayerRec** Add this to the bottom before End Type: ``` Smith As Byte SmithExp As Long Alchemy As Byte AlchemyExp As Long Enchants As Long EnchantsExp As Long ``` Find : **Private Type ItemRec** Add this to the bottom of Private Type ItemRec (before End Type) ``` 'crafting Tool As Long ToolReq As Long Recipe(1 To MAX_RECIPE_ITEMS) As Long Smithy As Long SmithReq As Long Alchemist As Long AlchemyReq As Long Enchanter As Long EnchantReq As Long ``` **In modConstants** Find: ``` Public Const ITEM_TYPE_SPELL As Byte = 8 ``` Add this below: ``` Public Const ITEM_TYPE_RECIPE As Byte = 9 ``` Add this to the bottom of the tile constants also( note your number might be different from mine) ``` Public Const TILE_TYPE_CRAFT As Byte = 15 ``` Also Add this under the rest of the general constants: ``` ' max number of crafting items Public Const MAX_RECIPE_ITEMS As Long = 5 ``` In **modGameEditors** Find: **Public Sub ItemEditorInit()** Under it add this: ``` Dim RecipeIndex As Long ``` under that **find** this: ``` If frmEditor_Item.Visible = False Then Exit Sub EditorIndex = frmEditor_Item.lstIndex.ListIndex + 1 ``` under that **add this:** ``` RecipeIndex = frmEditor_Item.scrlItemNum.Value ``` In the same sub **find** this: ``` If (frmEditor_Item.cmbType.ListIndex = ITEM_TYPE_SPELL) Then frmEditor_Item.fraSpell.Visible = True frmEditor_Item.scrlSpell.Value = .Data1 Else frmEditor_Item.fraSpell.Visible = False End If ``` Under it **add** this: ``` If (frmEditor_Item.cmbType.ListIndex = ITEM_TYPE_RECIPE) Then frmEditor_Item.fraRecipe.Visible = True frmEditor_Item.scrlItemNum.Max = MAX_RECIPE_ITEMS frmEditor_Item.scrlItemNum.Value = 1 frmEditor_Item.scrlResult.Value = .Data3 frmEditor_Item.cmbCToolReq.ListIndex = .ToolReq Else frmEditor_Item.fraRecipe.Visible = False End If ``` Under that you will see this : ``` ' Basic requirements frmEditor_Item.scrlAccessReq.Value = .AccessReq frmEditor_Item.scrlLevelReq.Value = .LevelReq ``` Add this below it: ``` ' Proficiencies frmEditor_Item.scrlSmithReq.Value = .SmithReq frmEditor_Item.chkSM = .Smithy ' Proficiencies frmEditor_Item.scrlAlchemyReq.Value = .AlchemyReq frmEditor_Item.chkAL = .Alchemist ' Proficiencies frmEditor_Item.scrlEnchantReq.Value = .EnchantReq frmEditor_Item.chkEN = .Enchanter ``` **Still in modGameEditors find**: ``` ' slide If frmEditor_Map.optSlide.Value Then .Type = TILE_TYPE_SLIDE .Data1 = MapEditorSlideDir .Data2 = 0 .Data3 = 0 End If ``` under this add: ``` ' crafting If frmEditor_Map.optCraft.Value Then .Type = TILE_TYPE_CRAFT .Data1 = SkillType .Data2 = 0 .Data3 = 0 End If ``` **In modText** **find this**: ``` Case TILE_TYPE_SLIDE DrawText TexthDC, tX, tY, "S", QBColor(BrightCyan) ``` Under it add this: ``` Case TILE_TYPE_CRAFT DrawText TexthDC, tX, tY, "CR", QBColor(White) ``` **In modDatabase** Find this Sub: **Sub SetPlayerExp** under the whole sub add this: ``` 'prof smithy Function GetPlayerSmith(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerSmith = Player(Index).Smith ' Error handler Exit Function errorhandler: HandleError "GetPlayerSmith", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerSmith(ByVal Index As Long, ByVal Smith As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).Smith = Smith ' Error handler Exit Sub errorhandler: HandleError "SetPlayerSmith", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub Function GetPlayerSmithExp(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerSmithExp = Player(Index).SmithExp ' Error handler Exit Function errorhandler: HandleError "GetPlayerSmithExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerSmithExp(ByVal Index As Long, ByVal SmithExp As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).SmithExp = SmithExp ' Error handler Exit Sub errorhandler: HandleError "SetPlayerSmithExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub 'prof alachemy Function GetPlayerAlchemy(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerAlchemy = Player(Index).Alchemy ' Error handler Exit Function errorhandler: HandleError "GetPlayerAlchemy", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerAlchemy(ByVal Index As Long, ByVal Alchemy As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).Alchemy = Alchemy ' Error handler Exit Sub errorhandler: HandleError "SetPlayerAlchemy", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub Function GetPlayerAlchemyExp(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerAlchemyExp = Player(Index).AlchemyExp ' Error handler Exit Function errorhandler: HandleError "GetPlayerAlchemyExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerAlchemyExp(ByVal Index As Long, ByVal AlchemyExp As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).AlchemyExp = AlchemyExp ' Error handler Exit Sub errorhandler: HandleError "SetPlayerAlchemyExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub 'prof enchantor Function GetPlayerEnchants(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerEnchants = Player(Index).Enchants ' Error handler Exit Function errorhandler: HandleError "GetPlayerEnchants", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerEnchants(ByVal Index As Long, ByVal Enchants As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).Enchants = Enchants ' Error handler Exit Sub errorhandler: HandleError "SetPlayerEnchants", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub Function GetPlayerEnchantsExp(ByVal Index As Long) As Long ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Function GetPlayerEnchantsExp = Player(Index).EnchantsExp ' Error handler Exit Function errorhandler: HandleError "GetPlayerEnchantsExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Function End Function Sub SetPlayerEnchantsExp(ByVal Index As Long, ByVal EnchantsExp As Long) ' If debug mode, handle error then exit out If Options.Debug = 1 Then On Error GoTo errorhandler If Index > MAX_PLAYERS Then Exit Sub Player(Index).EnchantsExp = EnchantsExp ' Error handler Exit Sub errorhandler: HandleError "SetPlayerEnchantsExp", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit Sub End Sub '/prof ``` **In modHandleData** Find this: **Private Sub HandlePlayerExp** Under: **Dim i As Long** Add this: ``` Dim TNSM As Long Dim TNAL As Long Dim TNEN As Long ``` Still in sub **HandlePlayerExp** before the **Error Handler** add: ``` ' Proficiencies smithy SetPlayerSmithExp Index, Buffer.ReadLong TNSM = Buffer.ReadLong frmMain.lblSmithExp.Caption = GetPlayerSmithExp(Index) & "/" & TNSM ' Proficiencies alchemy SetPlayerAlchemyExp Index, Buffer.ReadLong TNAL = Buffer.ReadLong frmMain.lblAlchemyExp.Caption = GetPlayerAlchemyExp(Index) & "/" & TNAL ' Proficiencies enchant SetPlayerEnchantsExp Index, Buffer.ReadLong TNEN = Buffer.ReadLong frmMain.lblEnchantsExp.Caption = GetPlayerEnchantsExp(Index) & "/" & TNEN ``` Still in **modHandleData** Find the sub: **HandlePlayerData** Under : Call SetPlayerPK(i, Buffer.ReadLong) Add this: ``` Call SetPlayerSmith(i, Buffer.ReadLong) Call SetPlayerAlchemy(i, Buffer.ReadLong) Call SetPlayerEnchants(i, Buffer.ReadLong) ``` Still in the same sub find this : ``` ' Set the character windows frmMain.lblCharName = GetPlayerName(MyIndex) & " - Level " & GetPlayerLevel(MyIndex) ``` Under it add this: ``` frmMain.lblSmith = GetPlayerSmith(MyIndex) frmMain.lblAlchemy = GetPlayerAlchemy(MyIndex) frmMain.lblEnchants = GetPlayerEnchants(MyIndex) ``` **In frmEditor_Item** : Under: **Option Explicit** Add this: ``` Private RecipeIndex As Long ``` Next find this: ``` If (cmbType.ListIndex = ITEM_TYPE_SPELL) Then fraSpell.Visible = True Else fraSpell.Visible = False End If ``` Under it add this: ``` If (cmbType.ListIndex = ITEM_TYPE_RECIPE) Then fraRecipe.Visible = True Else fraRecipe.Visible = False End If ``` **FORM WORK- Ok I included frm Examples of the item editor and the map editor at the bottom of the post.. I left frmMain out cause its only 6 labels and no code =)** FORM WORK- >! frmeditor_item >! 1\. First create a frame and name it : **fraRecipe** >! **All of this goes inside of the new frame!** >! 2.Make a new label named >! :**Label7** >! Set the Caption to: **1.** >! 3. >! Next create a label and place it right next to the first one and name >! it : **lblItem1** >! Set the caption to : **Item: >! None** >! 4\. Under that new label make a Scroll bar named: >! **scrlItem1** >! Set the Min to 0 >! 5\. Under that scrollbar >! make another label and name it : **lblItemNum** >! Set the caption >! to : **Item: None** >! 6\. Under **lblItemNum** >! Make another scroll bar and name it : >! **scrlItemNum** >! Set the Min to 1 >! 7\. Next somewhere in the >! new frame (**fraRecipe**) make a **label** and give it >! the caption : **Tool:** >! 8\. Under that make a >! **combobox** and name it: **cmbCToolReq** >! In >! the **list** add the following (Doesnt matter just giving you some >! ideas) : **None >! Hammer >! Mortar & Pestle >! Cooking >! Pot >! Enchanting Stone >! Dwarf Hammer** >! 9.Somewhere still in >! fraRecipe add a label named: **lblResult** >! Set the caption to: >! **Result: None** >! 10\. Under that make yet another scrollbar >! and name it : **scrlResult** >! 11.Now under all that bum candy >! still on fraRecipe make a check box named :**chkSM** >! Set caption >! as: **Smith** >! 12\. beside that new checkbox make a label >! named:**lblSmith** >! caption set as : >! **1** >! 13\. Under that checkbox make a new scrollbar named: >! **scrlSmithReq** >! 14\. Beside that new checkbox make another >! one named:**chkAL** >! Set caption as: >! **Alchemy** >! 15\. beside that new checkbox make a label >! named:**lblAlchemy** >! caption set as : >! **1** >! 16\. Under that checkbox make a new scrollbar named: >! **scrlAlchemyReq** >! 17\. Beside that new checkbox make another >! one named:**chkEN** >! Set caption as: >! **Enchant** >! 18\. beside that new checkbox make a label >! named:**lblEnchants** >! caption set as : 1 >! 19\. Under that >! checkbox make a new scrollbar named: **scrlEnchantReq** >! Damn >! seems like alot but its not so you should have: >! 1 new frame >! 6 scrollbars >! 1 combobox >! 3 check boxes >! 8 Labels >! Ok now Still frmEditor _Item in the "Equipment Data" frame >! 1\. Make a new **label** and set the caption to : **Crafting Tool:** >! 2\. Next to it make a **combobox** and name it: **cmbCTool** >! In the List of the new combobox add the same tools as you did with the other combobox(cmbCToolreq) >! Now for the code.. >! Add this to the bottom of **frmEditor_item** >! ``` Private Sub scrlItem1_Change() >! If scrlItem1.Value > 0 Then >! lblItem1.Caption = "Item: " & Trim$(Item(scrlItem1.Value).Name) >! Else >! lblItem1.Caption = "Item: None" >! End If >! Item(EditorIndex).Recipe(RecipeIndex) = scrlItem1.Value >! End Sub >! Private Sub scrlItemNum_Change() >! RecipeIndex = scrlItemNum.Value >! lblItemNum.Caption = "Item: " & RecipeIndex >! scrlItem1.Value = Item(EditorIndex).Recipe(RecipeIndex) >! End Sub >! Private Sub scrlResult_Change() >! If scrlResult.Value > 0 Then >! lblResult.Caption = "Result: " & Trim$(Item(scrlResult.Value).Name) >! Else >! lblResult.Caption = "Result: None" >! End If >! Item(EditorIndex).Data3 = scrlResult.Value >! End Sub >! Private Sub scrlSmithReq_Change() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! lblSmith.Caption = "SM: " & scrlSmithReq >! Item(EditorIndex).SmithReq = scrlSmithReq.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "scrlSmithReq_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub scrlEnchantReq_Change() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! lblEnchants.Caption = "EN: " & scrlEnchantReq >! Item(EditorIndex).EnchantReq = scrlEnchantReq.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "scrlSwordReq_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub scrlAlchemyReq_Change() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! lblAlchemy.Caption = "Cook: " & scrlAlchemyReq >! Item(EditorIndex).AlchemyReq = scrlAlchemyReq.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "scrlAlchemyReq_Change", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub chkAL_Click() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! Item(EditorIndex).Alchemist = chkAL.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "chkAL_Click", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub chkEN_Click() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! Item(EditorIndex).Enchanter = chkEN.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "chkEN_Click", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub chkSM_Click() >! ' If debug mode, handle error then exit out >! If Options.Debug = 1 Then On Error GoTo errorhandler >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! Item(EditorIndex).Smithy = chkSM.Value >! ' Error handler >! Exit Sub >! errorhandler: >! HandleError "chkSM_Click", "frmEditor_Item", Err.Number, Err.Description, Err.Source, Err.HelpContext >! Err.Clear >! Exit Sub >! End Sub >! Private Sub cmbCTool_Click() >! If EditorIndex = 0 Or EditorIndex > MAX_ITEMS Then Exit Sub >! Item(EditorIndex).Tool = cmbCTool.ListIndex >! End Sub >! ``` Ok i think thats it for the item editor if i forgot something let >! me know please… >! **Now form work for the Map editor** >! **frmEditor_Map** >! 1\. Under the >! other map Attributes make a new radio button named : >! **optCraft** >! Set caption to: **Crafting** >! 2. >! Next in picAttributes (to the right side of map editor) make a new frame called: >! **fraCraft** >! Set Caption to: **Crafting** >! 3. >! Inside this new frame make a scroll bar named: >! **scrlCraft** >! 4\. Under the scroll bar make a label named: >! **lblCType** >! Set Caption as : >! **Type:** >! 5.Under that make a command button named: >! **cmdCOk** >! Set caption as: Ok >! Now add this code to the >! bottom of frmEditor_Map >! ``` ' crafting >! Private Sub scrlCraft_Change() >! With lblCType >! Select Case scrlCraft.Value >! Case 0 >! .Caption = "None" >! Case 1 >! .Caption = "Alchemy" >! Case 2 >! .Caption = "Crafting" >! Case 3 >! .Caption = "Enchanting" >! End Select >! End With >! End Sub >! Private Sub optCraft_Click() >! ClearAttributeDialogue >! picAttributes.Visible = True >! fraCraft.Visible = True >! scrlCraft.Max = 3 >! lblCType.Caption = "Type :" & scrlCraft.Value >! End Sub >! '/crafting >! ' crafting >! Private Sub cmdCOk_Click() >! SkillType = scrlCraft.Value >! fraCraft.Visible = False >! picAttributes.Visible = False >! End Sub >! ``` >! Ok now move >! to **frmMain**… >! This next part is up to you as you can >! make this however you want.. It just displays your skill lvs and progress to the >! next level. I made a new button and picture box to display them but you can do >! whatever you want.. >! Make 3 Labels somewhere on **frmMain**. >! Can be in the options, character window, ect.. >! 1\. Name the first label: >! **lblSmith** >! 2\. Name the second : >! **lblAlchemy** >! 3\. And name the third: >! **lblEnchants** >! Beside each of those make 3 more labels and >! name >! them >! 1.**lblSmithExp** >! 2.**lblAlchemyExp** >! 3.**lblEnchantsExp** >! The first 3 labels will show the current level your skills are at and the next 3 show your exp and exp to next level… That shoould be it and now you have a dynamic crafting system with skill levels and seperate crafting stations… Im sure i missed something as im very high so just let me know it all works on my end so no worries... **EDIT:: Under this in modConstants (Client and Server):** ``` ' max number of crafting items Public Const MAX_RECIPE_ITEMS As Long = 5 ``` **Add this:** ``` ' Proficiency Public Const MAX_SKILL_LEVEL As Long = 100 ```