Showing posts with label CharSi. Show all posts
Showing posts with label CharSi. Show all posts

Wednesday, July 1, 2009

Java: CharSi Update #24

While using the program I, and others, ran into a few equipment pieces that didn't add the bonuses they should. This was due to either typos on my part or miswording of the mod itself, such as the "+2 to Combat skills" mod was spelled "+2 to Combat" instead. These were all very minor changes to about a half dozen different text files. There might be more out there, but I haven't found them yet.

A code clean-up was also performed to remove some unused variables and code pieces as well as remove all of the "public" identifiers from the variables and methods, as it wasn't necessary. This shortened the number of code lines a bit, not extremely noticable but more a personal preference than anything else.

Next on my To-Do list was to add some additional checks to the system to ensure that when creating items in the generator or selecting a value for a variable mod the value input was valid. Up to this point a Breast Plate could technically have a defense value of 100k. That is no longer possible. Now there is a check that will only allow values that fall between the given minimum and maximum mod values. This required a couple code lines addition to the DetermineRangeValue method in all of the class files.

if(CharSi.userInput){
while(rangeWrong){
userInput = Integer.parseInt(JOptionPane.showInputDialog(helmBackPanel, "Choose a value between " + start + " and " + end, modName, JOptionPane.PLAIN_MESSAGE));
if(userInput > Integer.parseInt(end) || userInput <>
JOptionPane.showMessageDialog(helmBackPanel, "Value given outside the allowed range. Retry.", "Input Error", JOptionPane.ERROR_MESSAGE);
rangeWrong = true;
}else
rangeWrong = false;
}
}

This piece is only active if the user is manually inputting values for variable mods. The rangeWrong boolean variable is initially set to True until the check is made. The user input is then compared to the given minimum and maximum values and if it passes is accepted, otherwise the error appears and the user has to try again until a valid input is given.

Lastly I wanted to ensure that runewords could not be created in the generator in illegal base items, such as a Spirit shield in a buckler that allows less than 4 sockets. This required several changes to the GenerateRunewords class file. First I had to decide how to store the information for how many sockets each piece of equipment allows. This I did with several array of arrays. Each sub-array was two values long, the first for the name of the item and the second for the maximum number of sockets. The array of arrays were grouped by item type available in the item generator, so one for armor, another for hammers and so forth. This method was called when the GUI is created.

Next I needed to be able to obtain the number of sockets the runeword required. To do this I altered the text file of each runeword item so that it displayed the number of runes used in the description in parentheses.

Runes(3):
Thul + Io + Nef

When the runeword is selected in the GUI this number is saved in a variable in integer form for later comparison.

Lastly I needed a way to compare this rune number with the number of sockets that each item could have, then eliminate from the available list those items that don't qualify. This was done with another method, ComapreSocketNumbers. Basically this method would see which JRadioButton was selected in the GUI and compare the rune number with each available item. Those that had less sockets than runes needed were removed from the DefaultListModel.

if(shieldFlag){ //if shield radiobutton marked
for(int i = 0; i <>
if(Integer.parseInt(shieldSocketArray[i][1]) <>
if(baseListModel.contains(shieldSocketArray[i][0])){
int index = baseListModel.indexOf(shieldSocketArray[i][0]);
baseListModel.remove(index);
}
}
}
}

This method is called when either the Display Base JButton is pressed or a runeword is selected from the available list. However to ensure that items removed from the baseListModel can be returned a doClick() call is made on the Display Base JButton to repopulate the listModel fully before it is checked for illegal items. Otherwise once an item is removed, it is gone until the program is closed and reopened, which isn't too convenient.

My next projected changes to the program is to take into account aura bonuses from equipment and also the +O skill mods.

Tuesday, March 24, 2009

Java: CharSi Update #23

Saving the character information turned out to be easier than I first expected. JMenuItems were added to the File JMenu for saving purposes. One for simply saving the currently opened character and the other (Save As...) to assign a new name to the virtual character's save file.

When saving the character information all of it is saved to a text file with each component on a different line. For example part of a character's file could look like the following.

Paladin
1
20
1
1
20
1
1
20
0
0
1
1

The information is saved in a specific order. First the charType from the Skills class, followed by the values of all the skill point arrays, then each piece of equipment and finally with all of the user inputted values from the Stats panel (character level, user inputted Strength, difficulty level and so forth).

Saving a character takes only a second, opening one takes about 10-20 seconds due to all of the updates that occur every time a component's value is changed. Opening a character basically takes each line of the text file and assigns it to the appropriate variable. However when each variable is altered that prompts a re-evaluation of all the final character values. This re-evaluation works fine when altering a single value manually, such as adding 100 points into Vitality. But when it is run after each variable change it does slow down the opening of the character a bit. Not sure if there is a way around that, but I'll look into it.

I did have some issues when opening characters, all due to pretty basic mistakes on my part but they took quite a long time to track down. The main one was that they program wouldn't update the user inputted stat values correctly. Every time a character was loaded the values of vitality, energy, strength and dexterity revered back to their base values. Upon checking variables I did notice that the correct numbers were being saved into the variables that handle this information.

This meant that I had to find the spot in the code where things information was stopped from being applied correctly. I used a brute force method to do this. In the Open method code I broke the code up into 5-10 line sections and one at a time checked the desired variable before and after the code block. The variable value was output in the command prompt in each instance. If it's value was correct I moved onto the next code block, if it wasn't I took each line of code in that block one at a time to find where the problem was.

Eventually I found that the program wasn't saving the type of character correctly and as a result couldn't assign any values to the stat fields as the variables weren't being updated. The code that caused all the problem was this:

character = input.substring(index1, index2);
Skills.charBox.setSelectedItem(character);
Skills.charType = Skills.charType.substring(0,0);
Skills.charType = Skills.charType.concat(character);

It was the second two lines that were the problem. Worst part was they were completely unnecessary, the first two lines update the appropriate variables correctly so no other changes needed to have been made. Once the last two lines were removed everything worked correctly.

Now it's possible to save and open virtual characters and name them however desired. This coupled with all of the other changes I've made constitutes a significant alteration of the original program, and therefore means I posted an update in the DII forums. The new program can be downloaded here. My To-Do list is much smaller now and mostly contains checks to ensure the user input is valid or code cleanup. The only major component I'll be adding will be a new tab that will contain all of the breakpoint values for FCR, FHR, IAS and block speed. I intend this page to show where the current character's value is, which breakpoint they have hit and how many points are needed to hit the next breakpoint. It should be a fairly straightforward page, but I will have to think about how to make it available when the application is in Standalone mode.

Friday, March 6, 2009

Java: CharSi Update #22

