Friday, May 23, 2014

Hoardomatic Code: Doing Something With It

Clever readers will have realized that everything I've posted up to this point doesn't actually do anything. There's a bundle of classes and data representing everything from a pile of treasure down to details of decor, but what to do with it? Ultimately, all one needs to randomly generate a hoard is something like the code below, which generates a hoard of random items worth $2,000. For a bigger or smaller hoard, just change the value of hoard_val.

package hoardomatic;

public class goMonkeygo {
    public static void main(String[] args) {
        Double hoard_val = 2000.0;
        Hoard avarice = new Hoard(hoard_val);
        System.out.println(avarice.hoardReport() );
    }
}





Thursday, May 22, 2014

Hoardomatic Code: Sample Data


And finally, data. Without the XML files, this is all, in the words of Han Solo, a really short trip. These (redundant, poorly structured) batches of XML are representative of the nature and structure of data required. Here's what they contain.

BulkGoods.xml: Detailed breakdowns of additional properties of bulk goods, notably the unit of measurement and containment type. These include W for wet goods like wines and pickles which must be stored in waterproof containers, D for dry goods like spices which can go in boxes and bags, and N for things like hides and raw fibers which are measured by bulk quantities but don't require containment.
Containers.xml: Detailed breakdowns of additional properties of containers, notably containment type and storage capacity.
Curses.xml: Curses are like lightweight enchantments or embellishments, with a name and a CF, which Items use to modify the cost of enchantments.
Embellishments.xml: Properties of mundane embellishments, including name, weight modifier, CF, and embellishment codes indicating properties of items with which they can be matched. Some have motif code, indicating whether or not decorative motifs are suitable to the embellishment.
Enchantments.xml: Name, cost, and item type for enchantments. Also includes energy reserve value, which isn't actually used in my code, 'cause all of the XML files are automated extracts from the database tables I maintain for my own use.
Gems.xml: Name and value modifier for gems.
Items.xml: As the Item class is key to the code, Items.xml is the most important data file. Lists items with name, base cost, base weight, and one or more attributes indicating which embellishments and enchantments are suitable for use with it.
Motifs.xml: A fairly simple list of decorative motifs.
SupernaturalEmbellishments.xml: List of supernatural embellishments which is called on for some enchanted items. Just a name and CF.



BulkGoods.xml

<?xml version="1.0" encoding="UTF-8"?>
<bulkgoods>

<item name="7-UP">
   <name>7-UP</name>
   <UnitPrice>5</UnitPrice>
   <Wt>8</Wt>
   <Unit>gallon</Unit>
   <ContainmentType>W</ContainmentType>
</item>

<item name="Emeril's Essence">
   <name>Emeril's Essence</name>
   <UnitPrice>150</UnitPrice>
   <Wt>0.0625</Wt>
   <Unit>oz.</Unit>
   <ContainmentType>D</ContainmentType>
</item>

<item name="Chanel Number 5">
   <name>Chanel Number 5</name>
   <UnitPrice>35</UnitPrice>
   <Wt>0.0625</Wt>
   <Unit>oz.</Unit>
   <ContainmentType>W</ContainmentType>
</item>

<item name="MSG">
   <name>MSG</name>
   <UnitPrice>150</UnitPrice>
   <Wt>0.0625</Wt>
   <Unit>oz.</Unit>
   <ContainmentType>D</ContainmentType>
</item>

<item name="Candle, Tea Light">
   <name>Candle, Tea Light</name>
   <UnitPrice>5</UnitPrice>
   <Wt>1</Wt>
   <Unit>Each</Unit>
   <ContainmentType>D</ContainmentType>
</item>

<item name="Candle, Birthday">
   <name>Candle, Birthday</name>
   <UnitPrice>0.5</UnitPrice>
   <Wt>1</Wt>
   <Unit>Each</Unit>
   <ContainmentType>D</ContainmentType>
</item>

<item name="Mrs. Dash">
   <name>Mrs. Dash</name>
   <UnitPrice>150</UnitPrice>
   <Wt>0.0625</Wt>
   <Unit>oz.</Unit>
   <ContainmentType>D</ContainmentType>
</item>

<item name="Cloth, Lycra">
   <name>Cloth, Lycra</name>
   <UnitPrice>5</UnitPrice>
   <Wt>1.5</Wt>
   <Unit>Bale</Unit>
   <ContainmentType>N</ContainmentType>
</item>

<item name="Cloth, Fuzzy Fleece">
   <name>Cloth, Fuzzy Fleece</name>
   <UnitPrice>565</UnitPrice>
   <Wt>1</Wt>
   <Unit>Bale</Unit>
   <ContainmentType>N</ContainmentType>
</item>

<item name="Whiteout">
   <name>Whiteout</name>
   <UnitPrice>65</UnitPrice>
   <Wt>0.5</Wt>
   <Unit>Each</Unit>
   <ContainmentType>W</ContainmentType>
</item>

<item name="Root beer">
   <name>Root beer</name>
   <UnitPrice>16</UnitPrice>
   <Wt>1</Wt>
   <Unit>pint</Unit>
   <ContainmentType>W</ContainmentType>
</item>

<item name="Pleather">
   <name>Pleather</name>
   <UnitPrice>200</UnitPrice>
   <Wt>75</Wt>
   <Unit>Bale</Unit>
   <ContainmentType>N</ContainmentType>
</item>

</bulkgoods>

Containers.xml

<?xml version="1.0" encoding="UTF-8"?>
<names>
<item name="Gift Box, Small">
   <name>Gift Box, Small</name>
   <Cost>2</Cost>
   <Wt>0.25</Wt>
   <ContainmentType>D</ContainmentType>
   <Capacity>2.5</Capacity>
   <attributes value="H"/>
</item>

<item name="Gift Box, Large">
   <name>Gift Box, Large</name>
   <Cost>15</Cost>
   <Wt>2</Wt>
   <ContainmentType>D</ContainmentType>
   <Capacity>20</Capacity>
   <attributes value="H"/>
</item>

<item name="Gift Bag">
   <name>Gift Bag</name>
   <Cost>30</Cost>
   <Wt>3</Wt>
   <ContainmentType>D</ContainmentType>
   <Capacity>40</Capacity>
   <attributes value="S"/>
</item>

<item name="Shipping Crate">
   <name>Shipping Crate</name>
   <Cost>1000</Cost>
   <Wt>220</Wt>
   <ContainmentType>D</ContainmentType>
   <Capacity>3300</Capacity>
   <attributes value="H"/>
</item>

<item name="Sippy Cup">
   <name>Sippy Cup</name>
   <Cost>5</Cost>
   <Wt>0.25</Wt>
   <ContainmentType>W</ContainmentType>
   <Capacity>0.5</Capacity>
   <attributes value="H"/>
</item>

<item name="Filter Bottle">
   <name>Filter Bottle</name>
   <Cost>3</Cost>
   <Wt>1</Wt>
   <ContainmentType>W</ContainmentType>
   <Capacity>2</Capacity>
   <attributes value="H"/>
</item>

<item name="2 liter bottle">
   <name>2 liter bottle</name>
   <Cost>10</Cost>
   <Wt>4</Wt>
   <ContainmentType>W</ContainmentType>
   <Capacity>2</Capacity>
   <attributes value="H"/>
</item>

<item name="Milk Jug">
   <name>Milk Jug</name>
   <Cost>10</Cost>
   <Wt>0.25</Wt>
   <ContainmentType>W</ContainmentType>
   <Capacity>8</Capacity>
   <attributes value="S"/>
</item>

