| 03-07-2009, 02:30 AM | #1 |
What would be the best way to gay about making an optimized equipment system in this day and age of vJass? I know there are systems out there but I don't want to use them as that doesn't help me much. I appreciate their contribution but on something like that I want to be able to custom make it so I can make it do what I want it to do, and so I can just work on how decently I can write code. I was considering just using an integer array to store/retrieve items and to attach data to each item for stats, but I feel like there is probably a better way to go about this. Hence this post, anyone have any suggestions? |
| 03-07-2009, 07:45 AM | #2 | |
Quote:
The best way to gay? You can use an struct array loop, depending on how much items. Or you could use gamecache, like alot of the other item systems. I don't really see much more options of storing/retrieving item-types. |
| 03-07-2009, 11:07 PM | #3 |
There is zero reason to store information about items unless you have "multiple pages" or some such. Or perhaps attached values to items. But other than that; it's useless. If you want the highest flexibility, use a gamecache. There's no reason to use an array really, because you gain a tiny amount of preformance but add a daunting limit. The performance isin't really going to be noticed because item events aren't executed often anyway. |
| 03-07-2009, 11:20 PM | #4 |
Why don't you just reference other systems (you don't have to use them) to see how they go about solving the problem that you have now. |
| 03-08-2009, 12:30 AM | #5 |
Thing is none of them even come close to what I'm working with. 28 Attributes, about 18 of which are calculated values and the other 10 will derive an item ability combination to achieve the same effect (aka item ability addition) Unless you know of a convenient way to create 28 attributes per item. I'm just using 28 scope globals right now. |
| 03-09-2009, 01:52 AM | #6 | |
Quote:
28 Attributes? You're digging your own grave! Whatever; like I said use a table it's much more appropriate for this application then 28 different arrays. I'm assuming attributes are not dynamic; in that case you'd want to attach the data to the item ID and store it in a table somewhere and retreive it based on the id. If they are dynamic; you will have to use the above method; clone the data onto the item ID (gotten through H2I) and then alter it from the ID. It's not that complicated actually. The major thing is watching for pickup/drops and handling inventory slots. |
| 03-09-2009, 02:13 AM | #7 |
Actually me and Deaod came up with a method via SubString. It works quite well. to clear up confusion I will post what it looks like currently. It's.. well it's nowhere near finished but meh haha. JASS:library ItemLibrary initializer Init //***************************************************************************************************************// // ItemLibrary v. Alpha // // Item Database that provides functions // // to add, modify, or remove tens of different // // stats. To be used in conjunction with the Equipment // // System. // // Changelog: // // // //***************************************************************************************************************// private keyword FI globals //Function Interface private FI array IF //Equipment Stats. Corresponds to Item ID private string array DoThis private integer array HP //01 private integer array Mana //02 private integer array Attack //03 private integer array AtckSpdSkill //04 private integer array Armor //05 private integer array Strength //06 private integer array Agility //07 private integer array Intelligence //08 private integer array Skill //09 private integer array Mental //10 private real array MeeleCrit //11 private real array SpellCrit //12 private real array MeeleHit //13 private real array SpellHit //14 private real array SpellHaste //15 private real array SpellDamage //16 private real array Dodge //17 private real array Parry //18 private real array Block //19 private real array BlockValue //20 private real array FireR //21 private real array IceR //22 private real array LitR //23 private real array EathR //24 private real array PoisR //25 private real array DisR //26 private real array MagR //27 //Holders the Hold Item Abilities for Gear private integer array HPMod private integer array ManaMod private integer array DamageMod private integer array ArmorMod //Holders for Total Values of Non-Stackable Abilities private integer array ArmorTotal //Equipment System Globals private integer RHand = 1 private integer LHand = 2 private integer Chest = 3 private integer Helm = 4 private integer Gloves = 5 private integer Sleeves = 6 private integer Pants = 7 private integer Boots = 8 private integer Necklace = 9 private integer RRing = 10 private integer LRing = 11 private integer REarring = 12 private integer LEarring = 13 //Array to help with Loops private integer array LoopNum endglobals struct UnitData unit who integer ItemID boolean negative static method create takes unit who, integer ItemID, boolean negative returns UnitData D local UnitData D = UnitData.allocate() set D.who = who set D.ItemID = ItemID set D.negative = negative return D endmethod endstruct private function interface FI takes UnitData D returns nothing //These Functions are what will be called inside of ModStats. private function ItemHP takes UnitData D returns nothing local integer Hp = HP[D.ItemID] local integer i = 9 local integer neg = 0 if D.negative == true then set neg = 10 endif loop if Hp >= LoopNum[i] then set Hp = Hp - LoopNum[i] call UnitAddAbility(D.who, HPMod[i + neg]) call SetUnitAbilityLevel(D.who, HPMod[i + neg], 2) call UnitRemoveAbility(D.who, HPMod[i + neg]) set i = i + 1 endif set i = i - 1 exitwhen Hp == 0 endloop endfunction private function ItemMana takes UnitData D returns nothing local integer MP = Mana[D.ItemID] local integer i = 9 local integer neg = 0 if D.negative == true then set neg = 10 endif loop if MP >= LoopNum[i] then set MP = MP - LoopNum[i] call UnitAddAbility(D.who, ManaMod[i + neg]) call SetUnitAbilityLevel(D.who, ManaMod[i + neg], 2) call UnitRemoveAbility(D.who, ManaMod[i + neg]) set i = i + 1 endif set i = i - 1 exitwhen MP == 0 endloop endfunction private function ItemDamage takes UnitData D returns nothing local integer Dmg = Attack[D.ItemID] local integer i = 9 local integer neg = 0 if D.negative == true then set neg = 10 endif loop if Dmg >= LoopNum[i] then set Dmg = Dmg - LoopNum[i] call UnitAddItem(D.who, CreateItem(DamageMod[i+neg], GetUnitX(D.who), GetUnitY(D.who))) set i = i + 1 endif set i = i - 1 exitwhen Dmg == 0 endloop endfunction private function ItemAtckSpeed takes UnitData D returns nothing endfunction private function ItemArmor takes UnitData D returns nothing local integer ArmVal = Armor[D.ItemID] local integer i = 0 local integer neg = 0 if D.negative == true then set neg = 9 set ArmVal = -1*ArmVal endif set ArmorTotal[GetPlayerId(GetOwningPlayer(D.who))] = ArmorTotal[GetPlayerId(GetOwningPlayer(D.who))] + ArmVal set ArmVal = R2I(((.15*I2R((ArmorTotal[GetPlayerId(GetOwningPlayer(D.who))])))/ 1. + (.05*(I2R(GetHeroLevel(D.who)))))) loop exitwhen i > 17 call UnitRemoveAbility(D.who, ArmorMod[i]) set i = i + 1 endloop set i = 8 if ArmVal < 0 then set ArmVal = 0 endif loop if ArmVal >= LoopNum[i] then set ArmVal = ArmVal - LoopNum[i] call UnitAddAbility(D.who, ArmorMod[i + neg]) set i = i + 1 endif set i = i - 1 exitwhen ArmVal == 0 endloop endfunction private function ItemStr takes UnitData D returns nothing endfunction private function ItemAgi takes UnitData D returns nothing endfunction private function ItemInt takes UnitData D returns nothing endfunction private function ItemMental takes UnitData D returns nothing endfunction private function ItemSkill takes UnitData D returns nothing endfunction private function ItemMeeleCrit takes UnitData D returns nothing endfunction private function ItemSpellCrit takes UnitData D returns nothing endfunction private function ItemMeeleHit takes UnitData D returns nothing endfunction private function ItemSpellHit takes UnitData D returns nothing endfunction private function ItemSpellHaste takes UnitData D returns nothing endfunction private function ItemSpellDamage takes UnitData D returns nothing endfunction private function ItemDodge takes UnitData D returns nothing endfunction private function ItemParry takes UnitData D returns nothing endfunction private function ItemBlock takes UnitData D returns nothing endfunction private function ItemBlockValue takes UnitData D returns nothing endfunction private function ItemFireR takes UnitData D returns nothing endfunction private function ItemIceR takes UnitData D returns nothing endfunction private function ItemLitR takes UnitData D returns nothing endfunction private function ItemEarthR takes UnitData D returns nothing endfunction private function ItemPoisR takes UnitData D returns nothing endfunction private function ItemDisR takes UnitData D returns nothing endfunction private function ItemMagR takes UnitData D returns nothing endfunction //This function will be called anytime a piece of equipment is equipped or uneqipped. It will run through all possible stats and make adjustments. Strength/Agility/Intelligence/Armor/Attack must all be completely recalculated everytime this is called since the item abilities of a same type do not stack. function ModStats takes integer ItemID, unit who, boolean negative returns nothing local UnitData D = UnitData.create(who, ItemID, negative) local integer i = 0 local integer k loop set k = S2I(SubString(DoThis[ItemID], i, i+2)) exitwhen k == 0 call IF[k].evaluate(D) set i = i + 2 endloop call D.destroy() endfunction //Initalize the Globals Here. Item stats are also initalized here. private function Init takes nothing returns nothing //Basic Global Init //Function Interface Setup set IF[1] = ItemHP set IF[2] = ItemMana set IF[3] = ItemDamage set IF[4] = ItemAtckSpeed set IF[5] = ItemArmor set IF[6] = ItemStr set IF[7] = ItemAgi set IF[8] = ItemInt set IF[9] = ItemMental set IF[10] = ItemSkill set IF[11] = ItemMeeleCrit set IF[12] = ItemSpellCrit set IF[13] = ItemMeeleHit set IF[14] = ItemSpellHit set IF[15] = ItemSpellHaste set IF[16] = ItemSpellDamage set IF[17] = ItemDodge set IF[18] = ItemParry set IF[19] = ItemBlock set IF[20] = ItemBlockValue set IF[21] = ItemFireR set IF[22] = ItemIceR set IF[23] = ItemLitR set IF[24] = ItemEarthR set IF[25] = ItemPoisR set IF[26] = ItemDisR set IF[27] = ItemMagR //Set the Loop Helper up set LoopNum[0] = 1 set LoopNum[1] = 2 set LoopNum[2] = 4 set LoopNum[3] = 8 set LoopNum[4] = 16 set LoopNum[5] = 32 set LoopNum[6] = 64 set LoopNum[7] = 128 set LoopNum[8] = 256 set LoopNum[9] = 512 //HPMod Abities Init. 0-9 = + 10-19 = - set HPMod[0] = 'A00E' set HPMod[1] = 'A00I' set HPMod[2] = 'A00J' set HPMod[3] = 'A00K' set HPMod[4] = 'A00L' set HPMod[5] = 'A00M' set HPMod[6] = 'A00N' set HPMod[7] = 'A00O' set HPMod[8] = 'A00P' set HPMod[9] = 'A00Q' set HPMod[10] = 'A00R' set HPMod[11] = 'A00S' set HPMod[12] = 'A00T' set HPMod[13] = 'A00U' set HPMod[14] = 'A00V' set HPMod[15] = 'A00W' set HPMod[16] = 'A00Z' set HPMod[17] = 'A00X' set HPMod[18] = 'A00Y' set HPMod[19] = 'A010' //ManaMod Abilities Init. 0-9 = + 10-19 = - set ManaMod[0] = 'A011' set ManaMod[1] = 'A012' set ManaMod[2] = 'A013' set ManaMod[3] = 'A014' set ManaMod[4] = 'A015' set ManaMod[5] = 'A016' set ManaMod[6] = 'A017' set ManaMod[7] = 'A018' set ManaMod[8] = 'A019' set ManaMod[9] = 'A01A' set ManaMod[10] = 'A01B' set ManaMod[11] = 'A01C' set ManaMod[12] = 'A01D' set ManaMod[13] = 'A01E' set ManaMod[14] = 'A01F' set ManaMod[15] = 'A01G' set ManaMod[16] = 'A01H' set ManaMod[17] = 'A01I' set ManaMod[18] = 'A01J' set ManaMod[19] = 'A01K' //DamageMod Items Init. 0-9 = + 10-19 = - set DamageMod[0] = 'I001' set DamageMod[1] = 'I002' set DamageMod[2] = 'I003' set DamageMod[3] = 'I004' set DamageMod[4] = 'I005' set DamageMod[5] = 'I006' set DamageMod[6] = 'I007' set DamageMod[7] = 'I008' set DamageMod[8] = 'I009' set DamageMod[9] = 'I00A' set DamageMod[10] = 'I00B' set DamageMod[11] = 'I00C' set DamageMod[12] = 'I00D' set DamageMod[13] = 'I00E' set DamageMod[14] = 'I00F' set DamageMod[15] = 'I00G' set DamageMod[16] = 'I00H' set DamageMod[17] = 'I00I' set DamageMod[18] = 'I00J' set DamageMod[19] = 'I00K' //ArmorMod Abilities Init. 0-8 = + 9-18 = - set ArmorMod[0] = 'A025' set ArmorMod[1] = 'A026' set ArmorMod[2] = 'A027' set ArmorMod[3] = 'A028' set ArmorMod[4] = 'A029' set ArmorMod[5] = 'A02A' set ArmorMod[6] = 'A02B' set ArmorMod[7] = 'A02C' set ArmorMod[8] = 'A02D' set ArmorMod[9] = 'A02E' set ArmorMod[10] = 'A02F' set ArmorMod[11] = 'A02G' set ArmorMod[12] = 'A02H' set ArmorMod[13] = 'A02I' set ArmorMod[14] = 'A02J' set ArmorMod[15] = 'A02K' set ArmorMod[16] = 'A02L' set ArmorMod[17] = 'A02M' //ArmorTotal Init set ArmorTotal[0] = 0 set ArmorTotal[1] = 0 set ArmorTotal[2] = 0 set ArmorTotal[3] = 0 set ArmorTotal[4] = 0 set ArmorTotal[5] = 0 // Item: TestHelm Stats: +25 Hp +25 Mana ID 1 set HP[1] = 25 set Mana[1] = 25 set DoThis[1] = "010200" // Item 2 Init // Etc... endfunction endlibrary JASS:scope EquipSystem globals item array ArmorInSlot boolean array ArmorFull endglobals function GetEquippedItem takes integer slot, unit who returns nothing local integer ItemID //Check for the item if ArmorFull[((13 * GetPlayerId(GetOwningPlayer(who))) + slot)] == false then //Display Error else set ItemID = GetItemLevel(ArmorInSlot[((13 * GetPlayerId(GetOwningPlayer(who))) + slot)]) //Remove Stats call ModStats(ItemID, who, true) //Modify the Multiboard //Add the Item to Inventory (Upon completing the inventory system, this will change.) call UnitAddItem(who, ArmorInSlot[((13 * GetPlayerId(GetOwningPlayer(who))) + slot)]) set ArmorInSlot[((13 * GetPlayerId(GetOwningPlayer(who))) + slot)] = null endif endfunction function EquipItem takes item whatitem, unit who returns nothing local integer ItemID local integer Slot set ItemID = GetItemLevel(whatitem) //Returns Item ID set Slot = R2I(GetWidgetLife(whatitem)) //Returns Slot ID //Check if slot is full if ArmorFull[((13 * GetPlayerId(GetOwningPlayer(who))) + Slot)] == true then call GetEquippedItem((13*GetPlayerId(GetOwningPlayer(who)))+Slot, who) endif //Apply Stats call ModStats(ItemID, who, false) //Modify Multiboard //Remove Item (Upon completing the inventory system, this wil change.) call UnitRemoveItem(who, whatitem) set ArmorInSlot[((13 * GetPlayerId(GetOwningPlayer(who))) + Slot)] = whatitem endfunction endscope Everytime I type HIDDENJASS I think of ninjas that code. Anyone else? |
| 03-09-2009, 03:47 AM | #8 |
If you are using the SubString method, abuse the colour tags. Unless you are already doing it, I guess this is an useless post. |c xx x xxx xx|r Everything that's an x is usable. -Av3n |
| 03-09-2009, 03:50 AM | #9 |
I still think any game with 28 attributes tho is far over compensating for things. private real array MeeleCrit //11 private real array SpellCrit //12 Things can easily be combined. SpellCrit + MeleeCrit = Regular Crit etc. But seriously thats not much of a problem as the fact that no one will know how to calculate damage if you have this: private real array Dodge //17 private real array Parry //18 private real array Block //19 private real array BlockValue //20 (dodge, parry, and block? jezz way to use 3 words that basically have nearly exact connotations.) And if that isn't enough they have to worry about elements as well? Theres no end! (Don't get me wrong d2 and titan quest with elemental stuff is alright but it's horrid practice for any game design I'd say since it's just too much overwhelming cake that makes game features just look better than they actually are.) I dunno maybe that's just me though. . . I kind of like the idea that the person playing actually has a bit of an idea of what the hell is going on. http://www.thehelper.net/forums/showthread.php?t=120068 This is the only inventory system that struck me as worthwhile so far for wc3. Simple yet effectively it uses a bit of vJASS and the display on a multiboard is something that actually makes sense.I can't imagine doing any inventory over the size of 6 slots without using the multiboard(Also in-game UI developed that pauses the game to show your items is beyond lame!). |
| 03-09-2009, 03:57 AM | #10 |
Yeah; there's alot going on here. And this is for items. Why are you even using a static method with 28 attributes? Use a linked list with a callback function for each attribute and save yourself a coding nightmare. <or better yet; just use constant codes for the static visible attributes and cache everything else as an arbitrary stat.> |
| 03-09-2009, 04:31 AM | #11 |
SpellCrit and Meelecrit are different because there are different formulas associated with each. Parry/Block are frontal only. Block does not mitigate 100% damage unless the Block Value equals or exceeds that damage recieved. Parry is not applied to all classes like Dodge is. I'm not overcompensating, I am allowing a large diversity in item choice. What do you mean by abuse the color tags? and honestly this isn't a coding nightmare. No matter what I do, I HAVE to code each stat. All the "reals" are simple addition and won't take 5 minutes to code. The only one that will be annoying is Armor as I am making armor depricate with level. Could you explain your method in more detail Black? From what I can tell this is the way of least hassle, although as far as optimization goes I am unsure. Also, if you think this is alot to keep track of, then I don't really know what to say. This is nothing compared to most MMOs nowadays. And to Switch: What the hell are you talking about? Nowhere do I pause the game. and I AM using a multiboard. I havn't added it yet. |
| 03-09-2009, 06:13 AM | #12 |
You can use the colour tags (what I showed before) to store information on the item's name. For example you can have it like this: "|cxxxxxxxx|r<Item Name>" You can use those 8 x's to do stuff if your using SubString -Av3n |
| 03-09-2009, 06:45 AM | #13 |
Thats actually a nifty idea. I will keep that in mind. |