Creating the GUI for the charm generator wasn't too difficult. It basically consisted of borrowing GUI pieces from other parts of the program. Since I've been doing that all along the page was up in a very short amount of time.


As expected the difficult part was creating the listeners behind the nice GUI interface. Many were fairly simple, for example the Clear JButton and Completed Items JList listener. On the other hand, other pieces were a bit more time consuming.

The list of prefix and suffixes came from a guide from the Diii.net site. Using this as my main information source I was able to setup the lists of possible values. From here creating the listeners was 75% of the entire page. First the selected item is obtained from the appropriate JList, then in the listener it is compared to all the possible options for that JList. Unfortunately the values possible differ with the size of the charm so once the mod is located then the program looks to see which JRadioButton is selected (and whose boolean flag was set to "true"). Once the charm type is identified then the String that will be tacked onto the end of the current display in the JTextArea is created.

if(mod.compareTo(AZURE) == 0){
if(smallFlag){
value = DetermineRangeValue(3,5,"Cold Resist %");
newMod = newMod.concat("Cold resist +" + value + "%\r\n");
}
if(largeFlag){
value = DetermineRangeValue(4,7,"Cold Resist %");
newMod = newMod.concat("Cold resist +" + value + "%\r\n");
}
if(grandFlag){
value = DetermineRangeValue(7,15,"Cold Resist %");
newMod = newMod.concat("Cold resist +" + value + "%\r\n");
}
}

When the Save JButton is selected a final check is done before the item is actually saved. It is possible to have both the suffix and prefix related to the same elemental damage type. Therefore a check must be made when the Save JButton is pressed before the charm is actually saved to ensure that these values are added together into the same mod line.

if(compare.indexOf("poison damage") )

The text in the JTextArea is rewritten if this is indeed the case and then the file is saved. Once saved the charms can then be added to the virtual character via a new tab in the Equipment page.

Adding and removing charms works the same way as all of the other equipment pages. The only change is the same charm may be added multiple times if desired. This avoids the need to create more than one type of charm and saves the user the hassle of scrolling through a long list of charms looking for just one more of a certain type of skiller.

One thing that was essential to this page is the charm counter display. This keeps track of how many charms of each type is already equipped to the virtual inventory and how many inventory spaces are left open. Before a charm can be added a check is made to ensure there is in face room for this charm. It can't be done on remaining spaces alone as grand charms can't be put in horizontally so only 10 total area allowed, for example.

grandFree = grandAllowed - grandCount;
if(charmSize == 3 && (grandFree == 0 || totalCount == 2))
add = false;

The checking method itself returns a boolean that is true unless it fails one of the checks such as above. It was actually easier to setup than I thought, as I was expecting to have to create an array of arrays that would replicate the physical inventory that I would fill in as charms were added. Not the best way to deal with the situation, so I'm glad the equations worked out as a much simpler solution.

Now the virtual character can be fully equipped, both with gear and charms. This includes the Battle.net only charms such as the Hellfire Torch. My next step is to create the ability to save characters so that they can be loaded in a latter program session without having to recreated them each time.

Friday, February 27, 2009

Java: CharSi Update #21

Apparently there were more bugs and problems with CharSi than I thought. I posted on the Diii.net for anyone who wanted to download the current version of CharSi. It seems more than I thought did, but as a result they found several issues or necessary improvements that need to be addressed to make CharSi much more viable.

A few of the issues were very basic. They ranged from adding "on attack" and "on monster kill" to the CtC section of the rare/magical item generator, correcting the spelling of the unique belt's pathname and switching the "\" characters with "/" characters to support operating systems other than Windows. These were resolved almost instantly and with little fuss.

Other issues were a little more complex but didn't require anything I hadn't already done before. For example adding a tool tip to the Defense JLabel that displays the current blocking percentage or a tool tip to the Character JLabel (in Stats tab) to display the required character level for the equipment worn. These followed the code for the strength/dexterity tool tips almost exactly. The same can be said for the JButton added to the magical/rare generator for adding automods to equipment. This borrowed completely from the JButtons already present for Charges and CtC mods.

However a few of the issues were definitely more involved and required some reorganization of the code to implement. In the Skill calculator a prerequisite can be unchecked while leaving the skill that depends on it with points present. Also I added the feature that when a skill has points added, if it's prerequisites don't already have points then a single one is added. A typical example would be the following:

if(event.getActionCommand().compareTo(FIREBALL) == 0){
fireSpellsArray[3] = Integer.parseInt(levelSelected);
if(fireSpellsArray[1] == 0 && fireSpellsArray[3] > 0)
fireBoltBox.setSelectedIndex(1);
if(fireSpellsArray[3] == 0){
meteorBox.setSelectedIndex(0);
hydraBox.setSelectedIndex(0);
enchantBox.setSelectedIndex(0);
fireBallBox.setSelectedIndex(0);
}
}

When the JComboBox for Fire Ball is utilized a few things must now happen. First the value selected is saved in the appropriate array for damage calculations. Then the first If statement checks that all prerequisites (fire Bolt) have a value greater than one, and if they don't then one point is added. The next If statement checks to ensure that if the value for Fire Ball is set to zero that all skills for which Fire Ball is a prerequisite are also set to zero.

Another option that was added from suggestions made by the Diii.net crowd was in the Stats page. Specifically the GUI portion that controls which difficulty the virtual character is in and which quests are completed needed to be reworked so that these two pieces were independent of each other. Up to this point if the character were in Hell, it was assumed all quests up to that point were completed and therefore the quest rewards already applied. To correct that the JCheckBoxes for the quests were changed to JButtons. When a button is pressed a dialog appears asking how many times the quest is completed. Then depending on the answer the appropriate bonus value is applied to the character. Along with that the JComboBox for difficulty selection had all of the code corresponding to the quest rewards removed, so now all it changes is the difficulty resistance value (0, -40, 100 respectively).

The last major piece that was added was also a suggestion from the Diii.net group. It was mentioned that too much user input is required to equip items with variable stats. So I added the ability to have those values automatically assigned a value. The values I allowed were maximum, minimum and average, along with the normal user input. To allow for this the DetermineRangeValue method in each class file needed to have a few lines of code added.

if(CharSi.userInput)
userInput = Integer.parseInt(JOptionPane.showInputDialog(helmBackPanel, "Choose a value between " + start + " and " + end, modName, JOptionPane.PLAIN_MESSAGE));
if(CharSi.maxValue)
userInput = Integer.parseInt(end);
if(CharSi.avgValue)
userInput = (Integer.parseInt(start) + Integer.parseInt(end))/2;
if(CharSi.minValue)
userInput = Integer.parseInt(start);

The method returns userInput so beyond the alteration to the DetermineRangeValue method nothing else needed to be done. I did set it so the value the user wants is saved from one session of CharSi to another, as I'm sure it would be annoying to have to reset this every time the program is used.