<item name="Tanker Trailer">
   <name>Tanker Trailer</name>
   <Cost>300</Cost>
   <Wt>60</Wt>
   <ContainmentType>W</ContainmentType>
   <Capacity>60000</Capacity>
   <attributes value="H"/>
</item>

</names>

Curses.xml

<?xml version="1.0" encoding="UTF-8"?>
<curses>
    <item name="Plays the same song over and over">
   <Curse>Plays the same song over and over</Curse>
   <CF>-0.5</CF>
</item>

<item name="Backlash (Poor Q Rating)">
   <Curse>Backlash (Poor Q Rating)</Curse>
   <CF>-0.2</CF>
</item>

<item name="Interesting Times">
   <Curse>Interesting Times</Curse>
   <CF>-0.2</CF>
</item>

<item name="Dysfunctional Family">
   <Curse>Dysfunctional Family</Curse>
   <CF>-0.2</CF>
</item>

<item name="Knuckle-Cracking">
   <Curse>Knuckle-Cracking</Curse>
   <CF>-0.2</CF>
</item>

</curses>

Embellishments.xml

<?xml version="1.0" encoding="UTF-8"?>
<embellishments>
<item name="Foin">
   <Embellishment>Foin</Embellishment>
   <CF>1.5</CF>
   <emb_code>W</emb_code>
   <wtmod>1</wtmod>
</item>
<item name="Foin">
   <Embellishment>Foin</Embellishment>
   <CF>2.5</CF>
   <emb_code>MW</emb_code>
   <wtmod>1.1</wtmod>
</item>
<item name="Foin">
   <Embellishment>Foin</Embellishment>
   <CF>2.5</CF>
   <emb_code>S</emb_code>
   <wtmod>1.1</wtmod>
</item>
<item name="Foin">
   <Embellishment>Foin</Embellishment>
   <CF>6.3</CF>
   <emb_code>B</emb_code>
   <wtmod>1.2</wtmod>
</item>
<item name="Foin">
   <Embellishment>Foin</Embellishment>
   <CF>6</CF>
   <emb_code>A</emb_code>
   <wtmod>0.85</wtmod>
</item>
<item name="Supafoin">
   <Embellishment>Supafoin</Embellishment>
   <CF>6</CF>
   <emb_code>A</emb_code>
   <wtmod>0.85</wtmod>
</item>
<item name="Supafoin">
   <Embellishment>Supafoin</Embellishment>
   <CF>16</CF>
   <emb_code>W</emb_code>
   <wtmod>1.7</wtmod>
</item>
<item name="Supafoin">
   <Embellishment>Supafoin</Embellishment>
   <CF>16</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
</item>
<item name="Bedazzling (cheap, extensive)">
   <Embellishment>Bedazzling (cheap, extensive)</Embellishment>
   <CF>4</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (cheap, minimal)">
   <Embellishment>Bedazzling (cheap, minimal)</Embellishment>
   <CF>1.5</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (expensive, extensive)">
   <Embellishment>Bedazzling (expensive, extensive)</Embellishment>
   <CF>7</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (expensive, minimal)">
   <Embellishment>Bedazzling (expensive, minimal)</Embellishment>
   <CF>3</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (cheap, extensive)">
   <Embellishment>Bedazzling (cheap, extensive)</Embellishment>
   <CF>4</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (cheap, minimal)">
   <Embellishment>Bedazzling (cheap, minimal)</Embellishment>
   <CF>1.5</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (expensive, extensive)">
   <Embellishment>Bedazzling (expensive, extensive)</Embellishment>
   <CF>7</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Bedazzling (expensive, minimal)">
   <Embellishment>Bedazzling (expensive, minimal)</Embellishment>
   <CF>3</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Designer Logos (extensive)">
   <Embellishment>Designer Logos (extensive)</Embellishment>
   <CF>2</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Designer Logos (minimal)">
   <Embellishment>Designer Logos (minimal)</Embellishment>
   <CF>0.75</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
   <motif>P</motif>
</item>
<item name="Material (Recyclable Plastic)">
   <Embellishment>Material (Recyclable Plastic)</Embellishment>
   <CF>0.5</CF>
   <emb_code>B</emb_code>
   <wtmod>1</wtmod>
</item>
<item name="Material (Bakelite)">
   <Embellishment>Material (Bakelite)</Embellishment>
   <CF>1</CF>
   <emb_code>B</emb_code>
   <wtmod>2</wtmod>
</item>
<item name="Corroded">
   <Embellishment>Corroded</Embellishment>
   <CF>-0.25</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
</item>
<item name="Tie-Dye (extensive)">
   <Embellishment>Tie-Dye (extensive)</Embellishment>
   <CF>5</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>Y</motif>
</item>
<item name="Tie-Dye (minimal)">
   <Embellishment>Tie-Dye (minimal)</Embellishment>
   <CF>2</CF>
   <emb_code>S</emb_code>
   <wtmod>1</wtmod>
   <motif>Y</motif>
</item>
<item name="Jeweled">
   <Embellishment>Jeweled</Embellishment>
   <CF>40</CF>
   <emb_code>H</emb_code>
   <wtmod>1</wtmod>
</item>
</embellishments>

Enchantments.xml

<?xml version="1.0" encoding="UTF-8"?>
<enchantments>
<item name="Oh There It Is">
   <Enchantment>Oh There It Is</Enchantment>
   <Type>ALL</Type>
   <Cost>8000</Cost>
   <Reserve>6</Reserve>
</item>
<item name="Take That You Fiend">
   <Enchantment>Take That You Fiend</Enchantment>
   <Type>W</Type>
   <Cost>4000</Cost>
   <Reserve>6</Reserve>
</item>
<item name="Abracadabra">
   <Enchantment>Abracadabra</Enchantment>
   <Type>ALL</Type>
   <Cost>24000</Cost>
   <Reserve>48</Reserve>
</item>
<item name="Hocus Pocus">
   <Enchantment>Hocus Pocus</Enchantment>
   <Type>ALL</Type>
   <Cost>6000</Cost>
   <Reserve>12</Reserve>
</item>
<item name="Bibbidy Bobbity Boo">
   <Enchantment>Bibbidy Bobbity Boo</Enchantment>
   <Type>ALL</Type>
   <Cost>12000</Cost>
   <Reserve>24</Reserve>
</item>
<item name="Curses">
   <Enchantment>Curses</Enchantment>
   <Type>ALL</Type>
   <Cost>18000</Cost>
   <Reserve>36</Reserve>
</item>
<item name="Curses Foiled">
   <Enchantment>Curses Foiled</Enchantment>
   <Type>ALL</Type>
   <Cost>24000</Cost>
   <Reserve>48</Reserve>
</item>
<item name="Curses Foiled Again">
   <Enchantment>Curses Foiled</Enchantment>
   <Type>ALL</Type>
   <Cost>30000</Cost>
   <Reserve>60</Reserve>
</item>
<item name="Alla Kazam">
   <Enchantment>Alla Kazam</Enchantment>
   <Type>ALL</Type>
   <Cost>20000</Cost>
   <Reserve>48</Reserve>
</item>
<item name="Alla Peanut Butter Sandwiches">
   <Enchantment>Alla Peanut Butter Sandwiches</Enchantment>
   <Type>ALL</Type>
   <Cost>15000</Cost>
   <Reserve>30</Reserve>
</item>
<item name="Zap">
   <Enchantment>Zap</Enchantment>
   <Type>MW</Type>
   <Cost>12000</Cost>
   <Reserve>12</Reserve>
</item>
<item name="Kapow">
   <Enchantment>Kapow</Enchantment>
   <Type>W</Type>
   <Cost>8000</Cost>
   <Reserve>18</Reserve>
