Skip to main content

Hoardomatic Code: Hoard Class

I've decided to start making available the code I've written for my treasure generator in a leisurely fashion. I won't be posting the XML files containing the data (that'd basically be posting the contents of DF8), but I will be putting up some sample files to demonstrate how the raw data is shaped.

This code is very rough, having been composed...let's say, organically, rather than according to a well thought-out plan and good programming principles. It contains much which is incomplete or inefficient. However, it ultimately gives me lists of useful treasures, which is more or less as far as I'm inclined to take things without it turning into something tediously like my day job. However, it may help those who want to pursue something similar.

Briefly, then, I've assembled a mess of Java code to represent bunches of items. The intended entry point is a Hoard object. A hoard contains a bunch of items, which in turn has a number of simple properties (base weight, base cost, name, etc.) and more complex properties representing lists of enchantments, lists of decorative embellishments, and containers, which are themselves items. Going from the top down, I'm starting with the Hoard class.

Hoard


ArrayList<Item> items: A list of items
Double remaining_val: Portion of the hoard's value not made up in items.

The hoard is a pretty simple construct containing a batch of items. The main usage I've implemented for it is a constructor which takes a Double value indicating the desired value of the hoard. Given that, it sets an approximate threshold for the maximum value of the items and randomly adds items to the list until it passes that value. I left some wiggle room in the value of the items so that the hoard-generator wouldn't get itself into an excessively long loop trying to find an item of just the right value to round out the desired total value of the hoard. There's a secondary constructor which takes a target value, a list of required attributes and a list of forbidden attributes. It acts much like the first constructor, but it tests prospective items by making sure they have an attribute on the required list and don't have any attributes on the forbidden list. This is the way to get, say, "the contents of the armory" (by requiring weapons and armor) or "the contents of the giant adventurer-eater's stomach" (by forbidding organic items).

Beyond that, the Hoard class just has a few functions bundling up the total value (necessary to check running progress) and concatenating descriptions of its component items. Here's the code:


package hoardomatic;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;

public class Hoard {

    private ArrayList<Item> items = new ArrayList<Item>(); // item attributes
    private Double remaining_val = 0.0;
   
    public Hoard() {
        // TODO Auto-generated constructor stub
    }
   
    public void setRemaining(Double inval){
        remaining_val = inval;
    }
   
    public Hoard(Double max_value){
       
        Double ceiling_val = max_value * .9;
        while(getHoardValue() < ceiling_val){
            Item test_item = new Item();
            if ((test_item.getFinalCost() + getHoardValue()) < max_value ){
                items.add(test_item);
            }
        }
        remaining_val = max_value - getHoardValue();
    }
   
   
    public void addItem (Item the_item){
        items.add(the_item);
    }
   
    public Hoard(Double max_value, ArrayList<String> req_list, ArrayList<String> forb_list){
       
        Double ceiling_val = max_value * .9;
        while(getHoardValue() < ceiling_val){
            Item test_item = new Item();
            boolean do_add = false;
            if ((test_item.getFinalCost() + getHoardValue()) < max_value ){
                // required attributes
                if (req_list.size() < 1){
                    do_add = true;
                }
               
                for(int a = 0; a < req_list.size() ; a++){
                    if (test_item.isAttribute(req_list.get(a))){
                        do_add = true;
                    }
                   
                    if (req_list.get(a).contentEquals("Shiny")){
                        if (test_item.isAttribute("Jewelry") | test_item.isAttribute("Iron") | test_item.isAttribute("Steel") | test_item.getGems().size() > 0 ){
                            do_add = true;
                        }
                    }
                   
                    if (req_list.get(a).contentEquals("Enchanted")){
                        if (test_item.getEnchantments().length() > 0 ){
                            do_add = true;
                        }
                    }
                }
               
                // forbidden attributes
                for(int b = 0; b < forb_list.size() ; b++){
                    if (test_item.isAttribute(forb_list.get(b))){
                        do_add = false;
                    }
                   
                    if (forb_list.get(b).contentEquals("Shiny")){
                        if (test_item.isAttribute("Jewelry") | test_item.isAttribute("Iron") | test_item.isAttribute("Steel") | test_item.getGems().size() > 0 ){
                            do_add = false;
                        }
                    }
                   
                    if (forb_list.get(b).contentEquals("Enchanted")){
                        if (test_item.getEnchantments().length() > 0 ){
                            do_add = false;
                        }
                    }
                }
            }

            if(do_add){
                items.add(test_item);
            }
           
        }
        remaining_val = max_value - getHoardValue();
    }

   
    public String hoardReport(){
        String full_report = "";
       
        for (Item iLine : items) {
            full_report = full_report + iLine.report() + "\n" ;
        }
       
        NumberFormat fmt = NumberFormat.getCurrencyInstance();
        full_report = full_report + fmt.format(remaining_val) + " in coins.";
       
        return full_report;
       
    }
   
   
    public Double getHoardValue(){
       
        Double total_val = 0.0;
       
        if(items.size() > 0){
            for (Item iLine : items) {
                total_val = total_val + iLine.getFinalCost();
            }
        }
        return total_val;
    }

}



Comments

Popular posts from this blog

Argonath 5

A while back, I made a Barad Dur case for The Kid's Xbox . And then he got a PS5. So...   The first possibility I looked at for a way of dressing up the console was Minas Tirith, but there's no way I could make that fit in any reasonable space. Then I hit on the Argonath, the twin statues marking the northern border of Gondor on the Anduin. One statue on either side? Doable.   There are a bunch of free versions of the Argonath out there, but they kind of suck, so I shelled out a few bucks for a much better model , and I do not regret it. Much like Barad Dur, I went through the simple process of scaling up and dividing into printable parts and then the multi-week process of printing them all out. After gluing together, I put on a coat of sandable primer. The thicker paint helps conceal the print lines a little bit.   Then stippling to give a natural stone look.   I wanted the unsculpted parts to look like they still had natural ground cover on them, so I masked the st...

Briefly, How To Play GURPS

For a long time, I’ve maintained that GURPS, despite its reputation for complexity, is actually pretty simple in play. I was thinking recently that I should see if I can express the fundamentals of playing GURPS in a short, easily digested form, and so here I am.   This does not address a more general “how to play rpgs” for those who know nothing on the topic. How to approach GURPS, at that level, isn’t necessarily a lot different from how to approach D&D or TFT or any other RPG system. It doesn’t get into optional and campaign-specific sets of rules or equipment. Rather, this is stuff applicable to playing GURPS no matter what the campaign is. It also doesn’t address how to build GURPS characters, which is a vastly more complicated topic. Rather, this is about how to engage GURPS rules when you’ve already got your character sheet and are sitting at the table to play. It’s a trifle over 1000 words, which I think isn’t too bad.   How To Play GURPS Most of what you’ll need t...

Spaced Out Rides

(This is the kind of thing I'd have sent into Pyramid   back in the day, but that's not an option now, so here we are.)   The GURPS Action series is the gift that keeps on giving for a lot of modern-and-later gaming. GURPS Action 2: Exploits has rules for sneaking around, running away, and all kinds of other activities which can be easily transplanted to cyberpunk and other high-tech settings. GURPS Action 6: Tricked-Out Rides provides more of the same for its topic, giving an easy framework for describing and even designing common types of vehicles without all the math and paralysis-by-analysis of GURPS Vehicles. Pick a standardized vehicle type (van, compact car, etc.) and apply modifiers (rugged, tinted windows). But, of course, it’s limited. It’s just ten pages, after all, so it’s great for common passenger vehicles for the modern(ish) era. But higher-tech vehic...