I did make changes based on every suggestion made by the Diii.net forum. I made the changes I could do relatively quickly. There are still some, for instance the option to save a virtual character for loading later on, that are on the To-Do list currently. The ones left are more features than bugs, so I'm leaving them for now and will get back to them later. First I want to add the ability to create any type of charm and then equip it to the virtual character's inventory so that those stats can be counted as well. Once that piece is done I'll make the updates available.

Friday, February 20, 2009

Java: CharSi Update #20

The tab for creating magical and rare items did borrow extensively from the runeword generator class. For the most part both tabs look extremely similar. However there were also some major differences. Specifically rare/magical items can have charges and a chance to cast certain character skills, so a pair of JButtons in the bottom panel enabled those options.

The longest part was, as expected, creating the mod JList/Listener. The list of mods themselves was originally the same list that could appear on any unique/runeword item. Once the code was complete, then those mods that can't actually appear on an item, such as Poison absorb, were commented out. Creating the JList options wasn't difficult so the extra code wasn't a problem, as all that is required is a simple addElement call to the DefaultModelList. Then the Listener was simply a massive if-else statement. When a specific mod is selected the user is prompted for to choose a value to assign the mod, such as Fire resist +30%. Then a String is created and added to the bottom of the already existing item's description.


When completed the user clicks the Save JButton. When this happens the special mods that pertain to defense/damage are used to calculate the item's final values in those areas. The text in the JTextArea is then updated with this information to display the final product as it will appear in the Equipment tab.

With this update the program is completely usable. Not that it wasn't usable before but now any type of character may be created and equipped with any item that can be found ingame. It is possible to generate illegal items, say with +20 to all skills. The amount of checks I put in place were minimal so the user does need to understand a little bit about the game so they don't create hacked items. Perhaps in the future I'll add in the necessary checks, but for now as long as one pays attention it should work fine.

As it is now a working program and the mods have agreed it may be useful to a selection of the community I am prepared to make it available to the general public of diii.net. I need to first create a bit of documentation to walk users through the quirks of the application, but that shouldn't take too much time. Then I'll make a post in the SPF and see what type of feedback I get.

I do expect bugs to be found, I'm not naive enough to think I made a perfect program. Most of the mod values should show correctly, but I am worried the damage numbers may be slightly off. I did the best I could and they look right to me, but I haven't tried every single permutation possible so there may still be a glitch with my calculations. I won't know until someone points it out to me though.

After the documentation is complete the next step is to allow the virtual character to have an inventory. This means a charm generator is next on the agenda. That and fixing any bugs others find when attempting to use CharSi.

Currently CharSi can be downloaded via RapidShare from this location.

Wednesday, February 11, 2009

Java: CharSi Update #19

I decided to break up the item generator task into three parts. Specifically there will be three tabs in the generator tab, one for runewords, charms and magical/rare items. As runewords are the most useful and important, I'll create that tab first.

As it turns out this tab wasn't as difficulty as I first assumed. It did help that I borrowed several GUI and listener pieces from the Armor and Runeword Wizard class files. This made putting the GUI together pretty much academic. Although for the base item panel I did have to change all of the components from JCheckBoxes to JRadioButtons, I didn't want more than one selected at a time.


Once the GUI was setup the listeners had to be attached to their designated components, and that is where the fun began. Just about every component has more than one listener attached, and vice versa, with all sorts of checks in place to ensure everything is set correctly. For example, when a JRadioButton is selected in the Base Items panel this marks a flag variable that designates which folder to view when looking for base item files. Also this populates the Possible Runeword JList with all runewords that can be made in this base item.

Still each listener only affected so much and therefore everything was put in order relatively quickly. The biggest, and most important, listener was the one attached to the Create Runeword JButton. This was the one that pretty much performed the actions the panel was created for. What it does is take the text from the Base Item Display and save this information into a set of String variables and an integer array. At the same time it does the same for the text in the Runeword Stats JTextArea, except that the majority of the mods are saved in a StringBuffer rather than an integer array. Only the mods affecting damage and defense are saved in an integer array. The reason for this is that once the base and runeword mods are saved, the variables pertaining to damage and defense are entered into the appropriate equations to determine their final outcomes. Once calculated all of the mod information is then combined into a StringBuffer variable and then exported to a newly created file.

While the creation is taking place the user is prompted to choose the values for any variable mods, as well as the name of the item being created. Once the runeword is finished it's name is displayed in the Completed Items JList, and selecting it will show the final result in the middle JTextArea component.

Of course, just being able to create these files isn't enough, it has to be possible to equip them on a virtual character as well. So the Importable Items JLists in the equipment tabs have their listeners set to populate the components once the application is launched. Once done it is now possible to equip user created runewords onto the virtual character.

Next step, allow the creation of rare and magical items by the user. This panel will borrow extensively from the runeword generator panel with only a few modifications. I don't think this will take too much time, but obtaining the full list of prefix and suffix mods and entering them into the code will be a bit time consuming.

Thursday, February 5, 2009

Java: CharSi Update #18

Mission accomplished. At least for this portion of the program. Several test characters were created and as a result quite a few bugs were found. Case in point the sorceress mastery skills weren't being calculated into the values displayed in the Skill tab's tooltips. Now they are.

Along with that I added a few extra features that I wanted and that also made the program much more user friendly. One would be that there is now a tooltip in the Stats panel for both the Strength and Dexterity JLabels. This tooltip displays how much strength/dexterity is required to wear all of the assigned equipment.

The second feature added is the option to add, or subtract, more than one point from the stat fields at a time. Up to this point the plus and minus JButtons had to be used to add stat points, and when 350 points needed to be added to Vitality the right mouse button got a lot of use. Now there is a JMenuItem under the File menu to add or subtract from each stat. A dialogue is displayed asking for a specific number and then that number is used to calculate the new stat values.

Now I have all the features I wanted set up and the mods and damage should be all calculated correctly. Most likely there are a few calculation bugs somewhere in the code, but I don't see them. So at this point I need others to find any errors for me. To that end I've send the idea to the diii.net forum moderators to see if such a program is useful to the community in general. I don't actually know if a similar program already exists that everyone is already using and I just haven't heard about it. I couldn't find one, but that doesn't mean it isn't out there. I won't compete with someone else. If something is already available I'll just use CharSi for myself. If it can be helpful to others, then I'll make it publicly available.

Either way, my next step is to work on an item generator that will allow the user to create any magical, rare or runeword item to equip onto the virtual character. Can't have those Spirit shields and +3 Fire skills amulets left unused.

Monday, January 26, 2009

Java: CharSi Update #17