</item>
   
</enchantments>

Gems.xml

<?xml version="1.0" encoding="UTF-8"?>
<gems>
    <item name="Rhinestone">
   <Gem>Rhinestone</Gem>
   <V>5</V>
</item>

<item name="Tanzenite">
   <Gem>Tanzenite</Gem>
   <V>25</V>
</item>

<item name="Shiny Glass">
   <Gem>Shiny Glass</Gem>
   <V>3</V>
</item>

<item name="Zircon">
   <Gem>Zircon</Gem>
   <V>30</V>
</item>

<item name="Moissanite">
   <Gem>Moissanite</Gem>
   <V>10</V>
</item>
</gems>

Items.xml

<?xml version="1.0" encoding="UTF-8"?>
<items>

<item name="Pointything Cane">
   <name>Pointything Cane</name>
   <Cost>600</Cost>
   <Wt>1.5</Wt>
   <attributes value="H"/>
   <attributes value="W"/>
</item>

<item name="Grille">
   <name>Grille</name>
   <Cost>31.25</Cost>
   <Wt>0.5</Wt>
   <attributes value="Jewelry"/>
   <attributes value="H"/>
</item>

<item name="Prince Albert">
   <name>Prince Albert</name>
   <Cost>0.625</Cost>
   <Wt>0.01</Wt>
   <attributes value="Jewelry"/>
   <attributes value="H"/>
</item>

<item name="Bullets">
   <name>Bullets</name>
   <Cost>2</Cost>
   <Wt>0.1</Wt>
   <attributes value="H"/>
   <attributes value="M"/>
   <attributes value="AMMO"/>
</item>

<item name="Bullets, hollow-point">
   <name>Bullets, hollow-point</name>
   <Cost>2.5</Cost>
   <Wt>0.1</Wt>
   <attributes value="H"/>
   <attributes value="M"/>
   <attributes value="AMMO"/>
</item>

<item name="Choppything">
   <name>Choppything</name>
   <Cost>50</Cost>
   <Wt>4</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
   <attributes value="Brand-H"/>
</item>

<item name="Blackboard">
   <name>Blackboard</name>
   <Cost>60</Cost>
   <Wt>7</Wt>
   <attributes value="H"/>
   <attributes value="Brand-H"/>
</item>

<item name="Backpack Toolkit, Pleatherworker">
   <name>Backpack Toolkit, Pleatherworker</name>
   <Cost>250</Cost>
   <Wt>7.5</Wt>
   <attributes value="H"/>
   <attributes value="S"/>
</item>

<item name="BackPointything">
   <name>BackPointything</name>
   <Cost>550</Cost>
   <Wt>3</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="Ball">
   <name>Ball</name>
   <Cost>3</Cost>
   <Wt>0.25</Wt>
   <attributes value="H"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
</item>

<item name="Barding, Turtle">
   <name>Barding, Turtle</name>
   <Cost>540</Cost>
   <Wt>37</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
</item>

<item name="Bastard Pointything">
   <name>Bastard Pointything</name>
   <Cost>650</Cost>
   <Wt>5</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="BroadPointything">
   <name>BroadPointything</name>
   <Cost>500</Cost>
   <Wt>3</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="Trench Coat">
   <name>Trench Coat</name>
   <Cost>210</Cost>
   <Wt>16</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
</item>

<item name="Frizbee">
   <name>Frizbee</name>
   <Cost>50</Cost>
   <Wt>0.5</Wt>
   <attributes value="H"/>
   <attributes value="M"/>
</item>

<item name="Denim Armor Suit">
   <name>Denim Armor Suit</name>
   <Cost>180</Cost>
   <Wt>13</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
</item>

<item name="Double Mail Hip Flask">
   <name>Double Mail Hip Flask</name>
   <Cost>520</Cost>
   <Wt>44</Wt>
   <attributes value="A"/>
   <attributes value="H"/>
</item>

<item name="Dress SmallPointything">
   <name>Dress SmallPointything</name>
   <Cost>300</Cost>
   <Wt>1</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="Dueling Bohemian Ear-Spoon">
   <name>Dueling Bohemian Ear-Spoon</name>
   <Cost>90</Cost>
   <Wt>6</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
   <attributes value="Brand-H"/>
</item>

<item name="Dueling PollChoppything">
   <name>Dueling PollChoppything</name>
   <Cost>100</Cost>
   <Wt>8</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
   <attributes value="Brand-H"/>
</item>


<item name="GURPS Basic Set: Characters">
   <name>GURPS Basic Set: Characters</name>
   <Cost>50</Cost>
   <Wt>2.5</Wt>
   <attributes value="B"/>
</item>

<item name="GURPS Basic Set: Campaigns">
   <name>GURPS Basic Set: Campaigns</name>
   <Cost>45</Cost>
   <Wt>2.5</Wt>
   <attributes value="B"/>
</item>

<item name="Great Choppything">
   <name>Great Choppything</name>
   <Cost>100</Cost>
   <Wt>8</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
   <attributes value="Brand-H"/>
</item>

<item name="GreatPointything">
   <name>GreatPointything</name>
   <Cost>800</Cost>
   <Wt>7</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="Heavy Pleather Leggings">
   <name>Heavy Pleather Leggings</name>
   <Cost>60</Cost>
   <Wt>4</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Heavy Pleather Sleeves">
   <name>Heavy Pleather Sleeves</name>
   <Cost>50</Cost>
   <Wt>2</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Hook Pointything">
   <name>Hook Pointything</name>
   <Cost>200</Cost>
   <Wt>3</Wt>
   <attributes value="W"/>
   <attributes value="H"/>
</item>

<item name="Pleather Armor">
   <name>Pleather Armor</name>
   <Cost>100</Cost>
   <Wt>10</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Cap">
   <name>Pleather Cap</name>
   <Cost>32</Cost>
   <Wt>0</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Gloves">
   <name>Pleather Gloves</name>
   <Cost>30</Cost>
   <Wt>0</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Helm">
   <name>Pleather Helm</name>
   <Cost>20</Cost>
   <Wt>0.5</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Jacket">
   <name>Pleather Jacket</name>
   <Cost>50</Cost>
   <Wt>4</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Leggings">
   <name>Pleather Leggings</name>
   <Cost>40</Cost>
   <Wt>2</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Pants">
   <name>Pleather Pants</name>
   <Cost>40</Cost>
   <Wt>3</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

<item name="Pleather Suit">
   <name>Pleather Suit</name>
   <Cost>340</Cost>
   <Wt>19.5</Wt>
   <attributes value="A"/>
   <attributes value="S"/>
   <attributes value="Brand-S"/>
   <attributes value="Skin"/>  
</item>

</items>

Motifs.xml

<?xml version="1.0" encoding="UTF-8"?>
<motifs>
    <item name="Good hat">
   <Motif>Good hat</Motif>
</item>
<item name="Evil hat">
   <Motif>Evil hat</Motif>
</item>
<item name="Police Badge">
   <Motif>Police Badge</Motif>
</item>
<item name="Corporate Logo">
   <Motif>Corporate Logo</Motif>
</item>
<item name="Pirate Parrot">
   <Motif>Pirate Parrot</Motif>
</item>
<item name="Anime Hair">
   <Motif>Anime Hair</Motif>
</item>
<item name="Bat Symbol">
   <Motif>Bat Symbol</Motif>
</item>
<item name="Superman Shield">
   <Motif>Superman Shield</Motif>
</item>
<item name="Gang Sign">
   <Motif>Gang Sign</Motif>
</item>
<item name="Philly Phanatic">
   <Motif>Philly Phanatic</Motif>
