Sunday, July 02, 2006

Just a thought

Maybe put an image box for pictures for the different items.

ClassEdit Finished

I finally have a saveable CharClass Editor. Users can drag and drop skills, feats, and special abilities into their respective ListViews. These ListViews are custom controls by Glacial Components(ListView v1.3) available here . These allow embedded controls. Currently I am using this functionality to embed NumericUpDowns in the skills view to edit any bonuses. I am considering not haveing this option and simplying allowing the user to choose the Class's class skills.

In addition to this, I have built generic methods for saving and loading the resource Xml files.
They are here:
public static void SaveToFile ( T obj, string fName )
{
try
{
TextWriter w = new StreamWriter(fName);
XmlSerializer s = new XmlSerializer(typeof(T));
s.Serialize(w, obj);
w.Close();
}
catch ( Exception ex )
{
MessageBox.Show("Problem saving file: " + fName + " " + ex.Message);
}
}

public static void LoadFromFile ( T obj, string fName )
{
StreamReader str = null;
try
{
str = new StreamReader(fName);
XmlSerializer s = new XmlSerializer(typeof(T));
obj = (T)s.Deserialize(str);
str.Close();
}
catch ( Exception ex )
{
MessageBox.Show("Problem loading file: " + fName + " " + ex.Message);
}
}

These methods will serialize or deserialize any serializable object. In order to be serializeable, the data you want must be a public property, and you have to have a parameterless constructor. There are probably more restrictions, but I don't know them.

In order to use drag and drop, three event handlers are needed: ItemDrag, DragEnter, and DragDrop. For some controls the MouseDown event may need to be used instead of ItemDrag. The ItemDrag event is placed in the source control, and the DragEnter and DragDrop in the target. DragEnter checks to make sure the dragged object is the right type, and then changes the effect to Copy. The DragDrop is where the control creates a new object and places it in.

When a user drags one of these objects onto the Class, a value copy is made. This means that the new item is referenced to a separate piece of memory. Changes can be made independently to the object in the main list.

The rest of today, I will probably work on the RaceEdit form.

Friday, June 30, 2006

I figured it out!!!

I figured out a mathematical formula for determining the number of bonus spells per day a character gets, given their ability modifier and the spell level. Here is the code in C# but the math works anywhere
public static int CalculateBonusSpells ( int mod, int spellLvl )
public static int CalculateBonusSpells ( int mod, int spellLvl )
{
int newMod = mod - ( spellLvl - 1 );
if ( newMod > 0 )
{
int bonus;
if ( newMod % 4 != 0 )
{bonus = newMod / 4 + 1;}
else { bonus = newMod / 4;}
return bonus;
}
else {return 0; }
}

First, the modifier is adjusted by the spell level(-1 to get it right) then if the result of the division of the modifier and 4 returns a remainder, then the bonus is the result of the integer division(which drops remainders) plus 1. If the division is clean then that is the result.


I also found the (immensely simpler) formula for the bonus psionic powers per day given ability modifier and class level:

public static int CalculateBonusPowers ( int mod, int classLvl )
{
return ( mod / 2 ) * classLvl;
}

it is simply the modifier divided by 2 and then that multiplied by the class level.

Thursday, June 29, 2006

Progress So Far

I guess I have to stop working for the day. So, I want to log what has been accomplisshed and what I can see still needs doing.

First off, I used Weifen Luo's Dockable Windows available at http://sourceforge.net/projects/dockpanelsuite

This allows me to have those nifty Dockable windows. Here's how to use them(or at least how I did it) First you need to import the .dll as a resource, then add a DockPanel to the window that will act as the container(the DockPanel should fill the window - Dock.Fill) Then just have all your docking windows inherit from the DockContent class instead of the standard Windows.Forms.Form. To load the windows with docking behavior, call their Show() method, with the DockPanel as the first param. then you have a couple of options, you cans set the DockState as the second paramater(if you want it as a document or on the left or right) If, however, you want it to float and the default float size is too small, use a Rectangle as the second param to ensure the size is what you want.(a call to ClientSize on the window doesn't seem to work)

So far, I have definitions for the following: Adventure, Armor, Attack, Character, CharacterClass, Feat, Item, Power, Race, Saga, Setting, Skill, SpecialABility, Speed, Spell, STBonus, Weapon, and a group of helper classes and enums. Some of these files need to be cleaned up and comments and documentation need to be standardized.

So the basic design pattern. There is a main window, that serves as a central point for all the others, The main window holds references to all the opened windows(they are not created dynamically, so, only one instance of each) these are given public properties and all windows take a reference to the main window as a param in their constructor. this way all windows have access to all the other windows' public properties and methods. I think there must be a better way to do this, but I haven't thought of it yet.

I'm tired of writing now so I will try to write some more later.

Beginning... Again

Well, for those of you who know me(if you don't listen well), I am terrible about finishing a project.
This blog is an attempt to help me remember what on earth I was doing when I pick this project up again. We'll see.

So, what project are we working on? Why, Njorl's Saga Manager of course. This is hopefully going to be a complete campaign manager solution for DMs using the d20 sytem. This is about the 50th time I have restarted this project, but hopefully, next time I will not have to start from scratch, because I will try to post whenever I work on the project so I can keep myself up on what is going on. If any of this turns out to be interesting to anyone else, cool.


Ken