Up to this point I have been ignoring any bonuses by having multiple pieces of a set equipped. Now that all equipment mods are stored and displayed correctly it is time to take these bonuses into account. I couldn't decide where to put the variables and methods needed to calculate what bonuses apply. So I created a whole new class file to hold these methods. The methods never get called inside this class file, only in the Stats and Character class files.

Each set evaluated in its own method, even though they are all called at the same time. The first thing to do is to determine how many set pieces are currently on the virtual character. Then the bonuses are applied depending on how many pieces are equipped and which ones they are.

static public void BerserkersCheck() {

for(int i = 0; i <>
berserkersArsenal[i] = 0;
berserkers = 0;

if(helm.compareTo(BERSERKERSHEAD) == 0) //detemrine which items are equipped
berserkersArsenal[0] = 1;
if(armor.compareTo(BERSERKERSHAU) == 0)
berserkersArsenal[1] = 1;
if(weaponOne.compareTo(BERSERKERSHAT) == 0)
berserkersArsenal[2] = 1;

berserkers = berserkersArsenal[0] + berserkersArsenal[1] + berserkersArsenal[2];

if(berserkers == 3){ //full set
charLevelMods[6] = charLevelMods[6] + 8;
charLevelDefOn[1] = charLevelDefOn[1] + 3;
eDmgOn = eDmgOn + 50;
stats[4] = stats[4] + 100;
specialMods[6] = specialMods[6] + 75;
modsOfNote[8] = modsOfNote[8] + 75;
poisonDamage[0] = poisonDamage[0] + 5;
poisonDamage[1] = poisonDamage[1] + 9;
itemStats[31] = itemStats[31] + 3;
}
if(berserkers == 2){
if(berserkersArsenal[0] == 1) //helm equipped
charLevelMods[6] = charLevelMods[6] + 8;
if(berserkersArsenal[1] == 1) //armor equipped
charLevelDefOn[1] = charLevelDefOn[1] + 3;
if(berserkersArsenal[2] == 1) //weapon equipped
eDmgOn = eDmgOn + 50;
stats[4] = stats[4] + 50;
}
}//end

First it is determined how many set pieces are equipped. Once that is determined each specific item is checked, if it is present the bonuses are added, if it isn't the item is skipped and the next item is checked. The arrays that contain the bonus information are then added along with the equipment arrays when everything is summed in the Stats class. This method is repeated for each of the other 31 sets. Most are a bit more complex, especially those that have more than three pieces to the set.

This ends the coding portion up to this point. Characters can be created, skills assigned, equipment worn and all of the bonuses and stats displayed appropriately. Now I need to run some checks to ensure everything really is displaying and no mods were left out. I checked everything as I added it to the program, but I'm sure some bugs slipped through. Case in point when putting this in I found out that the Barbarian mastery skill bonuses weren't being added to the displayed damage and attack rating values. So my next step is to create several text characters and see if their stats match up with what I am expecting.

Tuesday, January 20, 2009

Java: CharSi Update #16

Quite a lot of information has been gathered up to this point, from the equipment used to the mods the skills provide. However much of this information isn't displayed accurately, or at all, in the Stats panel. Now that is no longer the case. Every mod is now summed and displayed as accurately as I can in the Stats panel, from IAS provided by Fanaticism to the Attack Rating bonus from the Blessed Aim aura. Along with that the Skills panel now displays the elemental damage done while taking into account any bonuses provided by the equipment to increase this type of damage. This means if the virtual character is wearing Trang's gloves, then the poison damage done by the character's skills are increased accordingly.

However that is not all that was accomplished with this update. Quite a few minor points and details were addressed as well, including:
  • Add per level mods to Stats panel displayed values
  • Add elemental damage from equipment to Stats panel displayed values
  • Add skill bonuses to Stats panel displayed values
  • Correct poison damage calculation
  • Add ability to select active aura in Stats panel and add bonuses accordingly
  • Add ability to select attack type in Stats panel and add bonuses accordingly
  • Add hidden bonuses from Fade, Blessed Aim and Resist element auras
  • Set resistance values in Stats panel to no longer display a value higher than what is possible
  • Correct Enchant damage to take into account ranged weapons
  • Add display field for off weapon Increased Attack Speed

I think I caught all of the bugs I could find, but more testing will be needed to ensure that is the case. Now with these updates a character can be fully equipped with Set/Unique/White items, assigned skill points and see them accurately displayed in the Stats panel.


Most of the GUI changes were made in the damage sub-panel. Specifically I removed the assassin kick and paladin smite damage fields and instead Incorporated them into the primary weapon display field. I needed the space as I then had to include a few more JComboBoxes for prebuff skills as well as possible aura selections. Each of these JComboBoxes will be populated with options as those skills are assigned points in the Skills panel.

I believe I have the damage calculation correct. There are exceptions for several of the skills, such as Vengeance, Enchant, Smite, assassin kick skills, Berserk and so forth. As a result that particular method is quite confusing and unless someone points a bug out to me I'll have a devil of a time correcting any problems.

However to avoid some possible problems I did decide that only the physical attacks will be displayed in the Stats panel. If an elemental attack such as Firewall needs to be seen then the user can simply go to the Skills panel an view the values there. It would be a duplication of effort to have them displayed in the Skills panel, besides which would also require quite a few more exceptions as many sources of damage wouldn't be counted then. The only exception to this is Blessed Hammer. Seeing as Hammerdins are a very popular build and Blessed Hammer is given a bonus by Concentration the only way to display the values correctly was in the Stats panel, even though this is a caster skill.

Overall I think it is coming along quite nicely. I'm sure a minor bug or two will pop up and need fixing, although I think I caught most of them already. The GUI itself should be set, so this leaves me with only needing to take into account Set item bonuses to be done with the current panels.

Wednesday, January 7, 2009

Java: CharSi Update #15

Not done by any stretch of the imagination, but enough was completed to warrant an update. First thing on the agenda was to alter the GUI component so that it could better display the needed information. First off I removed the damage/AR to demons and undead components. While I still intend to provide that information, I think I'll do it as a ToolTip rather than in the GUI component itself, since that information is a tad less important.

In its place I've included damage and attack rating fields for the off-hand weapon, assassin kicking, paladin smiting and throwing of the primary weapon. So now that they are present, I have to determine how to populate data into each of these components. First step was to create a int array to hold the attack rating information. Then I needed the equation that determines what the true attack rating should be. This I found on the Amazon Basin when I was browsing it as the DIII forums were down for "maintenance". I created a method that would combine all of the mods associated with attack rating into one equation and then populate the attack rating int array appropriately. Adding the necessary JTextField.setText calls for the attack rating fields in the overall SetAll method means whenever anything is changed, these values will be updated.

Doing the same for the damage fields fell along the same lines, but there were quite a few more pieces to work together. First off the necessary equations were found in the Strategy Compendium. All of the needed mods were already summed up under other methods in the Stats class, so I simply plugged them into the equation inside of a new method and called this method when the SetAll method is run. Granted there were a few pieces that needed extra attention before this could be considered a success.

First I had to decide how to handle the StatsBonus variable. Each of the item descriptions contains the base item as its second line, all except the white items that is. So once I added this descriptor to all the white item text files I was able to save this information into its own variable. This variable was then compared to an array of Strings to determine if the chosen item falls into any of the special categories.

String[] hammers = {WARHAM, MAUL, GREATMAUL, BATHAM, WARCLUB, MARTEL, LEGMALL, OGREMAUL, THUMAUL};

for(int i = 0; i <>
if(hammers[i].compareTo(base) == 0){
hammer = true;
break;
}
}

If there is a match then a boolean variable is set to true, for use later.

if(hammer)
statBonus = (float)(1.10*(baseStats[0] + stats[0] + userStats[0]))/100;

With that variable determined I now only have the Modifier variable to deal with. This one is modified depending on what type of skill is being used. As a result I'm leaving this one until later as I have quite a few other pieces that need to be connected between the Skills class and Stats class that I'd like to handle all at once. However the damage panel does display a Normal attack without difficulties now.

Last but not least I did create the necessary methods to sum the +skill mods from the equipment worn by the virtual character. This information is then transferred over to the appropriate Skills sub class so that now the Skill Calculator can display values greater than level 20. It now accurately shows what level the character's skills will be at for the equipment worn.

However I'm not done yet. There is quite a bit of information that still needs to be attached between the Skills, Stats and Equipment classes. For example the auras used by the Paladin aren't considered for defense, attack speed, resistance or anything similar in the Stats panel. Correspondingly the mods given by equipment for +elemental damage aren't considered in the Skills panel information. So the next step is to finish attaching all of the different pieces behind the scenes until I have accounted for everything possible in all three JPanels.

Wednesday, December 31, 2008

Java: CharSi Update #14

Any mods provided by equipment is now properly displayed in the Stats panel, minus damage and attack rating calculations. The first step was to add a method for each category of mod that would sum the data from each of the equipment subpanels into a single value. I split up the mods into small groups to make things a bit easier, such as all boolean values in one method, all mods of note in another and so forth. During the calculations the mods that are based on character level had to be taken into account as well. This was done with a simple addition to the currently summed value.

((int)charLevelMods[15])*(levelCBox.getSelectedIndex()+1)

Once the summing was completed it was a simple matter of creating another method to populate all of the JTextFields and JTextAreas. To do this a couple of different methods were created to populate patches of these components, then a single method is made that calls all of the methods together, both the summing and populating ones. I determined it was easier just to sum everything each time a value is changed rather than only the ones affected, to ensure that I didn't miss something along the way.

The miscMods panel had a few different wrinkles beyond the others. Specifically the text files that contain the random mod information for each piece of equipment needed to be dealt with for when the program is closed or the item added/removed. Adding the information wasn't too difficult, however a new method needed to be created to erase all of the file's content when the item was removed or the program closed. This new method basically overwrote the current file with a blank one and is called every time just before an item is added or whenever one is removed, as well as when the miscMod Panel is initialized for cases when the program is closed with equipment still assigned to the virtual character.

Once that was done it was a simple matter of taking every mod that isn't deal with in any of the other panels and appending that mod's information to a StringBuffer that is then displayed in the miscMod JTextArea.

Now with all of the other Panels completed it is time to work on the Damage panel. This one will take a little research first as I need to get the correct damage equation to ensure I don't repeat the mistakes of the current LCS. That and I know I need to alter the current component's GUI quite a bit to take into account kick, smite, one-handed and throw damage as well as active auras for Paladins. Once that is completed there are only a few cleanup items to take care of before the current iteration of the program is complete. Then I'll have to decide what the next step will be.

Thursday, December 18, 2008

Java: CharSi Update #13

Progress is moving along nicely. I have now updated each of the equipment class files to incorporate the changes made to the Armor class file. Specifically each now can be used to search for an item given a set of parameters and then equip that item to the virtual character.


In updating all of these files I did encounter several mods that I had neglected to take into account earlier. Mods like Assassin kick damage and Fire absorb based on character level didn't appear in the armor items. As a result I had to update certain integer arrays in each of the class files as well as any methods that worked with these arrays each time a new mod was "discovered". Along with that I did find several of the item text files had typos that caused an exception to be generated. Those had to be corrected as well.Once that was done I was then able to completely equip a character with white, set or unique items and view those stats that I have hooked up in the Stats panel.


The Mods of Note panel is mostly attached to the equipment panels, as is the Stat Points and Properties panels. They are missing the additions for based on character mods but beyond that they should be accurate. The other panels need work however. So that's my next step, to attach all of the data I've collected from the equipment panels and display that properly in the Stats panel.

Tuesday, December 9, 2008

Java: CharSi Update #12

Before I could get the Equip and Remove JButtons working in the Armor panel I had to first correct some oversights and problems in the Stats class. Specifically not all of the mods were being summed correctly, or at all, so a few methods needed to be generated. I made a different method for each array or subset of variables so that each could be called separately. Currently I don't have a need to call them separately, but one could arise in the future so I'm planning ahead. Along with this a super method was needed that would call all of the summing methods at once, SetAll.

Now that the Stats panel was all set it was time to finish the Equip JButton listener. First a check is done to ensure that there isn't already a piece of Armor equipped on the virtual character. This is done with an array stored in the Equipment class, and therefore available to all classes that govern the tabbedpanes. After that check is complete, and passes, then the stats from the selected item are stored using the massive If-Else statement created earlier. Once completed the SetAll method is called to save this information into the Stat class variables and the Armor slot is considered "filled".

StoreItemStats();
Equipment.equipListModel.addElement(itemName);
Stats.SetAll();
Equipment.equipYes[1] = 1; //1 = filled, 0 = empty

This places the item name as an element in the equipped JList component. I decided that any elements in this list, while clickable, won't display the items properties in the JTextArea. That would have required saving the data into a text file to be displayed on command, and at this point that isn't a critical element for the application to function.

Now that an item can be equipped, it needs to be removed as well. Doing so needed another method, ZeroStatArrays, that would empty the contents of all the stat arrays before calling the SetAll method to sum the stats from all equipment pieces. Along with this the element in question would need to be removed from the equipped JList. However, before this could be done a check needs to be made to ensure that the user is in the correct JPanel for the equipment being removed. I decided that needed to be a requirement to remove the item piece.

Now that those pieces were in place, I had to run through the entire list of available armor pieces and both equip and remove each one. This was a check to ensure that the right values are being stored by the StoreItemStats method. As it turned out there were several bugs in that part of the code. A few times the wrong slot of the array was updated, while others there was a conflict between mods I didn't know existed, such as between "to mana" and "Damage taken goes to mana". Both contain the phrase "to mana" and therefore the method was attempting to apply both statements to the value given.

As a last piece I removed the Perfect and Reroll components. These were now redundant as the user is choosing the desired values whenever the item is equipped. The next step will be to transfer this code to the Belt class file and then test all those items to ensure the StoreItemStats code is still valid. I'm sure there are some mods not handled by the armor files that may still have small difficulties. Each piece of defensive equipment will be handled in turn until they are all completed.

Friday, December 5, 2008

Java: CharSi Update #11

Next step in this program was to transfer the flag code to the other Class files so that I can easily search on any item set and display that list in the item JList. Once that was done I did make a decision about the Weapon class file. Leaving the application the way it was would have been burdensome to find a particular item. So I bit the bullet and created massive if-else statements to incorporate the fifteen different weapon types in the code. Along with that I had to create a new GUI piece to allow the choice of which items to search under, leaving them all unselected to start with.

Once that was done it was time to start working on the true workhorse of this application, the ability to take the information from the text file and save it in the application to be added to the stat fields when needed. I elected to do this with a series of arrays and a single text file. Before I could do this however I had to alter the way some mods were written so that I could store them correctly. I made sure all variable ranges were encompasses by parentheses () and these were the only values that had such characters in their particular line. Same goes for the set items, {} brackets were used to signify those items so they could be dealt with differently.

This ended up being a much larger project than I had originally anticipated, not that I though this piece would be small mind you. The main method for this process, StoreItemStats, was designed to take the text and deal with it one line at a time. Each line was compared to the possible mod text and if it matched then the appropriate array field was updated with the value provided in the text. Sounds simple? Well not quite that easy.

First there are a ton of mods to deal with so a couple hundred String variables had to be created for the comparison. Then several arrays were created, each for a different type of mod so they could be identified easier, such as modsOfNote and stats. Once a mod was identified then it had to be determined if the mod was variable or not.

else if(currentString.contains(ML)){
if(currentString.contains(RANGE)){
modsOfNote[7] = DetermineRangeValue(currentString, "Mana stolen per hit");
}else
modsOfNote[7] = Integer.parseInt(currentString.substring(0,currentString.indexOf("%")));
}

The above is a call to see if the mod Mana Leech is present. If the line of text contains a "(" character then it is a range then the method DetermineRangeValue is called, as the program needs to determine what the exact value of this mod should be. That is where the user comes into play. The user will be provided a dialogue box to choose the desired value, then that value is stored in the appropriate array slot. This seemed a much easier route to go than to have the Reroll and Perfect JButton/JCheckBox components do this in a more random fashion. This way the user can simply create whatever version of the item they want, from low end to perfect and anywhere in between. It means I'll have to remove those components in the near future and unclutter the GUI a bit.

The coding itself wasn't so difficult, it was the amount of data I needed to sort through that gave me a headache (and a stiff back). The giant If-Else statement ended up being 1820 lines of code, which basically quadrupled the size of the Class file with one method. Some of the If-Else statements had to be nested together as their text was too similar to distinguish easily. For example there are several mods that reference "fire damage" or simply "damage", so to ensure the right value got into the right array slot those mods were nested together.


Now that this piece of the code is written the application works pretty much like a giant item database. Easy to search for a particular item but not much else beyond that. However now that I have all of the mod information stored into appropriate arrays (for the Armor class at least), the rest should go a bit quicker. I plan on working only on the Armor class for now so that I can get that one pretty much completed before transferring all of that code to the other defensive equipment classes. So along that train of thought, my next step will be to get the JList for equipped items working and ensure that I can't accidentally equip more than one item at a time. That and I need to get the Remove Item JButton working as well as remove the components that aren't necessary anymore.

Friday, November 14, 2008

Java: CharSi Update #10

Now that the Runeword Wizard portion of the program is completed I can turn my attention back to the main goal of this application, namely the ability to virtually equip a character with items and see those stats. To do this I need a list of available pieces of equipment that can be displayed in the item JList.

Similar to the way runewords are handled with the Runeword Wizard I decided upon text files, one for each possible item. Granted an access database or something similar would be a bit more efficient in the long run, but since I have no idea how to hook one up the application text files remain my only alternative beyond hard coding each item's stats into the class files.

Before these files could be created I needed to generate a list of all possible mods that can spawn on items. This is needed for two reasons; first to be able to consistently word a mod in the text files and secondly to lay the basis for the array of arrays necessary to compare possible mods to mods actually present and update the correct variables within the program. The second part is far into the future so I'm not worrying about that yet, however wording the mods right is something I must worry about. If I misspell a mod then when the text file is searched for that mod it won't be found due to a typo, and as a result the information displayed will be inaccurate. As a result I must be very careful when creating the text files, such as the one seen below.

Vampire Gaze
Grim Helm
Required level: 41
Required strength: 58
Defense: 252
Durability: 40
+100% Enhanced defense
Adds 6-22 cold damage over 4 seconds
15% Slower stamina drain
6-8% Life stolen per hit
6-8% Mana stolen per hit
Damage reduced by 15-20%
Magic damage reduced by 10-15

The files themselves are organized in subfolders that separate set/unique/white(normal) items based on whether they are normal, exceptional or elite. This makes displaying the list of item matches much easier in the JList component if all the normal set items are stored separate from the unique items.

Once the files were created, the code then needed to be generated that could search them and display the correct items dependent on which checkboxes the user had selected. A pair of methods were created for this purpose, one being the workhorse and the other calling the first dependent on what folder location was being utilized. A basic setup of the first method is below.

if(normalFlag){
if(whiteFlag){
location = location.concat("Normal/White/");
AddToList(location);
location = location.substring(0,11); //revert string back to original form
}
if(setFlag){
location = location.concat("Normal/Set/");
AddToList(location);
location = location.substring(0,11); //revert string back to original form
}
if(uniqueFlag){
location = location.concat("Normal/Unique/");
AddToList(location);
location = location.substring(0,11); //revert string back to original form
}
}

The folder location is passed to the workhorse method (AddToList) and all files in that location are dumped into an array of Strings. That list of Strings is then shortened to remove the .txt portion of the filename and then added to the DefaultListModel governing the item JList component. This allows the items to appear in the item JList component. Once in this component the JList Listener is then added that once an item is selected its corresponding text file is displayed in the JTextArea. The layout of the listener is the same as the method shown above.

The next step is to then transfer this same code to the class files for the other equipment types. I do realize that by grouping items in such broad terms the generated lists for the weapon types will be quite extensive. I've considered changing that class file into a JTabbedPane, one for each weapon type, except that there are fifteen different weapon types and that would lead to quite a bit of duplicate code. Another alternative is to add another set of checkboxes, one for each weapon type, that the user can select which weapon types to display. This would make the code quite a bit longer and require a new component added to the GUI to display these choices. I haven't decided which way I wish to go, or if I simply want to leave it as is and have a long list of items displayed. As a result I'm going to skip the weapon class update for now and concentrate on the others.

Wednesday, October 1, 2008

Java: CharSi Update #9

It turns out an array of arrays was the best way to contain all of the information needed for the Runeword Wizard. This allowed me to use For and While loops for any comparison purposes as I had an array for all of the selected options and then compared each slot to its corresponding slots in the array of arrays. Somewhat of a brute force method but I'm satisfied with the results.

To start off I needed to create the main variable of this program, the array of Strings that would hold all of my selection choices.

String[] selectionArray = {"", "", "1", "0", "2", "1", "0", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"};

There are 58 slots to this array, one for each rune, base item and search modifier. A value of "1" equals true while a "0" equals false. All runes are initially selected while the base items are not. As components are selected their corresponding Listeners will alter the necessary value in this array. Along with the selectionArray, a separate array was created for each possible runeword, of which there are eighty-three. To that end there were quite a few arrays that looked similiar to this:

String[] heartOfTheOak = {"heartoftheoak.txt", "Heart of the Oak", "1", "0", "4", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "1", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "1"};

After creation each array is then added to a slot in main runeword array to create the needed array of arrays. This becomes key when doing the actual comparison between what is needed and the runewords available. The workhorse of this program is a method named CompareRunewordCriteria(). This method is called when the Display Jbutton is pressed. To start it sets a boolean variable to false, assuming the runeword won't fit the criteria given. Then it compares the base items needed with those selected, if there is a match then the variable is set to true, if there isn't a match then we move on to the next runeword. Then runes available are compared to those needed, as well as if the runeword has the right number of slots, contains an aura and all the other selection criteria are compared. If after all that the boolean variable is set to true, then the runeword name is added to the DefaultListModel so that it is displayed as an option in the JList component.

That was the hard part. After that it was simply hooking up the JList component Listener to display the right text file when an option in the JList is selected. The code for displaying the text was borrowed from the AMAS Rune panel, as was the text files containing the runeword information.


After everything was in place I did run some comparisons between my program and the online runeword calculator to ensure my results were accurate. A few changes had to be made, I apparently didn't consider all weapon types when melee weapons are concerned. Also Mauls were removed as a selection since those are incoporated into the Hammer option and Daggers were put in place instead. When originally thinking about daggers I assumed one socket was all they could have, which turned out to be incorrect. But a few quick variable name changes and daggers are now an available option.

This Runeword Wizard now replaces the runeword list from the AMAS program as this one is much more robust. I can search on specific runes and it provides a much larger pool of available base items beyond the four originally available (shield, helm, armor, weapon). Gradually I'll be phasing AMAS out of use, but I don't see doing so for quite a while as I want to finish the character simulator portion of CharSi before adding any other reference tools to the program.

Wednesday, September 10, 2008

Java: Character Simulator Update #8

I had a decision to make as to whether to create a Runeword Wizard or finish the character simulator part of CharSi. I know that were I to start the character part I wouldn't be finished for quite a while. Since I already have a decent idea how to make the runeword wizard I decided that was the application I would work on. It is still going to be part of the overall CharSi program, but more of an add-on than an integral part since it won't interact with any other tabs.


I have a general idea as to what type of information was needed to perform the runeword query properly. After I had my list created I reviewed an online runeword calculator to ensure I didn't miss anything important. From that version I added the Paladin only aura runeword option, but that was all. The online version has some modifiers I can't see myself using, and since this is primarily for my personal use I'm not adding them in.

So then it was off to create the look-and-feel portion of the program. I created a separate JPanel for each section to be combined at the end into a single JPanel. I borrowed code from a few earlier programs to speed up the process, no need to recreate the wheel all over again. Specifically I am using a JList and JTextArea panel from the equipment tabs of CharSi. Virtually a cut-and-paste operation with only a few variable names changed. Also utilizing the Rune JPanel from the AMAS program, with a few modifications. The columns were changed from three to two and I needed to use a different constructor for the JCheckBoxes.

JCheckBoxMenuItem (String text, Icon icon, boolean b)

Actually it's a different component all together to be honest. Also needed to set their value upon initialization as I wanted all of the rune options to be initially checked. As a result had to borrow all of the rune images as well to include with the JPanel.

As it turned out the only pieces that had to be created from scratch were the query modifiers. Once that was all done the separate JPanels were grouped together using GroupLayout to display correctly. Now I need to look into how I want to handle the queries, and how to store the runeword information so that the information displayed is accurate. I'm considering an array of arrays so that For and While loops can be used rather than a separate instance for each runeword.

Friday, September 5, 2008

Java: Character Simulator Update #7

Three pieces were planned on being completed for the next update. Specifically:

1. Update the skill text files to hold data for skill values up to 55
2. Fix bug where JComboBox ToolTip is not updated when a synergies skill is changed
3. Fix bug where when switch between characters the SkillPanel panel is repopulated even when the application is set to standalone mode, where only the skill calculator Tabbedpane is visible

The first piece required the most amount of time and was mind-numbingly boring. It basically consisted of me updating text files with the information of each skill level. Some of the skills were fairly easy to do as the skill values progressed at a steady pace. In this regards the Barbarian class is my favorite. However other skills, such as Plague Javelin for the Amazon, increased exponentially and therefore required far more time to update. Thankfully that is done and hopefully all of the data was entered correctly, as finding a mistake will be rather difficult. I will spot check a few skills and compare my results to that of another skill calculator, but I will not be checking every single skill and synergy.

Fixing the ToolTip on the JComboBox to update when synergies are updated was fairly simple. I had Listeners set to update the calculations and tooltips for each category, such as Necromancer Curses. However some synergies are outside of the skill's category, so I expanded the update to include all tooltips rather than just the category's ten. To accomplish this I created a new method, RecalculateSkills, that was called at the end of each JPanel listener.

Lastly I wanted to fix the bug where when the Skill Calculator is not set to act in standalone mode the SkillPanel containing the JComboBoxes for selecting plus skill values is not removed correctly. When the standalone mode is turned off the initial SkillPanel is removed, but when a different character class is chosen then their corresponding SkillPanel appears. To bypass this a single line of code was required.

if (CharSi.standaloneMenuItem.getState() == true)

This is called just before the SkillPanel method is called, so that if the Skill Calculator is to act in standalone mode then the method is utilized, otherwise it is not.

Originally I had thought that after making these changes I would be done with the Skill Calculator and could move on to the next piece of the application. However upon further consideration I've decided to add two additional pieces.

1. Create Clear All skill selections button
2. Synergy information in skill description tooltips

Creating the Clear All button was the easy part. Simply add the JButton component at the end of the selectionPanel. A few JLabels full of spaces were added to ensure the original components stayed where they were and the JButton was placed in the upper right corner of the application window. Getting the listener to act properly was a bit tougher.

A difference instance for each character type was created inside of the listener. Within each instance a few things had to be altered. First the arrays that help plus skill values were zeroed out using For loops. Then the JComboBoxes had to be reset to index zero. It was this step that caused quite a few problems. When a JComboBox that has a requirement is set to zero this caused the JOptionPane error message to appear, regardless of which order the JComboBoxes were reset. In the end I had to create a new variable that would be a specific value inside of the Skills class Button listener. Then the character JPanel listeners were ignored if the new variable was this specific value.

if (Skills.clearing == 1)
return;

'Clearing' being the variable in question and the above code is executed first in each listener. This ensured the requirement error doesn't appear multiple times when the Clear All button was pressed.

As for including the Synergy information into the tiptool of the JLabel, no problem. All of the information was already in the description of the corresponding calculator method. It simply had to be copied over.

This leaves the Skill Calculator portion of the application basically complete. Some minor word changes or correction of typos may occur but it is fully functional and ready to use. Now I just need to create an icon for it and generate the necessary executable file.

Monday, August 4, 2008

Java: Character Simulator Update #6

Apparently I got a bit carried away with the next round of updates to this application. I decided that the skill calculator should have the option of being a standalone application that doesn't require the user to enter in what equipment they are using. As a result I needed to add another JPanel to the southern portion of the BorderLayout manager. This new JPanel, aptly named plusSkillPanel, is populated with JLabels and JComboBoxes depending on which character was selected.

Since the user will be able to select manually which types of +skill mods are available I needed to be able to keep track of what has been selected. This was done through a new int array variable and a listener that altered the array depending on which JComboBox was changed.

Of course if the skill calculator could be changed to be a standalone program then the equipment and final stats tabbedpanes would need to become hidden at that time. Otherwise the array variable holding the +skill mod values could be altered in both ways and that would lead to incorrect information being displayed. This was done by adding a new menu item, specifically a JCheckBoxMenuItem. When selected the tabbedpanes for final stats and equipment are removed from the program and the plusSkillPanel JPanel is added to the bottom of the application. When it is unchecked all of these changes are reversed.

if(event.getActionCommand().compareTo(STAND) == 0){ //standalone menuitem pressed
if (standaloneMenuItem.getState() == false){
tabbedPane.insertTab("Final Stats", null, new Stats(), null, 0);
Stats.SetCharType();

tabbedPane.insertTab("Equipment", null, new Equipment(), null, 1);

Skills.plusSkillPanel.removeAll();

Once that was completed it was time to work on the calculations and displays of the skills. There are seven characters with thirty skills apiece, that's 210 skills overall and each has it's own method calculating the value dependent on what level is selected for the skill. When calculating these skill values the synergies had to be taken into account as well, so the calculates are a bit lengthy, but not too complex.

First the String variable that holds the description of the skill's value is set to a null string just in case any previous data had been present. After that the method checks if the skill itself has either any hard points assigned or is gaining any points from equipment (which of course doesn't work in standalone mode). If points are in the skill then the String variable is altered to continue all of the values of the skill in question, calculated with synergies being taken into account as well as +skill mods. Then the String variable is set as the ToolTip for the JComboBox of the skill.

Along with this ToolTip a second tip was created that resides on the JLabel of each skill. Specifically this ToolTip is assigned in the constructor and is a text description of what the skill does exactly.

Each of these changes had to be made for all 210 skills, and after a while became very tedious. However it is all done and the skill calculator does work as intended, with a few updates necessary. Specifically:

1. Update the skill text files to hold data for skill values up to 55
2. Fix bug where JComboBox ToolTip is not updated when a synergies skill is changed
3. Fix bug where when switch between characters the SkillPanel panel is repopulated even when the application is set to standalone mode, where only the skill calculator Tabbedpane is visible

Friday, May 30, 2008

Java: DII Character Simulator Update #5

This project got put on hold due to lack of time once Gorny sucked me into playing the online game Travian with him and bunch of other people from the Diabloii boards. Thankfully that game is over and I can get back into working on this program again, however it took a while to reacquaint myself to the methods, variables and structure of the current code.

I had planned on finishing up the Skill calculator tab so that is where I started. It turns out there aren't any easy equations for how the skill damage/stats are governed, which makes my job a bit harder, and a little tedious. Instead I had to create a separate text file for each skill and list the variable stats for each level in the file.


This was the tedious part, as there are seven classes with thirty skills each and I went up to level twenty for each skill. So say around forty-two hundred columns of data needed to be generated. Thankfully there is an online version of the skill calculator that I use to view the needed information and transpose it into text format. Granted it's an "illegal" version according to Dii.net standards, but the information is accurate and I like the way it's displayed.

While that was the tedious, non-coding part there was also some real coding that went along with the text files. Specifically I needed a way to gather the information from the files and store it in the program for use in calculating skill stats per level when I make my own equations. In order to do this each skill needed it's own float array, one row for each variable stat.

float[] magicArrow = {0, 0, 0, 0};
float[] guidedArrow = {0, 0};
float[] immolationArrow = {0, 0, 0, 0, 0, 0, 0};


And so forth. The trick is recalling which row corresponds to which variable stat, and for this I had to create a set of cliff notes for each character class. Whether or not those files will be incorporated into the final product is up in the air at this point.

Now that there is somewhere to store the information a pair of methods were created to do the actual storing procedure.

public void FillSkillArray(String file, String location, int number, float array[])

This is the workhorse method and will open the associated text file, find the correct column depending on what value the skill has been given (int number) and then save the information into the corresponding float array. Every time a skill value is changed the entire set of skill stat arrays are repopulated. Since this is only populating thirty arrays it isn't time nor resource intensive. The second method simply calls FillSkillArray for each of the thirty skills at all once.

Now with the skill information being saved successfully we need a way to display this information. I see this happening in two parts. The first part will be a method that generates the correct stat amounts depending on synergies and such; one method for each skill. Then to actually display this information I was planning on using a Tip Tool on the label of each skill. While I haven't researched this yet I'm hoping simply hovering the mouse over the skill's label will display the bonuses given or damage done as calculated by the associated method.

I will need to add a few variables for use in the calculation portion that will take into account +skill mods from equipment. For now those will all have a value of zero but it is better to incorporate these variables into the program early than try to do so later on.