</item>
<item name="Emoji">
   <Motif>Emoji</Motif>
</item>
</motifs>


SupernaturalEmbellishments.xml

<?xml version="1.0" encoding="UTF-8"?>
<embellishments>
    <item name="Extra Shiny">
   <Embellishment>Extra Shiny</Embellishment>
   <CF>0.25</CF>
</item>
<item name="Smells faintly of lilac">
   <Embellishment>Smells faintly of lilac</Embellishment>
   <CF>0.1</CF>
</item>
<item name="Bringz in da funk, bringz in da noize">
   <Embellishment>Bringz in da funk, bringz in da noize</Embellishment>
   <CF>0.5</CF>
</item>
<item name="Always points the other direction">
   <Embellishment>Always points the other direction</Embellishment>
   <CF>1</CF>
</item>
<item name="Knows how to tango">
   <Embellishment>Knows how to tango</Embellishment>
   <CF>1</CF>
</item>

</embellishments>


Wednesday, May 21, 2014

Hoardomatic Code: Gem Class

Last class. Gems have their own bundle of properties, so they get their own class.

Gem


String gem_name: Name of the gem.
Double val_constant: The value constant for the stone, the V in the(C^2 + C*4) * V value formula.
Double carats: Weight of the gem in carats.

This one is similar to the previous two, but it takes on itself the task of randomly selecting a node from Gems.xml to turn into an object.   

package hoardomatic;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Random;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Gem {

    private String gem_name;
    private Double val_constant;
    private Double carats;
   
    public Gem() {
        // TODO Auto-generated constructor stub
        Node gemnode = getRandomNodeFromTable("Gems.xml");
       
        NodeList tempNodes = gemnode.getChildNodes();
        for (int j = 0; j < tempNodes.getLength(); j++) {
            Node subnode = tempNodes.item(j);

            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) subnode;
               
                if (element.getNodeName().contentEquals("Gem")) {
                    gem_name = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("V")) {
                    val_constant =Double.parseDouble(element.getTextContent());
                }

            }

        }
       
        double dr = (double) dieRoll(1,6) + dieRoll(1,6);
        double the_carats = dr/4;
       
        int get_big = dieRoll(1,12);
        while (get_big == 12){
            the_carats = the_carats + dieRoll(1,6);
            get_big = dieRoll(1,12);
        }
       
        carats = the_carats;
       
    }
   
   
        public Node getRandomNodeFromTable(String fname) {
           
            Node return_it;
            return_it = null;

            try {
                InputStream items = new FileInputStream(new File(fname));
               
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(items);

                doc.getDocumentElement().normalize();
                // System.out.println(doc.getDocumentElement().getNodeName());
                NodeList nodes = doc.getElementsByTagName("item");
               
                Integer itemlistlen = nodes.getLength();
               
                Integer pickItm = dieRoll(0, itemlistlen - 1);
               
                // System.out.println("==========================");
//                System.out.println(pickItm);

                for (int i = 0; i < nodes.getLength(); i++) {
                    Node node = nodes.item(i);
                    if (i == pickItm) {
                        return_it = node;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return return_it;
        }
   
   
    public Gem(Node gemnode){
       
       
        NodeList tempNodes = gemnode.getChildNodes();
        for (int j = 0; j < tempNodes.getLength(); j++) {
            Node subnode = tempNodes.item(j);

            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) subnode;
               
                if (element.getNodeName().contentEquals("Gem")) {
                    gem_name = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("V")) {
                    val_constant =Double.parseDouble(element.getTextContent());
                }

            }

        }
       
       
        double the_carats = (dieRoll(1,6) + dieRoll(1,6))/4;
       
        int get_big = dieRoll(1,12);
        while (get_big == 12){
            the_carats = the_carats + dieRoll(1,6);
            get_big = dieRoll(1,12);
        }
       
        carats = the_carats;
       
       
    }
   
    public Double getGemCost(){
        Double return_it = 0.0;
        // (c^2 + 4 x c) ^ v
        return_it = (carats * carats + 4 * carats) * val_constant;
        return return_it;
    }
   
    public String getGemName(){
        return gem_name;
    }
   
    public Double getGemWt(){
        return carats;
    }
   
    private int dieRoll(Integer min, Integer max) {

        Random r = new Random();
        int inroll = r.nextInt(max - min + 1) + min;
        return inroll;
    }


}

Tuesday, May 20, 2014

Hoardomatic Code: Enchantment Class

Enchantments are structurally very similar to Embellishments. The big difference is how costs are accounted for by the Item containing them.

Enchantment


String Enchantment_name: The name of the enchantment, usually just the name of a spell, though it may include a degree (Accuracy 3) or notation about which version of an enchantment the item has (Bravery (Cast only)).
Double cf: The embellishment's CF value. Not actually used, but it's there because I started enchantments by copying the embellishment class.
Double flat_cost: The base cost of the enchantment.
Double wt_mod: Weight adjustment, if any, which spells generally don't have.
String motif_option: Not used.
String ench_code: A code similar to the embellishment codes, indicating what kind of item the enchantment can be on. Most are generally applicable, but a few are limited to weapons or armor.

This class works very much like the Embellishments class: it takes a node provided to it and populates the enchantment's properties.

package hoardomatic;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Enchantment {
   
    private String Enchantment_name;
    private Double cf;
    private Double flat_cost;
    private Double wt_mod;
    private String motif_option;
    private String ench_code;

    public Enchantment() {

        Enchantment_name = "";
        cf = 0.0;
        flat_cost = 0.0;
        wt_mod = 1.0;
        motif_option = "";
        ench_code = "";
    }
   
    public Enchantment(Node node) {
        flat_cost = 0.0;

        NodeList tempNodes = node.getChildNodes();
        for (int j = 0; j < tempNodes.getLength(); j++) {
            Node subnode = tempNodes.item(j);

            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) subnode;
               
                if (element.getNodeName().contentEquals("Enchantment")) {
                    Enchantment_name = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("CF")) {
                    cf =Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("Cost")) {
                    flat_cost =Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("wtmod")) {
                    wt_mod = Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("ench_code")) {
                    ench_code = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("Type")) {
                    ench_code = element.getTextContent();
                }

            }

        }

    }

   
   
    public Enchantment(String the_name, Double the_cf, Double the_wt_mod) {

        Enchantment_name = the_name;
        cf = the_cf;
        wt_mod = the_wt_mod;
    }
   
    public void setCost(Double new_cost){
        flat_cost = new_cost;
    }
   
    public Double getCost(){
        return flat_cost;
    }
   
    public void setCF(Double new_cf){
        cf = new_cf;
    }
   
   
    public String getEnchantmentName(){
        return Enchantment_name;
    }
   
    public String getMotifOption(){
        return motif_option;
    }
   
    public Double getCf(){
        return cf;
    }

    public Double getWtMod(){
        return wt_mod;
    }
   
    public String getenchCode(){
        return ench_code;
    }


}

Monday, May 19, 2014

Hoardomatic Code: Embellishment Class

This represents an individual decorative or functional embellishment on an item.

Embellishment


String embellishment_name: Name of the embellishment (for example, "Fine material" or "Tassels").
Double cf: The embellishment's CF value.
Double wt_mod: Weight adjustment, if any. This defaults to 1 and is expressed as a decimal multiplier to the base item's weight. For example, 0.9 for an embellishment which reduces the weight of the item by 10%.
String motif_option: Some options don't lead to item having a particular decorative motif (for example, improved materials). Some do (for example, relief carving). Some could go either way (for example, painting; an item could simply be painted, say, entirely green, or have figures painted on it in green). This defaults to "N".
String emb_code: A single string corresponding to the range of attributes which items may have.

