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 18, 2009

Diablo II: The Peasants Tournament

The Peasants Tournament by Morathi was an interesting concept for a tournament. The basic premise is that each character is a peasant, and therefore restricted from having access to certain items and skills. Specifically no spells above level 18 are allowed to be used, although they may have points added for synergy purposes. Also defensive equipment was restricted to those without metal and all equipment restricted to only normal/rare/magical, no set or unique items allowed.

I entered with Calypso, a Firewall and Glacial Spike sorceress. Her progress was slow but steady. In the beginning she simply went melee and whacked all of the monsters she encountered. Later, as points were invested in Ice Blast that skill was used as the main monster killer and as a support feature for the mercenary. Being mana intense I found the need to return to town early and often, which was quite annoying. Things didn't get any easier once Firewall was available, as that skill is fairly mana intensive as well. However on the flip side Firewall was able to kill off any monster fairly quickly so progress sped up a bit.

General game play saw Calypso freezing her enemies with Glacial Spike and then dropping a Firewall on them while a GS or two were thrown in to keep the monsters in place. For those monsters that were highly fire immune then GS and Static Field were used in concert, with the mercenary cleaning up the mess afterwards. While this worked well in Normal and the beginning of Nightmare it definitely slowed down a bit as NM progressed.

Alas Calypso met her end in the sewers of Act III due to player error. Instead of dropping a Firewall on Icewing's pack but instead Teleported into their midst instead. With no FHR or FCR Calypso was stun locked and the mercenary was unable to scare the pack away due to having a very weak weapon.

Overall it was fun, but I was beginning to doubt that Glacial Spike with only a single synergy would be viable in Hell to deal with all of the fire immune monsters. I tend to doubt it as it had major issues dealing with monsters in Act II NM, much less the massive HP increase they'll all get in the later part of NM and Hell. I don't think I'll rejoin this tournament, I have so many softcore characters I want to build and a lot of new toys from the recent MFO and Pindlethon to use on them. As a result I'm going to do that for a while instead of any public tournaments.

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.