The constructor I'm using takes a node (from Embelishments.xml) handed to it by the calling class. It goes through the node's elements and extracts various bits of data, putting them into the appropriate variables.


package hoardomatic;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Embellishment {
   
    private String embellishment_name;
    private Double cf;
    private Double flat_cost;
    private Double wt_mod;
    private String motif_option;
    private String emb_code;

    public Embellishment() {

        embellishment_name = "";
        cf = 0.0;
        flat_cost = 0.0;
        wt_mod = 1.0;
        motif_option = "";
        emb_code = "";
    }
   
    public Embellishment(Node node) {

        motif_option = "";
        wt_mod = 1.0;
        flat_cost = 0.0;

        NodeList tempNodes = node.getChildNodes();
        for (int j = 0; j < tempNodes.getLength(); j++) {
            Node subnode = tempNodes.item(j);

            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) subnode;
               
                if (element.getNodeName().contentEquals("Embellishment")) {
                    embellishment_name = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("motif")) {
                    motif_option = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("CF")) {
                    cf =Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("Cost")) {
                    flat_cost =Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("wtmod")) {
                    wt_mod = Double.parseDouble(element.getTextContent());
                }

                if (element.getNodeName().contentEquals("emb_code")) {
                    emb_code = element.getTextContent();
                }

                if (element.getNodeName().contentEquals("Type")) {
                    emb_code = element.getTextContent();
                }

            }

        }

    }

   
   
    public Embellishment(String the_name, Double the_cf, Double the_wt_mod) {
        // TODO Auto-generated constructor stub
        embellishment_name = the_name;
        cf = the_cf;
        wt_mod = the_wt_mod;
    }

    public void setWtMod(Double new_wt_mod){
        flat_cost = new_wt_mod;
    }
   
    public void setCost(Double new_cost){
        flat_cost = new_cost;
    }
   
    public void setCF(Double new_cf){
        cf = new_cf;
    }
   
   
    public String getEmbellishmentName(){
        return embellishment_name;
    }
   
    public void setEmbellishmentName(String new_name){
        embellishment_name = new_name;
    }
   
    public String getMotifOption(){
        return motif_option;
    }
   
    public Double getCf(){
        return cf;
    }

    public Double getWtMod(){
        return wt_mod;
    }
   
    public String getEmbCode(){
        return emb_code;
    }


}

Friday, May 16, 2014

Hoardomatic Code: Item Class

Here's where most of the work happens. It also contains lots of untidy code which is a consequence of making it up as I go along: stub functions which are unimplemented, implemented but unused functions which don't do anything useful, and references to libraries that don't actually get used. No matter; the bits which do get used do what I need them to.

Item


String item_name: The name of the base item (broadsword, Dwarven theodolite, arrow, etc.)
Double base_cost: The cost of the unembellished item, used as the basis for CF-related price calculations.
Double base_weight: The unembellished weight of the item.
Integer quantity: Usually 1, but ammunition and bulk goods often have a larger quantity
String curse_name: Defaults to an empty string. An item may have no more than one curse.
Double curse_cf: The CF of the curse, which applies to the cost of enchantments.
String unit. The unit of measurement. Defaults to "each," but may be a unit of weight, length, etc.
String bulk_type: The type of bulk storage container the item requires. "W" for liquids, "D" for dry goods like spices, or "N" for items which don't require containers, like bales of hides.
ArrayList<String> attributes: Attributes indicate what kinds of embellishments and other treatments an item may have. For example, a soft item ("S" is an attribute) might have resist dying or embroidery as an embellishment but not relief carving or silver plating, while a hard item ("H" is an attribute) would be the opposite.
ArrayList<Embellishment> embellishments: A list of embellishments applied to the item.
ArrayList<Enchantment> enchantments: A list of enchantments applied to the item.
ArrayList<Gem> gems: a list of gemstones embedded in the object. Gems are a bit more complicated than other embellishments, so they get their own object.
Item container: A container, if necessary. Containers are themselves items which can have embellishments of their own.
String motif_name: A brief description of the item's decorative motif. Defaults to an empty string, since not all items will have a motif.

This is really the key class, representing a single valuable item, which may have multiple embellishments, enchantments, and other frippery about it. Most of what goes on happens in the Item() constructor. First, the getRandomItem() method opens up the list of items (Items.xml), checks the length, gets a random entry within that range, and takes it apart to populate some of the key variables with data.

Certain attributes are treated specially: ammo, jewelry, and bulk goods get a variable quantity. For jewelry, the quantity is invisible; it's effectively a multiplier for heavier rings, larger bracelets, and so on. Bulk goods get additional treatment. There's a stripped-down constructor: Item(String c_type, Double wt_cap). Given a containment type and a weight capacity, it'll get a container out of a special items list (Containers.xml, which contains additional properties not relevant to most items) and make that the container property for the item.

If the item isn't bulk goods, it'll get embellishments and is a candidate for enchantments. After a number of embellishments is rolled up, it opens up the list of embellishments (embellishments.xml) and starts picking some at random. The embellishment's appropriateness is compared to the list of item attributes and, if it's suitable, is added to the list. The loop continues for a while to try to get the right number of embellishments, but it'll bail out if it takes too long. The "Jeweled" embellishment code briefly diverts the process into the machinery to add a randomly selected and sized new gem to the list. After the embellishments are selected, their properties are checked to see if the item needs a decorative motif, which is also selected randomly.

The enchantment section follows. There's a chance of an item having enchantments. If it does, the machinery for adding enchantments is essentially identical to that adding embellishments, with a few specific adjustments. For one thing, an enchanted item has a chance of getting a supernatural embellishment (picked at random from SupernaturalEmbellishments.xml). While the source of the embellishment may be mystical, it acts just like any other embellishment, so it gets added to the embellishment list rather than the enchantment list. There's also a chance of a curse, picked from Curses.xml.

Once created, the key function is report(), which sends back a full description of the item, summarizing the complex of embellishments, enchantments, and so on. The function starts by constructing an expression for the quantity and unit of measurement if necessary and the name of the item itself. Then it constructs a summary list of embellishments and, if necessary, motif, followed by enchantments, curses, container (the container's description is a stripped down version of the full report; it excludes cost and weight, since those will be included in the grand total), and finally the total cost (computed from item base cost, embellishment CFs, enchantment costs, quantity, and container cost) and weight.

package hoardomatic;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;
import java.util.Set;
import java.io.File;
import java.io.FileInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Item {

    private String item_name;
    private Double base_cost;
    private Double base_weight;
    private Integer quantity = 1;
    private String curse_name = "";
    private Double curse_cf = 0.0;
    private String unit = "";
    private String bulk_type;
    private ArrayList<String> attributes = new ArrayList<String>(); // item attributes
    private ArrayList<Embellishment> embellishments = new ArrayList<Embellishment>(); // decorative and functional embellishments
    private ArrayList<Enchantment> enchantments = new ArrayList<Enchantment>(); // enchantments
    private ArrayList<Gem> gems = new ArrayList<Gem>();
    private Item container = null;
    private String motif_name = "";
   
// shiny, iron, organic, plate, mail, scale, edged, impaling
   
    public Item() {
        // TODO Auto-generated constructor stub
        getRandomItem();

        curse_cf = 0.0;
        curse_name = "";

        if (isAttribute("AMMO")){
            // if it's ammo, make it a bunch of them
            quantity = dieRoll(1, 20);
        }
       
        if (isAttribute("Jewelry")){
            // if it's jewelry, maybe make it big
            quantity = dieRoll(1, 6);
        }
       
        if (isAttribute("BULK")){
            // if it's bulk goods, make it a bunch of them
            quantity = dieRoll(1, 6);
            // add a container
           
            //get type from Bulk Goods table.
            getBulkAttributes(getName());
            String the_type = bulk_type;
           
            if (!(unit.contentEquals("Bale")) & !(the_type.contentEquals("N"))){
                container = new Item(the_type, getFinalWeight());
            }
            // end container
        } else {
        // apply random number of embellishments
            Integer rounds = 0; // this prevents excessive looping
        Integer numEmbs = dieRoll(1, 3);
        while (embellishments.size() < numEmbs & rounds < 40 ){
            Node anEmbellishment = null;
            rounds = rounds + 1;
            while ( anEmbellishment == null){
                anEmbellishment = getRandomNodeFromTable("Embellishments.xml");
            }
            Embellishment newEmb = new Embellishment(anEmbellishment);
            if (newEmb.getEmbellishmentName().contentEquals("Jeweled")){
                Gem newgem = new Gem();
                gems.add(newgem);
               
            } else {
                String e_code = newEmb.getEmbCode();
                boolean already_got = hasEmbellishment(newEmb.getEmbellishmentName());
               
                String[] e_codes = e_code.split(";");
                boolean acceptable_attribute = false;
                for (int e_code_count = 0; e_code_count < e_codes.length; e_code_count++){
                    if(isAttribute(e_codes[e_code_count])){
                        acceptable_attribute = true;
                    }
                }
               
               
                if (isAttribute(e_code) | (item_name.toLowerCase().contains(e_code.toLowerCase()) & e_code.length() > 3 ) ){
                    if (! already_got){
                        embellishments.add(newEmb);
                    }
                }               
            }
        }
       
        // add a motif, if needed
       
        // go through the embellishments and see if they require or at least support a motif
        if(embellishments.size() > 0){
            String need_motif = "N";
            for (Embellishment eLine : embellishments) {
                String emb_motif = eLine.getMotifOption();
                if (emb_motif.contentEquals("Y")){
                    need_motif = "Y";
                }else if (emb_motif.contentEquals("P") & !(need_motif.contentEquals("Y")) ){
                    need_motif = "P";
                }
            }
           
            // if they support but don't require a motif, flip a coin
            if (need_motif.contentEquals("P") ){
                int flip = dieRoll(1,2);
                if (flip == 1){
                    need_motif = "Y";
                }
            }
           
            // so if we need a motif, add one
            if (need_motif.contentEquals("Y")){
                Node the_motif_node = getRandomNodeFromTable("Motifs.xml");
                NodeList tempNodes = the_motif_node.getChildNodes();
                for (int j = 0; j < tempNodes.getLength(); j++) {
                    Node subnode = tempNodes.item(j);

                    if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                        Element element = (Element) subnode;

                        if (element.getNodeName().contentEquals("Motif")) {
                            motif_name = element.getTextContent();
                        }
                    }
                }
            }
        } // end embellishments

        // apply random number of enchantments

        rounds = 0;
        Integer hasEnch = dieRoll(1, 10);
        if (hasEnch > 5){
            Integer numEnch = dieRoll(1, 2);
            while (enchantments.size() < numEnch & rounds < 20 ){
                Node anEnchantment = null;
                rounds = rounds + 1;
                while ( anEnchantment == null){
                    anEnchantment = getRandomNodeFromTable("Enchantments.xml");
                }
       
                Enchantment newEnch = new Enchantment(anEnchantment);
                String e_code = newEnch.getenchCode();
               
                boolean already_got = hasEmbellishment(newEnch.getEnchantmentName());
               
                if (isAttribute(e_code) | e_code.contentEquals("ALL") ){
                    if (! already_got){
                        enchantments.add(newEnch);
                    }
                }
            }
       
            // check for supernatural embellishments
            Integer hasSE = dieRoll(1,10);
            if (hasSE > 5) {
                Node anEmbellishment = getRandomNodeFromTable("SupernaturalEmbellishments.xml");
            Embellishment newEmb = new Embellishment(anEmbellishment);
            String se_name = newEmb.getEmbellishmentName();
            newEmb.setEmbellishmentName(se_name + " (supernatural effect)");
                    embellishments.add(newEmb);
            }
            // check for curses
            Integer hasC = dieRoll(1,10);
            if (hasC > 9) {
                Node aCurse = getRandomNodeFromTable("Curses.xml");
                NodeList tempNodes = aCurse.getChildNodes();
                for (int j = 0; j < tempNodes.getLength(); j++) {
                    Node subnode = tempNodes.item(j);

                    if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                        Element element = (Element) subnode;
                       
                        if (element.getNodeName().contentEquals("Curse")) {
                            curse_name = element.getTextContent();
                        }

                        if (element.getNodeName().contentEquals("CF")) {
                            curse_cf = Double.parseDouble(element.getTextContent());
                        }
                    }
                }
               
            }
            // end curses
        }
        // end enchantments
        }
       
    }
   
    public String report(){
       
        String full_report = "";
       
        // name and, if needed, quantity
        if(quantity > 1 & !(isAttribute("Jewelry")) ){
            full_report = full_report + quantity.toString() + " ";
           
            if (!(unit.contentEquals("Each"))){
                full_report = full_report + unit + " ";
            }
        }
        full_report = full_report + item_name + ". ";
       
        String motif_exp = "";
        if (!(motif_name.contentEquals("") )){
            motif_exp = "; decorated with " + motif_name + " motif";
        }
       
        // embellishment list
        if(embellishments.size() > 0){
            int rounds = 1;
            for (Embellishment eLine : embellishments) {
                full_report = full_report + eLine.getEmbellishmentName();
                rounds = rounds + 1;
                if (rounds <= embellishments.size()){
                    full_report = full_report + ", ";
                }else{
                    full_report = full_report + motif_exp + ". ";
                }
            }
        } // end embellishments
       
        // gem list
        if(gems.size() > 0){
            int rounds = 1;
           
            full_report = full_report + "Set with ";
           
            for (Gem eLine : gems) {
                full_report = full_report + eLine.getGemWt().toString() + " ct. " + eLine.getGemName();
                rounds = rounds + 1;
                if (rounds <= gems.size()){
                    full_report = full_report + ", ";
                }else{
                    full_report = full_report + ". ";
                }
            }
        } // end gems
       
        // enchantment list
       
        if(enchantments.size() > 0){
            int rounds = 1;
            full_report = full_report + "Enchanted with ";
            for (Enchantment eLine : enchantments) {
                full_report = full_report + eLine.getEnchantmentName() ;
                rounds = rounds + 1;
                if (rounds <= enchantments.size()){
                    full_report = full_report + ", ";
                }else{
                    full_report = full_report + ". ";
                }
            }
            if(!curse_name.contentEquals("")){
                full_report = full_report + "Cursed with " + curse_name + ". ";
            }
        } // end enchantments
       
        if(!(container == null)){
            full_report = full_report + "Contained in " + container.report_short();
        }

        Double f_cst = getFinalCost();
        Double f_wt = getFinalWeight();
       
        DecimalFormat df = new DecimalFormat("#.00");
        NumberFormat fmt = NumberFormat.getCurrencyInstance();
       
        full_report = full_report + fmt.format(f_cst) + ", ";
        full_report = full_report + df.format(f_wt);

        if (f_wt > 1){
            full_report = full_report + " lbs.";
        }else{
            full_report = full_report + " lb.";
        }
       
        return full_report;
       
    }
   
    public String report_short(){
       
        String full_report = "";
       
        // name and, if needed, quantity
        if(quantity > 1){
            full_report = full_report + quantity.toString() + " x ";
        }
        full_report = full_report + item_name + ". ";
       
        String motif_exp = "";
        if (!(motif_name.contentEquals("") )){
            motif_exp = "; decorated with " + motif_name + " motif";
        }
       
        // embellishment list
        if(embellishments.size() > 0){
            int rounds = 1;
            for (Embellishment eLine : embellishments) {
                full_report = full_report + eLine.getEmbellishmentName();
                rounds = rounds + 1;
                if (rounds <= embellishments.size()){
                    full_report = full_report + ", ";
                }else{
                    full_report = full_report + motif_exp + ". ";
                }
            }
        } // end embellishments
       
        // enchantment list
       
        if(enchantments.size() > 0){
            int rounds = 1;
            full_report = full_report + "Enchanted with ";
            for (Enchantment eLine : enchantments) {
                full_report = full_report + eLine.getEnchantmentName() ;
                rounds = rounds + 1;
                if (rounds <= enchantments.size()){
                    full_report = full_report + ", ";
                }else{
                    full_report = full_report + ". ";
                }
            }
            if(!curse_name.contentEquals("")){
                full_report = full_report + "Cursed with " + curse_name + ". ";
            }
        } // end enchantments
       
        return full_report;
    }

    public Item(String specific_item) {
        // TODO Auto-generated constructor stub
        getNamedItem(specific_item);
        //
    }
   
    public Item(double low_val, double high_val) {
        // get random item
        getRandomItem();
       
    }
   
    public Double getFinalCost(){
        Double final_cost = getBaseCost();
        final_cost = final_cost * (1 + getTotalCF());
        final_cost = final_cost + getEnchantmentCosts();
               
        // gem list
        if(gems.size() > 0){
           
            for (Gem eLine : gems) {
                final_cost = final_cost + eLine.getGemCost();
            }
        } // end gems
       
        if (!(container == null)){
            final_cost = final_cost + container.getFinalCost();
        }
       
        return final_cost;
    }
   
    public boolean hasEmbellishment(String embName){
        boolean return_it = false;
        if (embellishments.size() > 0){
            for (Embellishment eLine : embellishments) {
                String this_nom = eLine.getEmbellishmentName();
                String embName_short = "";
               
                if (embName.indexOf("(") > 0){
                    embName_short = embName.substring(0, embName.indexOf("("));
                }else{
                    embName_short = embName;
                }
               
                if (this_nom.contains(embName_short)){
                    return_it = true;
                }
            }
        }
       
        return return_it;

    }
   
    public Double getTotalCF(){
        Double total_cf = 0.0;
        if (embellishments.size() > 0){
            for (Embellishment eLine : embellishments) {
                total_cf = total_cf + eLine.getCf();
            }
        }
        return total_cf;
    }
   
    public Double getEnchantmentCosts(){
        Double total_costs = 0.0;
        if (enchantments.size() > 0){
            for (Enchantment eLine : enchantments) {
                total_costs = total_costs + eLine.getCost() ;
            }
        }
       
        total_costs = total_costs * (1+ curse_cf);
       
        return total_costs;
    }
   
    public void getRandomItem() {

        try {
            InputStream items = new FileInputStream(new File("Items.xml"));
           
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(items);

            doc.getDocumentElement().normalize();
            NodeList nodes = doc.getElementsByTagName("item");
            Integer itemlistlen = nodes.getLength();
            Integer pickItm = dieRoll(0, itemlistlen-1);
            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                NamedNodeMap attrs = node.getAttributes();
               
                Node sn = attrs.getNamedItem("name");
               
                if (i == pickItm) {

                    NodeList tempNodes = node.getChildNodes();
                    for (int j = 0; j < tempNodes.getLength(); j++) {
                        Node subnode = tempNodes.item(j);

                        if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                            Element element = (Element) subnode;

                            if (element.getNodeName().contentEquals("name")) {
                                item_name = element.getTextContent();
                            }

                            if (element.getNodeName().contentEquals("Wt")) {
                               
                                String base_read = element.getTextContent();
                                if (base_read == "" | base_read.length() == 0)
                                {
                                    base_cost = 0.0;
                                } else {
                                    base_weight = Double.parseDouble(element.getTextContent());
                                }
                            }

                            if (element.getNodeName().contentEquals("Cost")) {
                               
                                String base_read = element.getTextContent();
                                if (base_read == "" | base_read.length() == 0)
                                {
                                    base_cost = 0.0;
                                } else {
                                    base_cost = Double.parseDouble(element.getTextContent());
                                }
                               
                            }

                            if (element.getNodeName().contentEquals("attributes")) {
                                attributes.add(element.getAttribute("value").toString()) ;
                            }
                        }

                    }

                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   
    public void getNamedItem(String the_item) {

        try {
            InputStream items = new FileInputStream(new File("Items.xml"));
           
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(items);

            doc.getDocumentElement().normalize();
            NodeList nodes = doc.getElementsByTagName("item");

            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                NamedNodeMap attrs = node.getAttributes();
               
                Node sn = attrs.getNamedItem("name");
               
                if (sn.getTextContent().contentEquals(the_item)) {

                    NodeList tempNodes = node.getChildNodes();
                    for (int j = 0; j < tempNodes.getLength(); j++) {
                        Node subnode = tempNodes.item(j);

                        if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                            Element element = (Element) subnode;

                            if (element.getNodeName().contentEquals("name")) {
                                item_name = element.getTextContent();
                            }

                            if (element.getNodeName().contentEquals("Wt")) {
                               
                                String base_read = element.getTextContent();
                                if (base_read == "" | base_read.length() == 0)
                                {
                                    base_cost = 0.0;
                                } else {
                                    base_weight = Double.parseDouble(element.getTextContent());
                                }
                            }

                            if (element.getNodeName().contentEquals("Cost")) {
                               
                                String base_read = element.getTextContent();
                                if (base_read == "" | base_read.length() == 0)
                                {
                                    base_cost = 0.0;
                                } else {
                                    base_cost = Double.parseDouble(element.getTextContent());
                                }
                               
                            }

                            if (element.getNodeName().contentEquals("attributes")) {
                                attributes.add(element.getAttribute("value").toString()) ;
                            }

                        }

                    }

                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
   
    public Double getFinalWeight(){
       
        Double running_weight = base_weight;
        if (embellishments.size() > 0){
            for (Embellishment eLine : embellishments) {
                running_weight = running_weight * eLine.getWtMod();
            }
        }
        running_weight = running_weight * quantity;
        if (!(container == null)){
            running_weight = running_weight + container.getFinalWeight();
        }
        return running_weight;
    }
   
     public String getName(){
         return item_name;
     }

     public Integer getQuantity(){
         return quantity;
     }

     public Double getWeight(){
         // do a bunch of math
         return base_weight;
     }
     public Double getCost(){
         return base_cost;
     }
     public Double getBaseWeight(){
         return base_weight;
     }
     public Double getBaseCost(){
         return base_cost;
     }
   
     public boolean isAttribute(String test_val){
         boolean p = false;
            for (String aLine : attributes) {
                if (aLine.contentEquals(test_val)) {
                    p = true;
                }
            }
         return p;
     }
   
     public String getEmbellishments(){
         return "";
     }
     public boolean isEmbellishment(String test_val){
         return true;
     }
     public String getEnchantments(){
         return "";
     }
     public boolean isEnchantment(String test_val){
         return true;
     }
     public String getContainer(){
         return "";
     }
     public void addEmbellishment(){}
     public void addEnchantment(){}
     public void addContainer(){}
   
     public ArrayList<Gem> getGems(){
         return gems;
     }

    public Node getRandomNodeFromTable(String fname) {
           
            Node return_it;
            return_it = null;

            try {
                InputStream items = new FileInputStream(new File(fname));
               
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(items);

                doc.getDocumentElement().normalize();
                NodeList nodes = doc.getElementsByTagName("item");
                Integer itemlistlen = nodes.getLength();
                Integer pickItm = dieRoll(0, itemlistlen - 1);

                for (int i = 0; i < nodes.getLength(); i++) {
                    Node node = nodes.item(i);
                    if (i == pickItm) {
                        return_it = node;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return return_it;
        }
       
       
        public String getBulkType(String bulk_name){
            String bulk_type = "";
           
            Node bulk_node = getNamedNodeFromTable("BulkGoods.xml", bulk_name);
           
            NodeList tempNodes = bulk_node.getChildNodes();
            for (int j = 0; j < tempNodes.getLength(); j++) {
                Node subnode = tempNodes.item(j);

                if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) subnode;
                   
                    if (element.getNodeName().contentEquals("ContainmentType")) {
                        bulk_type = element.getTextContent();
                    }

                }

            }
           
            return bulk_type;
        }
       
        public void getBulkAttributes(String bulk_name){
           
            Node bulk_node = getNamedNodeFromTable("BulkGoods.xml", bulk_name);
           
            NodeList tempNodes = bulk_node.getChildNodes();
            for (int j = 0; j < tempNodes.getLength(); j++) {
                Node subnode = tempNodes.item(j);

                if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) subnode;
                   
                    if (element.getNodeName().contentEquals("ContainmentType")) {
                        bulk_type = element.getTextContent();
                    }

                    if (element.getNodeName().contentEquals("Unit")) {
                        unit = element.getTextContent();
                    }

                }

            }
        }
       
   
        public Node getNamedNodeFromTable(String fname, String get_item) {
           
            Node return_it;
            return_it = null;

            try {
                InputStream items = new FileInputStream(new File(fname));
               
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(items);

                doc.getDocumentElement().normalize();
                NodeList nodes = doc.getElementsByTagName("item");

                for (int i = 0; i < nodes.getLength(); i++) {
                    Node node = nodes.item(i);
                    NamedNodeMap attrs = node.getAttributes();
                   
                    Node sn = attrs.getNamedItem("name");
                    if (sn.getTextContent().contentEquals(get_item)) {
                        return_it = node;
                    }
               
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            return return_it;
        }
       
        private int dieRoll(Integer min, Integer max) {

            Random r = new Random();
            int inroll = r.nextInt(max - min + 1) + min;
            return inroll;
        }
       
        // container stuff
        public Item(String c_type, Double wt_cap) {
           
            // This creates a container item of a given type and capacity
           
            getSizedContainer(c_type, wt_cap);
               
                // apply random number of embellishments
                    Integer rounds = 0;
                Integer numEmbs = dieRoll(1, 2);
                while (embellishments.size() < numEmbs & rounds < 20 ){
                    Node anEmbellishment = null;
                    rounds = rounds + 1;
                    while ( anEmbellishment == null){
                        anEmbellishment = getRandomNodeFromTable("Embellishments.xml");
                    }
           
                    Embellishment newEmb = new Embellishment(anEmbellishment);
                   
                    if (newEmb.getEmbellishmentName().contentEquals("Jeweled")){
                        Gem newgem = new Gem();
                        gems.add(newgem);
                       
                    } else {
                        String e_code = newEmb.getEmbCode();
                        boolean already_got = hasEmbellishment(newEmb.getEmbellishmentName());
                        if (isAttribute(e_code) | (item_name.toLowerCase().contains(e_code.toLowerCase()) & e_code.length() > 3 ) ){
                            if (! already_got){
                                embellishments.add(newEmb);
                            }
                        }               
                    }
               
               
               
                }
               
                // add a motif, if needed
               
                // go through the embellishments and see if they require or at least support a motif
                if(embellishments.size() > 0){
                    String need_motif = "N";
                    for (Embellishment eLine : embellishments) {
                        String emb_motif = eLine.getMotifOption();
                        if (emb_motif.contentEquals("Y")){
                            need_motif = "Y";
                        }else if (emb_motif.contentEquals("P") & !(need_motif.contentEquals("Y")) ){
                            need_motif = "P";
                        }
                    }
                   
                    // if they support but don't require a motif, flip a coin
                    if (need_motif.contentEquals("P") ){
                        int flip = dieRoll(1,2);
                        if (flip == 1){
                            need_motif = "Y";
                        }
                    }
                   
                    // so if we need a motif, add one
                    if (need_motif.contentEquals("Y")){
                        Node the_motif_node = getRandomNodeFromTable("Motifs.xml");
                        NodeList tempNodes = the_motif_node.getChildNodes();
                        for (int j = 0; j < tempNodes.getLength(); j++) {
                            Node subnode = tempNodes.item(j);

                            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                                Element element = (Element) subnode;

                                if (element.getNodeName().contentEquals("Motif")) {
                                    motif_name = element.getTextContent();
                                }
                            }
                        }
                    }
                } // end embellishments
            }

            public void getSizedContainer(String substance_type, Double wt_capacity) {
               
                Double ct_cap = 0.0;
                String ct_type = "";

                try {
                   
                    InputStream items = new FileInputStream(new File("Containers.xml"));
                   
                    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                    Document doc = dBuilder.parse(items);

                    doc.getDocumentElement().normalize();
                    NodeList nodes = doc.getElementsByTagName("item");

                    for (int i = 0; i < nodes.getLength(); i++) {
                        Node node = nodes.item(i);
                        NamedNodeMap attrs = node.getAttributes();
                        Node sn = attrs.getNamedItem("name");
                            NodeList tempNodes = node.getChildNodes();
                            for (int j = 0; j < tempNodes.getLength(); j++) {
                                Node subnode = tempNodes.item(j);

                                if (subnode.getNodeType() == Node.ELEMENT_NODE) {
                                    Element element = (Element) subnode;
                                   
                                    if (element.getNodeName().contentEquals("ContainmentType")) {
                                        ct_type = element.getTextContent();
                                    }
                                    if (element.getNodeName().contentEquals("Capacity")) {
                                       
                                        String base_read = element.getTextContent();
                                            ct_cap = Double.parseDouble(element.getTextContent());
                                    }
                                   

                                    if (element.getNodeName().contentEquals("name")) {
                                        item_name = element.getTextContent();
                                    }

                                    if (element.getNodeName().contentEquals("Wt")) {
                                       
                                        String base_read = element.getTextContent();
                                        if (base_read == "" | base_read.length() == 0)
                                        {
                                            base_cost = 0.0;
                                        } else {
                                            base_weight = Double.parseDouble(element.getTextContent());
                                        }
                                    }

                                    if (element.getNodeName().contentEquals("Cost")) {
                                       
                                        String base_read = element.getTextContent();
                                        if (base_read == "" | base_read.length() == 0)
                                        {
                                            base_cost = 0.0;
                                        } else {
                                            base_cost = Double.parseDouble(element.getTextContent());
                                        }
                                    }
                                    if (element.getNodeName().contentEquals("attributes")) {
                                        attributes.add(element.getAttribute("value").toString()) ;
                                    }
                               
                                   
                                }
                            }
                           
                            // if the containment type is good and the container will hold enough, break the loop
                            if (ct_type.contentEquals(substance_type) & ct_cap >= wt_capacity){
                                break;
                            }
                           
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
           
        // end container stuff

}