function rail_peddler_run()
{
    global $session, $inventory;
    $op = httpget("op");
    $loc = rail_peddler_getloc();
    $hid = $loc["peddlerhid"];
    $rid = $loc["peddlerrid"];
    $price = get_module_setting("peddlerprice");
    if ($op == "buy") {
        $headertext = "Why sure, I'll take one of those!";
    } else {
        $headertext = "Go away, I'm busy.";
    }
    page_header($headertext);
    switch ($op) {
        case "buy":
            output("The scruffy vendor's eyes gleam. Was that a fla`gs`0h of green, or no? \"`2Verra wise, %s. Ye willna be sorry!`0\"`n`n", translate_inline($session['user']['sex'] ? 'lass' : 'lad'));
            give_item("cardcase");
            //			if (!$success){
            //				output("Then -- a frown. \"`2Wait, no, I canna sell t'ye. Ye'd better petition the Big Boss, tell 'im t'see what's gaen wrong wiv all dis.`0\"`n`n");
            //			} else {
            output("You have a fine leather card case. Pleased, you admire its soft texture. What an excellent purchase you have made!`n`n");
            //			}
            $session['user']['gems'] -= $price;
            break;
        case "pass":
            output("\"`2Bleedin' smart-arse.`0\" The scruffy vendor shrugs and goes off to pester someone else.`n`n");
            break;
    }
    addnav("Back to the Concourse", "runmodule.php?module=improbablehousing&op=interior&hid={$hid}&rid={$rid}");
    page_footer();
}
function hunterslodge_selectionbox_use($args)
{
    global $session;
    //give all the items in the Selection Box
    //eboy's items
    for ($i = 0; $i < 2; $i++) {
        give_item("banggrenade");
        give_item("cratesniffer");
        give_item("energydrink");
        give_item("improbabilitybomb");
        give_item("largemedkit");
        give_item("monsterrepellentspray");
        give_item("nicotinegum");
        give_item("oneshotteleporter");
        give_item("rationpack");
        give_item("smallmedkit");
        give_item("whoomphgrenade");
        give_item("zapgrenade");
    }
    //lodge items
    give_item("buildersbrew");
    give_item("hunterslodge_avatar");
    give_item("hunterslodge_cigs_small");
    give_item("hunterslodge_customarmour");
    give_item("hunterslodge_customcolours");
    give_item("hunterslodge_customrace");
    give_item("hunterslodge_customtitle");
    give_item("hunterslodge_customweapon");
    give_item("hunterslodge_namedmount");
    give_item("hunterslodge_req_small");
    give_item("hunterslodge_specialcomments_small");
    return $args;
}
function hunterslodge_selectionbox_builder_use($args)
{
    global $session;
    //give all the items in the Selection Box
    for ($i = 0; $i < 10; $i++) {
        give_item("buildersbrew");
        give_item("monsterrepellentspray");
        give_item("oneshotteleporter");
        give_item("rationpack");
        give_item("energydrink");
    }
    give_item("hunterslodge_cigs_large");
    give_item("hunterslodge_cigs_large");
    return $args;
}
function supplycrates_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "donation":
            $amt = $args['amt'];
            $donationbonus = floor($args['amt'] / get_module_setting("donationaddition"));
            $xmax = get_module_setting("worldmapsizeX", "worldmapen");
            $ymax = get_module_setting("worldmapsizeY", "worldmapen");
            for ($i = 0; $i < $donationbonus; $i++) {
                $x = e_rand(1, $xmax);
                $y = e_rand(1, $ymax);
                $owner = "worldmap_" . $x . "," . $y . ",1";
                give_item("supplycrate", false, $owner);
            }
            break;
    }
    return $args;
}
function hunterslodge_selectionbox_eboy_use($args)
{
    global $session;
    //give all the items in the Selection Box
    //eboy's items
    for ($i = 0; $i < 2; $i++) {
        give_item("banggrenade");
        give_item("cratesniffer");
        give_item("energydrink");
        give_item("improbabilitybomb");
        give_item("largemedkit");
        give_item("monsterrepellentspray");
        give_item("nicotinegum");
        give_item("oneshotteleporter");
        give_item("rationpack");
        give_item("smallmedkit");
        give_item("whoomphgrenade");
        give_item("zapgrenade");
    }
    return $args;
}
function human_loot_run()
{
    global $session;
    page_header("The Procurement of Appurtenances");
    if (get_module_pref("itemstaken") <= 3 && httpget("give")) {
        debug(get_module_pref("itemstaken"));
        give_item(httpget("give"));
        increment_module_pref("itemstaken");
    }
    debug(get_module_pref("itemstaken"));
    switch (get_module_pref("itemstaken")) {
        case 0:
            output("\"`1Ah.  Yes, I don't believe you've had your standard equipment issue today.  Well, let's get started, then.`0\"  The man sets his newspaper down, and counts on his fingers.  \"`1We've got BANG Grenades, ZAP Grenades, WHOOMPH Grenades, Small Medkits and Ration Packs.  You can have any three items you like.`0\"`n`nHe unselfconsciously goes back to reading his newspaper while you make up your mind.");
            break;
        case 1:
            output("\"`1Okay.`0\"  The man reaches under his desk and brings up your chosen item, without taking his hands off the newspaper.  \"`1Two more.`0\"");
            break;
        case 2:
            output("\"`1Right-ho.`0\"  The man once again reaches under his desk and brings up your chosen item.  You wonder if he would even notice if someone else came in and took your place.  \"`1Last one, now.`0\"");
            break;
        case 3:
            output("\"`1Right, there we are.`0\"  The man plonks your chosen item down next to the others.  \"`1Have a nice day, and try not to get killed.`0\"");
            break;
    }
    if (get_module_pref("itemstaken") < 3) {
        addnav("Gimme a...");
        addnav("BANG Grenade", "runmodule.php?module=human_loot&give=banggrenade");
        addnav("WHOOMPH Grenade", "runmodule.php?module=human_loot&give=whoomphgrenade");
        addnav("ZAP Grenade", "runmodule.php?module=human_loot&give=zapgrenade");
        addnav("Small Medkit", "runmodule.php?module=human_loot&give=smallmedkit");
        addnav("Ration Pack", "runmodule.php?module=human_loot&give=rationpack");
    } else {
        addnav("Out you go, then.");
        addnav("Leave", "village.php");
    }
    page_footer();
}
function supplycrate_use($args)
{
    increment_module_pref("cratesopened", 1, "supplycrates");
    $found = get_module_pref("cratesopened", "supplycrates");
    if (is_module_active("medals")) {
        if ($found > 250) {
            require_once "modules/medals.php";
            medals_award_medal("crate1000", "Supreme Crate Finder", "This player has opened more than 250 Supply Crates!", "medal_crategold.png");
        }
        if ($found > 50) {
            require_once "modules/medals.php";
            medals_award_medal("crate500", "Expert Crate Finder", "This player has opened more than 50 Supply Crates!", "medal_cratesilver.png");
        }
        if ($found > 10) {
            require_once "modules/medals.php";
            medals_award_medal("crate100", "Supreme Crate Finder", "This player has opened more than 10 Supply Crates!", "medal_cratebronze.png");
        }
    }
    $crateables = get_items_with_settings("cratefind");
    $randompool = array();
    foreach ($crateables as $item => $prefs) {
        for ($i = 0; $i < $prefs['cratefind']; $i++) {
            $randompool[] = $item;
        }
    }
    output("You spend a few minutes prying open your Supply Crate.`n");
    $giveitems = array();
    $numitems = e_rand(get_module_setting("minitems", "supplycrates"), get_module_setting("maxitems", "supplycrates"));
    $chosenitems = array_rand($randompool, $numitems);
    foreach ($chosenitems as $key => $poolkey) {
        $item = $randompool[$poolkey];
        $name = $crateables[$item]['verbosename'];
        output("You find a %s!`n", $name);
        give_item($item);
    }
    return $args;
}
function items_world_map_gathering_run()
{
    global $session;
    page_header("Gathering Materials");
    $type = httpget('mat');
    $item = httpget('item');
    require_once "modules/staminasystem/lib/lib.php";
    if ($type == "wood") {
        $lv = process_action("Logging");
        $stam = get_stamina();
        $rstam = get_stamina(0);
        $failchance = e_rand(0, 99);
        if ($failchance < $stam) {
            give_item("wood");
            use_item($item, "logging");
            output("`0You hack away until you have what can only be described as a bloody enormous log, suitable as a part of a quaint little cabin.  It couldn't possibly fit into your backpack, but you stuff it in anyway.`n");
            if ($lv['lvlinfo']['levelledup'] == true) {
                output("`n`c`b`0You gained a level in Logging!  You are now level %s!  This action will cost fewer Stamina points now, so you can lumberjack more lumber each day!`b`c`n", $lv['lvlinfo']['newlvl']);
            }
        } else {
            if ($failchance < $rstam) {
                output("You hack away until you have what can only be described as a whole shitload of matchsticks.  The wood just splintered into barely more than pulp under your clumsy, half-asleep paws.`n`nMaybe it'd be a good idea to rest a bit before you try this again.`n`n");
            } else {
                $fail = 1;
                output("You hack away at the tree, your half-asleep mind blissfully ignorant of its wild swaying.  Ignorant, that is, until it falls on you.`n`nYou wake up, naturally, on the FailBoat.`n`n");
            }
        }
    } else {
        if ($type == "stone") {
            $lv = process_action("Stonecutting");
            $stam = get_stamina();
            $rstam = get_stamina(0);
            $failchance = e_rand(0, 99);
            if ($failchance < $stam) {
                $success = 1;
                give_item("stone");
                use_item($item, "stonecutting");
                output("`0You hack away until you have what can only be described as a huge-ass lump of stone, very heavy and cumbersome.  For some reason your backpack seems like a really good place to put it.`n");
                if ($lv['lvlinfo']['levelledup'] == true) {
                    output("`n`c`b`0You gained a level in Stonecutting!  You are now level %s!  This action will cost fewer Stamina points now, so you can break more rocks each day!`b`c`n", $lv['lvlinfo']['newlvl']);
                }
            } else {
                if ($failchance < $rstam) {
                    output("You hack away until you have what can only be described as a whole shitload of gravel.  The rock just smashed into splinters under your clumsy, half-asleep paws.`n`nMaybe it'd be a good idea to rest a bit before you try this again.`n`n");
                } else {
                    $fail = 1;
                    output("You hack away at the rock, blissfully unaware that another, larger rock is being gently dislodged by your half-asleep ministrations.  Another, larger rock that happens to be balanced precariously on an outcrop just above your head.`n`nYou wake up, naturally, on the FailBoat.`n`n");
                }
            }
        }
    }
    if (!$fail) {
        items_world_map_gathering_showgather();
        addnav("Other");
        addnav("Show Inventory", "inventory.php?items_context=worldmap");
        addnav("Return to the World Map", "runmodule.php?module=worldmapen&op=continue");
    } else {
        $session['user']['hitpoints'] = 0;
        $session['user']['gold'] = 0;
        $session['user']['alive'] = 0;
        //set the user's location to the last place on the map they touched
        $session['user']['location'] = get_module_pref("lastCity", "worldmapen");
        addnav("Guess what happens now?");
        addnav("That's right.", "shades.php");
    }
    page_footer();
}
function eboy_run()
{
    global $session, $inventory;
    if (!isset($inventory)) {
        load_inventory();
    }
    page_header("eBoy's Trading Station");
    addnav("Buy Items");
    addnav("Sell Items");
    require_once "modules/cityprefs/lib.php";
    $cid = get_cityprefs_cityid("location", $session['user']['location']);
    $item = httpget('item');
    if ($item) {
        $curstock = get_item_setting("eboy_stock_" . $cid, $item);
        $curprice = get_item_setting("eboy_price_" . $cid, $item);
    }
    eboy_updateprices();
    $eboy_info = get_items_with_settings("eboy");
    if (httpget('op') == "start") {
        output("Already fearing the worst, you head into eBoy's Trading Station.`n`nYour fears are well-founded.  The place is packed with the heaving, sweaty bodies of the hardcore capitalist, shouting \"`iBuy, buy!`i\" and \"`iSell, sell!`i\" and \"`iPut down the chainsaw and let's talk about this!`i\"`n`neBoy himself - although you suspect that this place, like Mike's Chop Shop, is a franchise of which you'll find one in every outpost, so is his name really eBoy?  Whoever he is, he stands on an elevated section of floor behind a tall mahogany counter, grabbing money with one hand and tossing grenades and ration packs over his shoulder with the other.  His arms are a blur.  His speech is the unintelligible, rapid-fire gabble of a professional auctioneer.  His eyes bulge and swivel.  You know he's loving this.`n`n");
    }
    if (httpget('op') == "buy") {
        $pprice = httpget('price');
        if ($pprice == $curprice) {
            if ($curstock > 0) {
                give_item($item);
                $session['user']['gold'] -= $curprice;
                increment_item_setting("eboy_stock_" . $cid, -1, $item);
                output("You fight your way to the front of the crowd and shout your order up to eBoy, slapping your Requisition tokens down on the counter.  Before you can blink, your money is gone and the item you desired sits in its place.  You grab it hastily and stuff it into your backpack as eBoy turns to deal with the next customer.`n`n");
            } else {
                output("eBoy turns to you and gibbers.`n`n\"Sorrymatejustsoldthelastoneyougottabefasteritsthequickandthedeadaroundherepal.\"  He turns to the next customer in line, leaving you trying to piece together whatever it is that he just said.`n`n");
            }
        } else {
            output("You fight your way to the front of the crowd and shout your order up to eBoy, slapping your Requisition tokens down on the counter.  eBoy turns to you and gibbers.`n`n\"Idontmeantobefunnymatebutlookattheboardthepricehasjustbloodychangedagainyousureyoustillwannabuy?\"  After giving you exactly one microsecond to consider what the hell he just asked, he rolls his eyes and turns to the next customer in line.`n`n");
        }
    }
    if (httpget('op') == "sell") {
        $pprice = httpget('price');
        $requiredprefs = array("inventorylocation" => "main");
        $itemid = has_item($item, $requiredprefs);
        if ($pprice == $curprice) {
            delete_item($itemid);
            if ($curstock < 3) {
                $buy = round($curprice * 0.5);
            } else {
                $buy = round($curprice * 0.7);
            }
            $session['user']['gold'] += $buy;
            increment_item_setting("eboy_stock_" . $cid, 1, $item);
            output("You barge your way through the crowd like a battleship through an ice floe, and toss your item up to eBoy.  eBoy snatches the item out of the air with his left hand while tossing your Requisition tokens back at you with his right, and goes on to serve the next customer.`n`n");
        } else {
            output("You fight your way to the front of the crowd and shout your order up to eBoy, slapping your Requisition tokens down on the counter.  eBoy turns to you and gibbers.`n`n\"Idontmeatobefunnymatebutlookattheboardthepricehasjustbloodychangedagainyousureyoustillwannasell?\"  After giving you exactly one microsecond to consider what the hell he just asked, he rolls his eyes and turns to the next customer in line.`n`n");
        }
    }
    output("You look up above eBoy's head at the trading board, the values of each commodity displayed on a mechanical readout which clatters and changes constantly.`n`n");
    $sellable_inventory = array();
    foreach ($inventory as $itemid => $prefs) {
        if (!$prefs['carrieritem'] && $prefs['eboy'] && $prefs['inventorylocation'] == "main") {
            $sellable_inventory[$prefs['item']]['quantity'] += 1;
            $sellable_inventory[$prefs['item']]['itemids'][] = $itemid;
        }
    }
    eboy_updateprices();
    $eboy_info = get_items_with_settings("eboy");
    //inventory-type display routine
    rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
    $classcount = 1;
    foreach ($eboy_info as $item => $settings) {
        if ($settings['eboy_stock_' . $cid] > 0) {
            $stock = number_format($settings['eboy_stock_' . $cid]) . " available";
        } else {
            $stock = "`4Sold Out`0";
        }
        $classcount++;
        $class = $classcount % 2 ? "trdark" : "trlight";
        rawoutput("<tr class='{$class}'><td>");
        if ($settings['image']) {
            rawoutput("<table width=100% cellpadding=0 cellspacing=0><tr><td width=100px align=center><img src=\"images/items/" . $settings['image'] . "\"></td><td>");
        }
        output("`b%s`b`n", stripslashes($settings['verbosename']));
        output("%s`n", stripslashes($settings['description']));
        if ($settings['weight']) {
            output("Weight: %s kg`n", $settings['weight']);
        }
        rawoutput("<table width=100%><tr><td width=50%>");
        output("`bStock:`b %s", $stock);
        if ($settings['eboy_stock_' . $cid] < 3) {
            $buy = round($settings['eboy_price_' . $cid] * 0.5);
        } else {
            $buy = round($settings['eboy_price_' . $cid] * 0.7);
        }
        if ($settings['eboy_price_' . $cid] > 0) {
            output("`n`7Buying at: %s Requisition", number_format($buy));
        } else {
            output("`nNot Buying");
        }
        if ($settings['eboy_stock_' . $cid] > 0) {
            output("`n`2Selling at: %s Requisition`n`n", number_format($settings['eboy_price_' . $cid]));
        } else {
            output("`n`n");
        }
        rawoutput("</td><td width=50%>");
        $requiredprefs = array("inventorylocation" => "main");
        if ($sellable_inventory[$item]) {
            addnav("Sell Items");
            if ($settings['eboy_stock_' . $cid] < 3) {
                $buy = round($settings['eboy_price_' . $cid] * 0.5);
            } else {
                $buy = round($settings['eboy_price_' . $cid] * 0.7);
            }
            if ($sellable_inventory[$item]['quantity'] > 0 && $settings['eboy_price_' . $cid] > 0) {
                addnav(array("%s (%s available)", $settings['verbosename'], $sellable_inventory[$item]['quantity']), "runmodule.php?module=eboy&op=sell&item=" . $item . "&price=" . $settings['eboy_price_' . $cid], true);
                addnav("", "runmodule.php?module=eboy&op=sell&item=" . $item . "&price=" . $settings['eboy_price_' . $cid]);
                rawoutput("<a href=\"runmodule.php?module=eboy&op=sell&item=" . $item . "&price=" . $settings['eboy_price_' . $cid] . "\">Sell for <strong>" . number_format($buy) . " </strong> Requisition (" . $sellable_inventory[$item]['quantity'] . " available to sell)</a><br />");
            }
        } else {
            output("`&You don't have any of this item to sell.`0`n");
        }
        if ($session['user']['gold'] >= $settings['eboy_price_' . $cid] && $settings['eboy_stock_' . $cid]) {
            addnav("Buy Items");
            addnav(array("%s (%s Req)", $settings['verbosename'], $settings['eboy_price_' . $cid]), "runmodule.php?module=eboy&op=buy&item=" . $item . "&price=" . $settings['eboy_price_' . $cid], true);
            addnav("", "runmodule.php?module=eboy&op=buy&item=" . $item . "&price=" . $settings['eboy_price_' . $cid]);
            rawoutput("<a href=\"runmodule.php?module=eboy&op=buy&item=" . $item . "&price=" . $settings['eboy_price_' . $cid] . "\">Buy for <strong>" . number_format($settings['eboy_price_' . $cid]) . "</strong> Requisition</a><br />");
        } else {
            if (!$settings['eboy_stock_' . $cid]) {
                output("`&There are no items of this type available.`0`n");
            } else {
                $difference = $settings['eboy_price_' . $cid] - $session['user']['gold'];
                output("`&You need another %s Requisition to buy this item.`0`n", number_format($difference));
            }
        }
        rawoutput("</td></tr></table>");
        if ($settings['image']) {
            rawoutput("</td></tr></table>");
        }
        rawoutput("</td></tr>");
    }
    rawoutput("</td></tr></table>");
    addnav("Leave");
    addnav("Return to the Outpost", "village.php");
    addnav("Inventory");
    addnav("View your Inventory", "inventory.php?items_context=eboy");
    //set_module_objpref("city",$cid,"eboytrades-intelligent",serialize($info));
    page_footer();
    return true;
}
function giftbox_use($args)
{
    global $session;
    debug($args);
    $cname = get_item_pref("verbosename", $args['giftbox_contains']);
    output("`0You open up the box to find a %s!`0`n`n", $cname);
    if (get_item_pref("inventorylocation", $args['giftbox_contains']) == "lodgebag") {
        if (!has_item("lodgebag")) {
            give_item("lodgebag");
        }
    } else {
        clear_item_pref("inventorylocation", $args['giftbox_contains']);
    }
    change_item_owner($args['giftbox_contains'], $session['user']['acctid']);
    return $args;
}
function giftstation_run()
{
    global $session;
    page_header("The Gifting Station");
    $op = httpget('op');
    $points = $session['user']['donation'] - $session['user']['donationspent'];
    switch ($op) {
        case "start":
            if (httpget("subop") == "continue") {
                output("The KittyMorph shows you a big smile.  \"`1Okay, that'll be delivered first thing in the morning.  Should make for a nice surprise when they wake up.  Anyone else you'd like to send a gift to?`0\"`n`n");
                $player = httpget('player');
                $itemid = httpget('item');
                $box = httpget('box');
                $free = httpget('free');
                $anonymous = httpget('anonymous');
                $boxid = give_item($box, false, "giftstation_" . $player);
                //	debug($boxid);
                //	debug($itemid);
                change_item_owner($itemid, $boxid);
                set_item_pref("giftbox_contains", $itemid, $boxid);
                if (!$anonymous) {
                    $desc = get_item_pref("description", $boxid);
                    $desc .= "`nThere's a gift tag attached to the box, telling you that this present came from " . $session['user']['name'] . "`0.";
                    set_item_pref("description", $desc, $boxid);
                }
                //notify player that they've got something awesome waiting for them
                require_once "lib/systemmail.php";
                $body = "Someone has used the Gifting Station in Common Ground to send you something.  Whatever it is, it'll turn up on your next new Game Day.";
                systemmail($player, "Someone sent you something awesome!", $body);
                if (!$free) {
                    $session['user']['donationspent'] += 1;
                    //log purchase
                    $sql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','giftstation_giftwrap','1','none','0','" . date("Y-m-d H:i:s") . "')";
                    $points = $session['user']['donation'] - $session['user']['donationspent'];
                }
                addnav("No, I think that'll do, thanks.", "gardens.php");
            } else {
                if (httpget("subop") == "searchagain") {
                    output("The KittyMorph nods, scratching out the contestant's name on his clipboard.  \"`1No problem.  Let's take it from the top.`0\"`n`n");
                    addnav("Actually, forget the whole thing.", "gardens.php");
                } else {
                    output("`0You head into the Gift Exchange.  A black-furred KittyMorph stands behind a counter.`n`n\"`1Hey there!`0\" he says.  \"`1As part of our continued diplomatic efforts, we provide a gift-wrapping service for items you'd like to send to your fellow contestants.  Interested?`0\"`n`n");
                    output("It costs one Supporter Point to gift-wrap and transfer (nearly) any item to any player.  Some items can be transferred for free.  You currently have %s Supporter Points.`n`n", number_format($points));
                    addnav("No thanks.", "gardens.php");
                }
            }
            if ($points > 0) {
                output("Search below for a player to send a present to.");
                rawoutput("<form action='runmodule.php?module=giftstation&op=findplayer' method='post'>");
                rawoutput("<input name='name'>");
                rawoutput("<input type='submit' class='button' value='" . translate_inline("search") . "'>");
                rawoutput("</form>");
                addnav("", "runmodule.php?module=giftstation&op=findplayer");
            } else {
                output("You don't have any Supporter Points!`n`n");
            }
            break;
        case "findplayer":
            $search = "%";
            $n = httppost('name');
            for ($x = 0; $x < strlen($n); $x++) {
                $search .= substr($n, $x, 1) . "%";
            }
            $search = " AND name LIKE '" . addslashes($search) . "' ";
            $uid = $session['user']['uniqueid'];
            $lastip = $session['user']['lastip'];
            $sql = "SELECT uniqueid, acctid, name FROM " . db_prefix("accounts") . " WHERE locked=0 {$search} ORDER BY name DESC ";
            $result = db_query($sql);
            output("The KittyMorph nods.  \"`1Okay, let's have a look at who I've got written down here whose name sounds like that...`0\"`n`n");
            $matches = 0;
            for ($i = 0; $i < db_num_rows($result); $i++) {
                $row = db_fetch_assoc($result);
                if ($row['uniqueid'] != $session['user']['uniqueid']) {
                    addnav("", "runmodule.php?module=giftstation&op=chooseitem&player=" . $row['acctid']);
                    output_notl("<a href='runmodule.php?module=giftstation&op=chooseitem&player=" . $row['acctid'] . "'>" . $row['name'] . "</a>", true);
                    output("`n");
                    $matches++;
                }
            }
            if ($matches == 0) {
                output("He looks down at his list.  \"`1Oh.  Actually, it doesn't look like there's `ianyone`i matching that description who you can send a present to.  Bummer.  Wanna try that again?`0\"");
            }
            addnav("Return to Common Ground", "gardens.php");
            addnav("Search Again", "runmodule.php?module=giftstation&op=start");
            break;
        case "chooseitem":
            $player = httpget('player');
            output("The KittyMorph reaches below his counter and brings up a clipboard on which he writes down the name of your nominated contestant.  \"`1Okay, I've got the name - now, what would you like to send?`0\"`n`n");
            $giftables = get_items_with_prefs("giftable");
            if ($giftables) {
                $giftables = group_items($giftables);
                foreach ($giftables as $sortid => $prefs) {
                    $itemid = $prefs['itemid'];
                    if ($prefs['freegift']) {
                        addnav("Send for free");
                        addnav(array("%s (%s available)", $prefs['verbosename'], $prefs['quantity']), "runmodule.php?module=giftstation&op=choosewrapping&item={$itemid}&player={$player}&free=1");
                    } else {
                        addnav("Send for one Supporter Point");
                        addnav(array("%s (%s available)", $prefs['verbosename'], $prefs['quantity']), "runmodule.php?module=giftstation&op=choosewrapping&item={$itemid}&player={$player}&free=0");
                    }
                }
                addnav("Cancel?");
                addnav("Wait, I've changed my mind.  Let's back up a step.", "runmodule.php?module=giftstation&op=start&subop=searchagain");
                addnav("Actually, forget the whole thing.", "gardens.php");
            } else {
                output("You realise that you have nothing that you can give away.  You shrug your shoulders and give the KittyMorph a big, silly grin.`n`n");
                addnav("This is awkward.");
                addnav("Run out of the shop.  Just run.", "gardens.php");
            }
            break;
        case "choosewrapping":
            $player = httpget('player');
            $itemid = httpget('item');
            $free = httpget('free');
            output("The KittyMorph nods, taking the item from you and beginning to wrap it in tissue paper.  \"`1They should be pleased with that.  Care to choose a box, while I wrap this up?`0\"`n`nClick on any box to confirm the gift.`n`n");
            $boxes = get_items_with_settings("giftwrap");
            foreach ($boxes as $boxid => $prefs) {
                $img = $prefs['image'];
                rawoutput("<a href='runmodule.php?module=giftstation&op=chooseanonymous&player={$player}&item={$itemid}&box={$boxid}&free={$free}'><img src='images/items/{$img}'></a>");
                addnav("", "runmodule.php?module=giftstation&op=chooseanonymous&player={$player}&item={$itemid}&box={$boxid}&free={$free}");
            }
            addnav("Cancel?");
            addnav("Wait, I've changed my mind.  Let's back up a step.", "runmodule.php?module=giftstation&op=start&subop=searchagain");
            addnav("Actually, forget the whole thing.", "gardens.php");
            break;
        case "chooseanonymous":
            $player = httpget('player');
            $itemid = httpget('item');
            $free = httpget('free');
            $box = httpget('box');
            output("The KittyMorph ties a ribbon around the box before reaching below the counter and bringing up a gift tag and a preposterously flamboyant quill pen.`n`n\"`1So, is this an anonymous gift, or would you like your name on it?`0\"`n`n");
            addnav("Anonymous or not?");
            addnav("Tell them who it's from", "runmodule.php?module=giftstation&op=start&subop=continue&player={$player}&item={$itemid}&box={$box}&free={$free}");
            addnav("Give anonymously", "runmodule.php?module=giftstation&op=start&subop=continue&player={$player}&item={$itemid}&box={$box}&free={$free}&anonymous=true");
            break;
    }
    page_footer();
    return true;
}
function rail_collector_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "newday":
            set_module_pref("cardstoday", 0);
            $wherefound = array();
            set_module_pref("wherefound", serialize($wherefound));
            // calculate cardluck:
            // (we do it this way to have better control over the shape of the curve - bell is too generous)
            $c0 = get_module_setting("cardluckchance0");
            $c2 = get_module_setting("cardluckchance2");
            $c3 = get_module_setting("cardluckchance3");
            $c4 = get_module_setting("cardluckchance4");
            // a little paranoia never hurt anyone
            $c1 = 100 - $c0 - $c2 - $c3 - $c4;
            if ($c1 <= 0) {
                // the module settings are fubar'd. Go with the defaults
                $c0 = 5;
                $c1 = 60;
                $c2 = 25;
                $c3 = 5;
            }
            $t0 = $c0;
            $t1 = $t0 + $c1;
            $t2 = $t1 + $c2;
            $t3 = $t2 + $c3;
            $d100 = e_rand(1, 100);
            switch ($d100) {
                case $d100 <= $t0:
                    $luck = 0;
                    break;
                case $d100 <= $t1:
                    $luck = 1;
                    break;
                case $d100 <= $t2:
                    $luck = 2;
                    break;
                case $d100 <= $t3:
                    $luck = 3;
                    break;
                default:
                    $luck = 4;
            }
            set_module_pref("cardluck", $luck);
            if (rail_hascard("cardcase")) {
                if ($luck == 0) {
                    output("`2Something seems out of kilter today, you're not sure what.`0`n");
                }
                if ($luck >= 3) {
                    output("`2You feel very lucky today! Wonderful things might happen to you.`0`n");
                }
            }
            // award rail passes:
            $val = rail_collector_valuehand();
            if (!$val['firstclass'] && $val['value'] > 0) {
                // no Joker, so give them however many regular rail passes they are entitled to:
                for ($i = 0; $i < $val['value']; $i++) {
                    give_item("railpass");
                }
                // empty their hand (and if they had more than 5 cards, well... tough.)
                $qty = rail_collector_emptyhand();
                if ($val['value'] == 1) {
                    $phrase = "an `bImprobable Island Railway Company RAIL PASS`b";
                } else {
                    $phrase = "not just one, but `b" . $val['value'] . " Improbable Island Railway Company RAIL PASSES`b";
                }
                output("`2Uh-oh, your card case feels much lighter. You had %s valuable cards here and they've all been bloody `istolen!`i Filthy midget bast-- wait, what? What's this? In their place, you now have %s! Awesome! ...um, so maybe it wasn't midgets after all. Critical mass, improbability, whatever. Who cares!`0`n", $qty, $phrase);
            }
            // end - awarding of rail passes
            break;
            // end case 'newday'
        // end case 'newday'
        case "iitems_tradables-top":
            // remove any rail-feature tradables (ie, cards) if recipient has no card case.
            if (has_item("cardcase", false, $args['tradewith']['acctid']) === false) {
                $playerhascards = false;
                if (is_array($args['tradables'])) {
                    foreach ($args['tradables'] as $tkey => $tdetails) {
                        if ($tdetails['feature'] == "rail") {
                            $playerhascards = true;
                            unset($args['tradables'][$tkey]);
                        }
                    }
                }
                if ($playerhascards) {
                    output("Unfortunately, %s has no place to put any cards.`n`n", $args['tradewith']['name']);
                }
            }
            break;
            // end case 'iitems_tradables-top'
        // end case 'iitems_tradables-top'
        case "improbablehousing_interior":
            $hid = $args['hid'];
            $rid = $args['rid'];
            $locs = rail_collector_getlocs();
            $collectspot = 0;
            $key = "unknown";
            $phrase = "in a shadowy corner of the room";
            foreach ($locs as $loc => $locarray) {
                if ($hid == $locarray[0] && $rid == $locarray[1]) {
                    // We're in a place where a card could be found
                    $collectspot = 1;
                    $key = $loc;
                    $phrase = $locarray[2];
                    break;
                    // no need to keep looking through the rest of the array
                }
            }
            if ($collectspot) {
                // not allowed to find more than one card in a location
                $wherefound = unserialize(get_module_pref("wherefound"));
                $foundhere = 0;
                if (is_array($wherefound)) {
                    foreach ($wherefound as $lc => $larray) {
                        if ($larray[0] == $hid && $larray[1] == $rid) {
                            // woops, they already found a card in this location today
                            $foundhere = 1;
                        }
                    }
                }
                if (!$foundhere) {
                    debug("finding card?");
                    // all right, let them try their luck
                    if (rail_collector_findcard()) {
                        $wherefound[$key] = array($hid, $rid);
                        set_module_pref("wherefound", serialize($wherefound));
                        output("`2What luck! You find a smudged, battered old playing card %s. You've heard these can be worth quite a bit to a collector. Carefully you tuck it away in your fine leather card case.`0`n`n", $phrase);
                    }
                } else {
                    debug("Player has already found a card here.");
                }
            }
            break;
    }
    // end $hookname switch
    return $args;
}
function iitems_hunterslodge_run()
{
    global $session;
    page_header("Hunter's Lodge");
    $op = httpget('op');
    $pointsleft = $session['user']['donation'] - $session['user']['donationspent'];
    $pointstotal = $session['user']['donation'];
    $pointsspent = $session['user']['donationspent'];
    switch ($op) {
        case "superuser":
            $sql = "SELECT * FROM " . db_prefix("purchaselog");
            $result = db_query($sql);
            $peritem = array();
            $now = time();
            while ($row = db_fetch_assoc($result)) {
                $item = $row['purchased'];
                $peritem[$item]['sold'] += 1;
                $peritem[$item]['income'] += $row['amount'];
                $time = strtotime($row['timestamp']);
                if (isset($peritem[$item]['firstpurchase']) && $peritem[$item]['firstpurchase'] > $time) {
                    $peritem[$item]['firstpurchase'] = $time;
                } else {
                    if (!isset($peritem[$item]['firstpurchase'])) {
                        $peritem[$item]['firstpurchase'] = $time;
                    }
                }
            }
            foreach ($peritem as $item => $data) {
                $timesincefirst = $now - $data['firstpurchase'];
                $incomeperday = round($data['income'] / ($timesincefirst / 86400) / 100, 2);
                $peritem[$item]['incomeperday'] = $incomeperday;
                $peritem[$item]['item'] = $item;
            }
            function sortbysold($a, $b)
            {
                if ($b['sold'] > $a['sold']) {
                    return true;
                } else {
                    return false;
                }
            }
            function sortbyincome($a, $b)
            {
                if ($b['income'] > $a['income']) {
                    return true;
                } else {
                    return false;
                }
            }
            function sortbydailyincome($a, $b)
            {
                if ($b['incomeperday'] > $a['incomeperday']) {
                    return true;
                } else {
                    return false;
                }
            }
            rawoutput("<table width=100% border=0 cellpadding=0 cellspacing=0><tr class='trhead'><td>Item</td><td>Item Verbose Name</td><td><a href='runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbysold'>Units sold</a></td><td><a href='runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbyincome'>Profit total</a></td><td><a href='runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbydailyincome'>Profit per day</a></td></tr>");
            $classcount = 1;
            addnav("", "runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbysold");
            addnav("", "runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbyincome");
            addnav("", "runmodule.php?module=iitems_hunterslodge&op=superuser&sort=sortbydailyincome");
            if (httpget('sort')) {
                usort($peritem, httpget('sort'));
            }
            foreach ($peritem as $item => $data) {
                $classcount++;
                $class = $classcount % 2 ? "trdark" : "trlight";
                $vname = get_item_setting("verbosename", $data['item']);
                if (!$vname) {
                    $vname = $data['item'];
                }
                rawoutput("<tr class='{$class}'><td>" . $data['item'] . "</td><td>" . $vname . "</td><td>" . number_format($data['sold']) . "</td><td>\$" . number_format($data['income'] / 100, 2) . "</td><td>\$" . number_format($data['incomeperday'], 2) . "</td></tr>");
            }
            rawoutput("</table>");
            addnav("Return");
            addnav("Back to the Grotto", "superuser.php");
            break;
        case "explain":
            output("You give a friendly nod to the proprietor, and open your mouth to ask him a question.`n`nHe grins back at you.`n`nThere's a small `ipop`iping sensation in the centre of your skull, like a muscle abruptly shifting - and you suddenly realise what this place is all about.`n`n`bAbout Supporter Points`b`nImprobable Island is entirely funded by donations from its players.  When you donate, you get Supporter Points, which you can use on items in the Hunter's Lodge.  You get one hundred Supporter Points per US Dollar, and donations are accepted through PayPal.  To donate, click the coin slot to the lower right of your screen.  Always use the \"Site Admin\" PayPal button when donating if you wish to receive Supporter Points (donations made through the \"Author\" button go to Eric Stevens, the author of the game engine on which Improbable Island was originally based - you don't get any Supporter Points for donating through this button).  You can also get Supporter Points by referring new players to the site (click the Referrals link to the left) or sometimes in `4Other Ways`0 which will be announced from time to time.`n`n`bTo give presents`b`nAll Hunter's Lodge items (and most other in-game items) can be given as gifts to other players.  Visit the Gifting Station in Common Ground to do so.  Some items can be gifted for free - others cost one Supporter Point each to gift.  Hunter's Lodge items that bestow permanent benefits (IE unlimited title change documents) can only be gifted if they're unused.  In all cases, you'll get to choose your gift-wrap and whether to give anonymously or not.`n`n`bHey, it's my birthday soon.  Can I ask my non-Island-playing mates to buy me points on the Island?`b`nYes!  Just send them to this link:`nhttp://www.improbableisland.com/runmodule.php?module=giftpoints&acctid=%s`n`n", $session['user']['acctid']);
            addnav("Okay");
            addnav("Back to the Hunter's Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            addnav("Referrals", "runmodule.php?module=iitems_hunterslodge&op=referrals");
            break;
        case "referrals":
            output("If you help bring new players to Improbable Island, you'll earn one Supporter Point every time those players hit a new Game Day.  To refer players, use this address:`n`n");
            $url = getsetting("serverurl", "http://" . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] == 80 ? "" : ":" . $_SERVER['SERVER_PORT']) . dirname($_SERVER['REQUEST_URI']));
            if (!preg_match("/\\/\$/", $url)) {
                $url = $url . "/";
                savesetting("serverurl", $url);
            }
            output_notl("%shome.php?r=%s`n`n", $url, rawurlencode($session['user']['login']));
            $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE referer={$session['user']['acctid']} ORDER BY dragonkills,level";
            $result = db_query($sql);
            $number = db_num_rows($result);
            if ($number) {
                output("Accounts you've referred:`n");
                for ($i = 0; $i < $number; $i++) {
                    $row = db_fetch_assoc($result);
                    output_notl("%s`0`n", $row['name']);
                }
            }
            addnav("Okay");
            addnav("Back to the Hunter's Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
        case "start":
            output("You head into the Hunter's Lodge.  It's a bright, shiny place, with many expensive-looking items arranged inside glass cabinets.  The proprietor, a snappily-dressed male Joker, grins at you from behind the counter.`n`n");
            if (!has_item("lodgebag")) {
                output("The joker silently hands you a small bag, with a look that suggests you put your purchases inside.`n`n");
                give_item("lodgebag");
            }
            output("`0You have `b`5%s`0`b Supporter Points left, out of `5%s`0 accumulated in total.`n`n", number_format($pointsleft), number_format($pointstotal));
            addnav("What's all this about, then?");
            addnav("How do I get supporter points, or give presents to people?", "runmodule.php?module=iitems_hunterslodge&op=explain");
            $lodgeitems = get_items_with_settings("lodge");
            //debug($lodgeitems);
            rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
            $boughtitems = array();
            $sql = "SELECT * FROM " . db_prefix("purchaselog") . " WHERE acctid = '" . $session['user']['acctid'] . "'";
            $result = db_query($sql);
            while ($row = db_fetch_assoc($result)) {
                $boughtitems[$row['purchased']] = 1;
            }
            foreach ($lodgeitems as $key => $vals) {
                if (!$vals['lodge']) {
                    continue;
                }
                $classcount += 1;
                $class = $classcount % 2 ? "trdark" : "trlight";
                rawoutput("<tr class='{$class}'><td>");
                if ($vals['image']) {
                    rawoutput("<table width=100% cellpadding=0 cellspacing=0><tr><td width=100px align=center><img src=\"images/items/" . $vals['image'] . "\"></td><td>");
                }
                output("`b%s`b`n", stripslashes($vals['verbosename']));
                output("%s`0`n", stripslashes($vals['description']));
                if ($vals['weight']) {
                    output("Weight: %s kg`n`0", $vals['weight']);
                }
                rawoutput("<table width=100%><tr><td width=50%>");
                if ($vals['tradable']) {
                    output("`5Giftable Item`0`n");
                }
                if ($vals['lodge_cost']) {
                    $disp = "`b`5" . number_format($vals['lodge_cost']) . "`0`b Supporter Points";
                    $sdisp = $vals['lodge_cost'] . " Points";
                    output("Price: %s`n", $disp);
                    if ($vals['lodge_limited']) {
                        output("`4Limited Item`0: %s available`n", $vals['lodge_stock']);
                    }
                }
                if ($vals['lodge_limited'] && $vals['lodge_stock'] > 0 || !$vals['lodge_limited']) {
                    if ($vals['lodge_singlebuy'] && $boughtitems[$key]) {
                        output("`7You've already obtained and used this item.  No need to get it again!`n");
                    } else {
                        if ($pointstotal >= $vals['lodge_freebie_threshold'] && $vals['lodge_freebie_threshold']) {
                            output("`2This item is now `bfree`b!`0`n");
                            addnav("", "runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key . "&freebie=true");
                            rawoutput("<a href=\"runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key . "&freebie=true\">Get it!</a><br />");
                        } else {
                            if ($vals['lodge_freebie_threshold']) {
                                output("`2This item becomes free once you have accumulated more than %s Supporter Points, spent or unspent.`0`n", $vals['lodge_freebie_threshold']);
                            }
                            if ($pointsleft >= $vals['lodge_cost']) {
                                addnav("Buy Items");
                                addnav(array("%s (%s)", stripslashes($vals['verbosename']), $sdisp), "runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key, true);
                                addnav("", "runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key);
                                rawoutput("<a href=\"runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key . "\">More Details / Buy for " . appoencode($disp) . "</a><br />");
                            } else {
                                output("`&You need another %s Supporter Points for this item.`0`n", number_format($vals['lodge_cost'] - $pointsleft));
                                addnav("", "runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key . "&cannotafford=1");
                                rawoutput("<a href=\"runmodule.php?module=iitems_hunterslodge&op=buy&item=" . $key . "&cannotafford=1\">More Details</a><br />");
                            }
                        }
                    }
                } else {
                    output("`&Sold out!`0`n");
                }
                rawoutput("</td></tr></table>");
                if ($vals['image']) {
                    rawoutput("</td></tr></table>");
                }
                rawoutput("</td></tr>");
            }
            rawoutput("</td></tr></table>");
            modulehook("hunterslodge");
            break;
        case "buy":
            $itemid = httpget("item");
            $item = get_item_settings($itemid);
            $free = httpget("freebie");
            $cannotafford = httpget("cannotafford");
            //debug($item);
            if ($item['lodge_longdesc']) {
                output_notl("`0%s`0`n`n", stripslashes($item['lodge_longdesc']));
            }
            if (!$cannotafford) {
                if (!$free) {
                    output("You're about to buy a %s for %s Supporter Points, leaving you with %s points available to spend afterwards.`n`n", $item['verbosename'], number_format($item['lodge_cost']), number_format($pointsleft - $item['lodge_cost']));
                    addnav("Confirm");
                    addnav(array("Buy %s for %s Points", stripslashes($item['verbosename']), $item['lodge_cost']), "runmodule.php?module=iitems_hunterslodge&op=buyconfirm&item={$itemid}");
                    addnav("No, I don't want to do that!");
                    addnav("Back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
                } else {
                    redirect("runmodule.php?module=iitems_hunterslodge&op=buyconfirm&item={$itemid}&freebie=true");
                }
            } else {
                output("`0You need another %s Supporter Points to get this item.`0`n`n", number_format($item['lodge_cost'] - $pointsleft));
                addnav("Okay");
                addnav("Back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
                addnav("How do I get supporter points?", "runmodule.php?module=iitems_hunterslodge&op=explain");
            }
            break;
        case "buyconfirm":
            $itemid = httpget("item");
            $iteminside = httpget("item_inside");
            $item = get_item_settings($itemid);
            $free = httpget("freebie");
            if (!$free) {
                $cost = $item['lodge_cost'];
                output("You have purchased a %s for %s Supporter Points.  You can find the item in your Inventory.  Thank you for your support!`n`n", $item['verbosename'], $item['lodge_cost']);
                give_item($itemid);
                $session['user']['donationspent'] += $item['lodge_cost'];
            } else {
                //handle freebie items
                give_item($itemid);
                output("`0You now have a %s`0!  Thank you for your support!`n`n", $item['verbosename']);
                $cost = 0;
            }
            if ($item['lodge_limited']) {
                increment_item_setting("lodge_stock", -1, $itemid);
            }
            //log purchase
            $sql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','" . $itemid . "','" . $cost . "','" . addslashes(serialize($item)) . "','" . $wrap . "','" . date("Y-m-d H:i:s") . "')";
            //debug($sql);
            db_query($sql);
            addnav("Yay!");
            addnav("Back to the Hunter's Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
    }
    addnav("Leave");
    addnav("Return to the Outpost", "village.php");
    addnav("Inventory");
    addnav("View your Inventory", "inventory.php?items_context=lodge");
    page_footer();
    return true;
}
function meatsystem_run()
{
    global $session;
    require_once "modules/staminasystem/lib/lib.php";
    page_header("Meat!");
    addnav("Meat Skills");
    $from = httpget('from');
    switch (httpget('op')) {
        case "devour":
            //special ability for Zombies only - Zombies can eat raw meat, so we're giving them the ability to simply devour the carcass where it lies.
            $carcasses = unserialize(get_module_pref("carcasses"));
            if (!is_array($carcasses)) {
                $carcasses = array();
            }
            debug($carcasses);
            foreach ($carcasses as $carcassnum => $creatureid) {
                $sql = "SELECT creaturename FROM " . db_prefix("creatures") . " WHERE creatureid = " . $creatureid . " ";
                $result = db_query_cached($sql, "creaturename-" . $creatureid, 86400);
                $creature = db_fetch_assoc($result);
                output("Giving in to your primal urges, you lean down and begin ripping meat from the still-twitching %s with your teeth.`n`n", $creature['creaturename']);
                $meat1 = get_module_objpref("creatures", $creatureid, "meat1");
                $meat2 = get_module_objpref("creatures", $creatureid, "meat2");
                $meat3 = get_module_objpref("creatures", $creatureid, "meat3");
                for ($i = 0; $i < $meat1; $i++) {
                    increment_module_pref("nutrition", 1, "staminafood");
                    increment_module_pref("fat", 3, "staminafood");
                    increment_module_pref("fullness", 1, "staminafood");
                    addstamina(1000);
                }
                for ($i = 0; $i < $meat2; $i++) {
                    increment_module_pref("nutrition", 2, "staminafood");
                    increment_module_pref("fat", 2, "staminafood");
                    increment_module_pref("fullness", 1, "staminafood");
                    addstamina(2000);
                }
                for ($i = 0; $i < $meat3; $i++) {
                    increment_module_pref("nutrition", 3, "staminafood");
                    increment_module_pref("fat", 1, "staminafood");
                    increment_module_pref("fullness", 1, "staminafood");
                    addstamina(5000);
                }
                output("For the record, and since it's nice to know these things even if you're too busy tearing cartilage and muscle from the bone to really pay attention to them, in this meal you have eaten %s bite's-worth of Crap Meat, %s bite's-worth of Half-Decent Meat, and %s bite's-worth of Tasty Meat.`n", $meat1, $meat2, $meat3);
                $full = get_module_pref("fullness", "staminafood");
                if ($full < 0) {
                    output("You still feel as though you haven't eaten in days.`n`n");
                }
                if ($full >= 0 && $full < 50) {
                    output("You feel a little less hungry.`n`n");
                }
                if ($full >= 50 && $full < 100) {
                    output("You still feel as though you've got room for more!`n`n");
                }
                if ($full >= 100) {
                    output("You're stuffed!  You feel as though you can't possibly eat anything more today.`n`n");
                }
                unset($carcasses[$carcassnum]);
                set_module_pref("carcasses", serialize($carcasses));
            }
            break;
        case "clean":
            $creatureid = httpget('creatureid');
            $carcass = httpget('carcass');
            $meat1 = get_module_objpref("creatures", $creatureid, "meat1");
            $meat2 = get_module_objpref("creatures", $creatureid, "meat2");
            $meat3 = get_module_objpref("creatures", $creatureid, "meat3");
            $amber = get_stamina();
            $return = process_action("Cleaning the Carcass");
            if ($return['lvlinfo']['levelledup'] == true) {
                output("`n`c`b`0You gained a level in Cleaning Carcasses!  You are now level %s!  This action will cost fewer Stamina points now, so you can butcher more creatures each day!`b`c`n", $return['lvlinfo']['newlvl']);
            }
            $failchance = e_rand(0, 100);
            if ($failchance > $amber) {
                //failure - the nice meat gets turned into Crap Meat
                $meat1 += $meat2;
                $meat1 += $meat3;
                output("`4You sit down to clean the carcass.  Your exhausted, clumsy incisions make a mockery of the choicest cuts - what is left over can only be described as Crap Meat.  %s bite's-worth, to be precise.  It looks like it was hacked into chunks by a blind woodsman.", $meat1);
                //todo
                for ($i = 0; $i < $meat1; $i++) {
                    give_item("meat_low", false, false, true);
                }
                load_inventory();
                $carcasses = unserialize(get_module_pref("carcasses"));
                unset($carcasses[$carcass]);
                $carcasses = array_values($carcasses);
                set_module_pref("carcasses", serialize($carcasses));
            } else {
                //success - all meat is sorted
                output("You spend a few minutes up to your elbows in gore, and getting rather hungry.`n");
                if ($meat1 > 0) {
                    output("You tear off enough to make %s rough bite's-worth of what the locals affectionately call Crap Meat.  It's mostly wobbling chunks of stinking yellow fat, intermingled with the occasional squirmy tendon.`n", $meat1);
                }
                if ($meat2 > 0) {
                    output("You make swift work of the fattier muscle, and before too long you have %s rough bite's-worth of Half-Decent Meat.`n", $meat2);
                }
                if ($meat3 > 0) {
                    output("The red, tender slivers of muscle slide easily from the bone, and you wind up with %s rough bite's-worth of Tasty Meat.`n", $meat3);
                }
                //todo
                for ($i = 0; $i < $meat1; $i++) {
                    give_item("meat_low", false, false, true);
                }
                for ($i = 0; $i < $meat2; $i++) {
                    give_item("meat_medium", false, false, true);
                }
                for ($i = 0; $i < $meat3; $i++) {
                    give_item("meat_high", false, false, true);
                }
                load_inventory();
                $carcasses = unserialize(get_module_pref("carcasses"));
                unset($carcasses[$carcass]);
                $carcasses = array_values($carcasses);
                set_module_pref("carcasses", serialize($carcasses));
                $pmeat1 = has_item("meat_low");
                $pmeat2 = has_item("meat_medium");
                $pmeat3 = has_item("meat_high");
                if (($pmeat1 || $pmeat2 || $pmeat3) && $session['user']['race'] != "Robot") {
                    if (get_module_pref("fullness", "staminafood") < 100) {
                        $cookcost = stamina_getdisplaycost("Cooking");
                        addnav(array("Cook up some meat (`Q%s%%`0)", $cookcost), "runmodule.php?module=meatsystem&op=cook&from=" . $from);
                    } else {
                        addnav("You're too full to cook, let alone eat", "");
                    }
                }
            }
            break;
        case "cook":
            $pmeat1qty = has_item_quantity("meat_low");
            $pmeat2qty = has_item_quantity("meat_medium");
            $pmeat3qty = has_item_quantity("meat_high");
            output("You whip out your camping stove.  It's time to cook!`n`nWhat will you put in the pan?  You can fit up to 20 bite's-worth of meat in there.  Right now you have %s bite's-worth of Crap Meat, %s bite's-worth of Half-Decent Meat, and %s bite's-worth of Tasty Meat.`n`n", $pmeat1qty, $pmeat2qty, $pmeat3qty);
            rawoutput("<form action='runmodule.php?module=meatsystem&op=cookfinal&from=" . $from . "' method='POST'>");
            rawoutput("Put in <input name='meat1' width='2' value='0'> bite's-worth of Crap Meat.<br />");
            rawoutput("Put in <input name='meat2' width='2' value='0'> bite's-worth of Half-Decent Meat.<br />");
            rawoutput("Put in <input name='meat3' width='2' value='0'> bite's-worth of Tasty Meat.<br />");
            rawoutput("<input type='submit' class='button' value='" . translate_inline("Cook!") . "'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=meatsystem&op=cookfinal&from=" . $from);
            break;
        case "cookfinal":
            $pmeat1qty = has_item_quantity("meat_low");
            $pmeat2qty = has_item_quantity("meat_medium");
            $pmeat3qty = has_item_quantity("meat_high");
            $meat1 = httppost("meat1");
            $meat2 = httppost("meat2");
            $meat3 = httppost("meat3");
            //check for the dumbass player cooking meat that they don't have
            if ($meat1 > $pmeat1qty || $meat2 > $pmeat2qty || $meat3 > $pmeat3qty) {
                output("You don't `ihave`i that much meat!`n`n");
                addnav("Whoops");
                addnav("Sorry, I forgot how to count for a second there.  Let's try this again.", "runmodule.php?module=meatsystem&op=cook&from=" . $from);
                break;
            }
            //check for the dumbass player inputting a negative number
            if ($meat1 < 0 || $meat2 < 0 || $meat3 < 0) {
                page_header("Either taking vegetarianism to whole new levels, or trying to grow meat from an empty pan");
                output("You want to cook `inegative`i meat?  How very Zen of you.`n`n");
                addnav("You sneaky bugger");
                addnav("Abandon your efforts to produce the opposite of meat and try again, pretending that you weren't just trying to cheat.", "runmodule.php?module=meatsystem&op=cook&from=" . $from);
                break;
            }
            //check for the dumbass player trying to put too much meat in the pan
            $totalmeat = $meat1 + $meat2 + $meat3;
            if ($totalmeat > 20) {
                output("Your pan can't hold that much meat, pal.`n`n");
                addnav("Whoops");
                addnav("Try again, without filling the pan up so much", "runmodule.php?module=meatsystem&op=cook&from=" . $from);
                break;
            }
            //check for the dumbass player trying to cook no meat at all
            $totalmeat = $meat1 + $meat2 + $meat3;
            if ($totalmeat == 0) {
                output("You start the process of cooking up your tasty meat.  After a few minutes of poking around in your pan, growing hungrier by the second, you realise that you've forgotten something.`n`n");
                addnav("Whoops");
                addnav("Try again, with meat this time", "runmodule.php?module=meatsystem&op=cook&from=" . $from);
                break;
            }
            //Stamina interaction, including consequences and level-up details.
            $amber = get_stamina();
            $return = process_action("Cooking");
            if ($return['lvlinfo']['levelledup'] == true) {
                output("`n`c`b`0You gained a level in Cooking!  You are now level %s!  This action will cost fewer Stamina points now, so you can cook more tasty meals each day!`b`c`n", $return['lvlinfo']['newlvl']);
            }
            $failchance = e_rand(0, 100);
            if ($failchance > $amber) {
                output("`4You put your meat into the pan, and sit down to stir-fry it.  The hypnotic motion and white-noise sizzling, combined with your tiredness, sends you staring into space.  While your concentration is impaired, the meat bursts into flames.  You jerk back into awareness, and look down sadly at the flaming chunks.  Bummer.");
                for ($i = 0; $i < $meat1; $i++) {
                    delete_item(has_item("meat_low"));
                }
                for ($i = 0; $i < $meat2; $i++) {
                    delete_item(has_item("meat_medium"));
                }
                for ($i = 0; $i < $meat3; $i++) {
                    delete_item(has_item("meat_high"));
                }
                break;
            }
            //we can now assume that the player is not some sort of cheating reprobate, or trying to cook while dog-tired, and do some cooking!
            for ($i = 0; $i < $meat1; $i++) {
                increment_module_pref("nutrition", 1, "staminafood");
                increment_module_pref("fat", 3, "staminafood");
                increment_module_pref("fullness", 1, "staminafood");
                delete_item(has_item("meat_low"));
                addstamina(1000);
            }
            for ($i = 0; $i < $meat2; $i++) {
                increment_module_pref("nutrition", 2, "staminafood");
                increment_module_pref("fat", 2, "staminafood");
                increment_module_pref("fullness", 1, "staminafood");
                delete_item(has_item("meat_medium"));
                addstamina(2000);
            }
            for ($i = 0; $i < $meat3; $i++) {
                increment_module_pref("nutrition", 3, "staminafood");
                increment_module_pref("fat", 1, "staminafood");
                increment_module_pref("fullness", 1, "staminafood");
                delete_item(has_item("meat_high"));
                addstamina(5000);
            }
            output("You fry up your lovely meaty loveliness, and sit down to eat.  You gain some Stamina!`n`n");
            $full = get_module_pref("fullness", "staminafood");
            if ($full < 0) {
                output("You still feel as though you haven't eaten in days.`n`n");
            }
            if ($full >= 0 && $full < 50) {
                output("You feel a little less hungry.`n`n");
            }
            if ($full >= 50 && $full < 100) {
                output("You still feel as though you've got room for more!`n`n");
            }
            if ($full >= 100) {
                output("You're stuffed!  You feel as though you can't possibly eat anything more today.`n`n");
            }
            break;
    }
    $carcasses = unserialize(get_module_pref("carcasses"));
    if (!is_array($carcasses)) {
        $carcasses = array();
    }
    if (count($carcasses) > 0) {
        output("You look at the spoils of your most recent battle.  They lie bloodied and broken on the ground.  What will you do with them?");
        foreach ($carcasses as $carcassnum => $creatureid) {
            $sql = "SELECT creaturename FROM " . db_prefix("creatures") . " WHERE creatureid = " . $creatureid . " ";
            $result = db_query_cached($sql, "creaturename-" . $creatureid, 86400);
            $creature = db_fetch_assoc($result);
            $cleancost = stamina_getdisplaycost("Cleaning the Carcass");
            addnav(array("Clean the carcass of %s (`Q%s%%`0)", $creature['creaturename'], $cleancost), "runmodule.php?module=meatsystem&op=clean&creatureid=" . $creatureid . "&carcass=" . $carcassnum . "&from=" . $from);
        }
    } else {
        if (httpget('op') != "cook" && httpget('op') != "cookfinal") {
            output("Now only bloody bones lie strewn around the area.`n`n");
        }
    }
    addnav("Ah, screw it.");
    if ($from == "forest") {
        addnav("Return to the Jungle", "forest.php");
    } else {
        if ($from == "world") {
            addnav("Return to the World Map", "runmodule.php?module=worldmapen&op=continue");
        }
    }
    page_footer();
    return true;
}
function rail_ironhorse_run()
{
    global $session;
    $op = httpget("op");
    $fromhid = httpget("hid");
    $fromrid = httpget("rid");
    $locs = rail_ironhorse_getlocs();
    switch ($op) {
        case "board":
            page_header("On the Train!");
            // Conductor walks through the train here
            if (rail_hascard("railpass_active") || rail_hascard("railpassfirst_active")) {
                // they already have a punched ticket - they're fine
                if (e_rand(1, 20) == 1) {
                    output("`2The `@Conductor `2lurches through the train again, examining passes, taking bribes, exchanging familiar nods with the regular riders.`0`n`n");
                }
            } else {
                if (rail_hascard("railpass") && rail_hascard("railpassfirst")) {
                    // they have both - we have to ask them which they want to use
                    output("`0The `@Conductor `0examines your passes. \"`2Why, you seem to have both regular and first class passes here. Which would you prefer to use today?`0\"`n`n");
                    addnav("Which pass will you use?");
                    addnav("Just the regular today, thanks", "runmodule.php?module=rail_ironhorse&op=choose&hid={$fromhid}&rid={$fromrid}&pass=reg");
                    addnav("It's first class for me, baby", "runmodule.php?module=rail_ironhorse&op=choose&hid={$fromhid}&rid={$fromrid}&pass=first");
                    page_footer();
                    break;
                } else {
                    // they have one or the other but not both - we can punch automatically
                    if (rail_hascard("railpass")) {
                        // they have a regular pass
                        output("`2The `@Conductor `2peers myopically at your Rail Pass and fumbles with a ticket punch. Ka-`btchik`b! Now you're free to ride the train as much as you want for the rest of the day!`0`n`n");
                        rail_ironhorse_activatepass("railpass");
                    } else {
                        // they have a first class pass
                        output("`2The `@Conductor `2inspects your First Class Rail Pass and deferentially produces a ticket punch. Ka-`btchik`b! Now you can ride `ifirst class`i for the rest of the day! Awesome!`0`n`n");
                        rail_ironhorse_activatepass("railpassfirst");
                    }
                }
            }
            $hookargs = array("hid" => $fromhid, "rid" => $fromrid);
            modulehook("ironhorse-onboard", $hookargs);
            set_module_pref("hasridden", 1);
            output("`2The wheels clatter, the car shakes with the astounding speed. Why, you must be going a good twenty-five miles an hour!`0`n`n");
            addnav("Get off!");
            foreach ($locs as $loc => $locarray) {
                if ($loc == "WA" || $loc == "DB") {
                } else {
                    if ($locarray[0] == $fromhid) {
                        addnav(array("`2Back to %s: `0%s", $loc, $locarray[2]), "runmodule.php?module=rail_ironhorse&op=leave&hid={$fromhid}&rid={$fromrid}&loc={$loc}");
                    } else {
                        addnav(array("`2%s: `0%s", $loc, $locarray[2]), "runmodule.php?module=rail_ironhorse&op=leave&hid={$fromhid}&rid={$fromrid}&loc={$loc}");
                    }
                }
            }
            if (rail_hascard("railpassfirst_active")) {
                addnav("First Class");
                addnav("Request Stop", "runmodule.php?module=rail_ironhorse&op=request&hid={$fromhid}&rid=fromrid");
            }
            addcommentary();
            viewcommentary("Riding the Train", "Shout over the engine's thunder:");
            page_footer();
            break;
        case "leave":
            page_header("You have reached your destination!");
            rail_ironhorse_cleanup($fromhid);
            switch (e_rand(1, 200)) {
                // where are we leaving to?
                case 1:
                    $loc = "WA";
                    break;
                case 2:
                    $loc = "DB";
                    break;
                default:
                    $loc = httpget("loc");
                    break;
            }
            $tohid = $locs[$loc][0];
            $torid = $locs[$loc][1];
            $house = improbablehousing_gethousedata($locs[$loc][0]);
            $tohousename = $house['data']['name'];
            set_module_pref("worldXYZ", $house['location'], "worldmapen");
            set_module_pref("lastCity", $locs[$loc][3], "worldmapen");
            $session['user']['location'] = "House: " . $tohousename . ", Room " . $torid . "";
            output("`0The `@Conductor `0smiles toothily as you prepare to disembark. \"`2Thank-you for travelling with the `bImprobable Island Railway Company`b. Please don't forget to take all your luggage with you, and have an improbable day!`0\"`n`n");
            output("`2%s`0`n`n", $locs[$loc][4]);
            addnav("Get off the train");
            addnav(array("`2%s`0 Platform", $locs[$loc][2]), "runmodule.php?module=improbablehousing&op=interior&hid={$tohid}&rid={$torid}");
            if (!($loc == "WA") && !($loc == "DB")) {
                addnav("Wait, I've changed my mind");
                addnav("`2Stay `0 on board", "runmodule.php?module=rail_ironhorse&op=board&hid={$tohid}&rid={$torid}");
            } else {
                output("`2You feel stronger after your pleasant train ride, and rather refreshed!`n`n`0");
                if ($session['user']['hitpoints'] < $session['user']['maxhitpoints']) {
                    $session['user']['hitpoints'] = $session['user']['maxhitpoints'];
                } else {
                    $session['user']['hitpoints'] = $session['user']['hitpoints'] * 1.1;
                    require_once "modules/staminasystem/lib/lib.php";
                    addstamina(25000);
                }
            }
            page_footer();
            break;
        case "request":
            page_header("First Class has its privileges!");
            output("`2As holder of an Improbable Island Railway Company `bFirst Class`b Rail Pass, you have the privilege of asking the train to let you off anywhere on the map. Yes, even in the deepest ocean, should that be your whim! This is, after all, an `iImprobable`i railway system; it can accomplish the seemingly impossible.`n`nSimply tell the `@Conductor `2where on the Island you would like to be dropped off.`0`n`n");
            rawoutput("<form action='runmodule.php?module=rail_ironhorse&op=requestfinish&hid=" . $fromhid . "&rid=" . $fromrid . "' method='POST'>");
            // Note: Width 2 means a 2-digit number. Set the default location to 13,11 Improbable Central.
            rawoutput("X = <input name='stopX' width='2' value='13'> , Y = <input name='stopY' width='2' value='11'><br/><br/>");
            rawoutput("<input type='submit' class='button' value='" . translate_inline("Stop here!") . "'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=rail_ironhorse&op=requestfinish&hid={$fromhid}&rid={$fromrid}");
            addnav("Wait, I've changed my mind");
            addnav("`2Stay `0 on board", "runmodule.php?module=rail_ironhorse&op=board&hid={$fromhid}&rid={$fromrid}");
            page_footer();
            break;
        case "requestfinish":
            page_header("First Class has its privileges!");
            $x = httppost("stopX");
            $y = httppost("stopY");
            // strip out any non-numeric characters that got entered by mistake
            $x = ereg_replace("[^0-9]", "", $x);
            $y = ereg_replace("[^0-9]", "", $y);
            // make sure they entered values that are in range for the size of the map.
            $sizeX = get_module_setting("worldmapsizeX", "worldmapen");
            $sizeY = get_module_setting("worldmapsizeY", "worldmapen");
            if ($x <= 0 || $x > $sizeX || $y <= 0 || $y > $sizeY) {
                output("`2Sorry mate, stay on the map. Train service doesn't run outside the Improbability bubble. Nice try though.`0");
                addnav("Oops!");
                addnav("Let's try that again", "runmodule.php?module=rail_ironhorse&op=request&hid={$fromhid}&rid={$fromrid}");
            } else {
                output("`0The `@Conductor `0smiles, all sleek and fangsome, as you prepare to disembark. \"`2Thank-you for travelling with the `bImprobable Island Railway Company`b. Please don't forget to take all your luggage with you, and have an improbable day!`0\"`n`n");
                rail_ironhorse_cleanup($fromhid);
                $maploc = $x . "," . $y . ",1";
                set_module_pref("worldXYZ", $maploc, "worldmapen");
                addnav("Thanks!");
                addnav("`2Leave `0 the train", "runmodule.php?module=worldmapen&op=continue");
            }
            page_footer();
            break;
        case "choose":
            $pass = httpget("pass");
            if ($pass == "first") {
                rail_ironhorse_activatepass("railpassfirst");
            } else {
                rail_ironhorse_activatepass("railpass");
            }
            addnav("", "runmodule.php?module=rail_ironhorse&op=board&hid={$fromhid}&rid={$fromrid}");
            redirect("runmodule.php?module=rail_ironhorse&op=board&hid={$fromhid}&rid={$fromrid}");
            break;
        case "stationmaster":
            page_header("The Stationmaster");
            $val = rail_collector_valuehand();
            // note, we only get here if there's a joker in the hand, so only first class passes
            if ($val['value'] > 2) {
                $phrase = "that's quite a hand you have there. Quite a hand! I think in this case we could even stretch to `b" . $val['value'] . "`b First Class Rail Passes.";
            } else {
                if ($val['value'] > 1) {
                    $phrase = "excellent. For that hand, we could easily give you `btwo`b First Class Rail Passes.";
                } else {
                    $phrase = "no question about it, definitely a `bFirst Class Rail Pass`b.";
                }
            }
            output("`2Having heard that this eccentric railroad company will sometimes give out a rail pass in exchange for used playing cards, you show the Stationmaster your grubby little collection. \"`#Interested?`2\" you ask.`n`n\"`^Why yes. Those would be worth... let me see. Oh, %s`2\"`0`n`n", $phrase);
            addnav("What do you say?");
            addnav("It's a deal!", "runmodule.php?module=rail_ironhorse&op=stationmasterdeal&hid={$fromhid}&rid={$fromrid}");
            addnav("No thanks, I'll wait", "runmodule.php?module=improbablehousing&op=interior&hid={$fromhid}&rid={$fromrid}");
            page_footer();
            break;
        case "stationmasterdeal":
            page_header("The Stationmaster");
            $val = rail_collector_valuehand();
            for ($i = 0; $i < $val['value']; $i++) {
                give_item("railpassfirst");
            }
            $qty = rail_collector_emptyhand();
            output("`2The Stationmaster thanks you, and the two of you make the exchange to your mutual satisfaction. What on earth the Company `iwants`i with all those old playing cards... well. You've naturally wondered about that from time to time, but they're not saying.`0`n`n");
            addnav("Leave");
            addnav("Return to the platform", "runmodule.php?module=improbablehousing&op=interior&hid={$fromhid}&rid={$fromrid}");
            page_footer();
            break;
    }
}
function mementos_run()
{
    global $session;
    page_header("Memento Forge");
    $op = httpget('op');
    $pointsavailable = $session['user']['donation'] - $session['user']['donationspent'];
    require_once "modules/wcgpoints.php";
    $cstones = wcgpoints_getpoints();
    switch (httpget('op')) {
        case "start":
            $moulds = load_inventory("mementomoulds_" . $session['user']['acctid'], true);
            if (count($moulds)) {
                output("Here are the original prototypes of Mementos you have made.`n`n");
                rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
                $classcount = 1;
                $moulds = modulehook("mementos", $moulds);
                foreach ($moulds as $id => $prefs) {
                    $classcount++;
                    $class = $classcount % 2 ? "trdark" : "trlight";
                    rawoutput("<tr class='{$class}'><td>");
                    output("`b%s`b`0`n", stripslashes($prefs['verbosename']));
                    output("%s`0`n`n", stripslashes($prefs['description']));
                    output("`bUse Text`b:%s`0`n`n", stripslashes($prefs['usetext']));
                    if ($prefs['mouldusesleft']) {
                        output("You can make another %s of these, at `6`b250`b CobbleStones`0 and `5`b1`b Supporter Point`0 each.`n", $prefs['mouldusesleft']);
                        rawoutput("<a href='runmodule.php?module=mementos&op=makecopy&itemid=" . $id . "'>Make a copy</a><br />");
                    } else {
                        if (!isset($prefs['mouldusesleft'])) {
                            output("You can make a mould for this Memento, enabling you to make copies using `6CobbleStones`0.  It'll cost you `5500 Supporter Points`0.`n");
                            rawoutput("<a href='runmodule.php?module=mementos&op=makecopy&itemid=" . $id . "'>Make a mould</a><br />");
                        } else {
                            output("This mould is too old and knackered to make any more Mementos, but you can re-forge it for `5500 Supporter Points`0.`n");
                            rawoutput("<a href='runmodule.php?module=mementos&op=makecopy&itemid=" . $id . "'>Make a mould</a><br />");
                        }
                    }
                    addnav("", "runmodule.php?module=mementos&op=makecopy&itemid=" . $id);
                    if (is_array($prefs['memento_forge_actions']) && count($prefs['memento_forge_actions'])) {
                        foreach ($prefs['memento_forge_actions'] as $action) {
                            rawoutput($action);
                        }
                    }
                    rawoutput("</td></tr>");
                }
                rawoutput("</table>");
            } else {
                //if there are no moulds
                output("You're about to ask the grinning Joker proprietor about these Memento things you've been hearing about, when suddenly the knowledge rushes into your head unbidden.`n`nMementos are player-created objects that can be given to other players.  They grant no in-game advantages, but are fun for roleplaying.  Players often roleplay giving items to each other, but with Mementos, those items can appear in Inventories and act like 'real' in-game items.`n`n`n`bWhat you need to know about Mementos`b`nMementos are weightless, and occupy the 'Shoebox' portion of the player's Inventory.  Mementos survive Drive Kills, and don't go away when 'used.'  They can only be destroyed by being discarded by the player.  They can also be put down and picked up on map squares, and gifted to other players for free (anonymously if desired) via Common Ground's Gifting Station.`n`nYou can specify the Name (shown in the Inventory) of the Memento, the Plural form of the name, the Description (shown in the Inventory), and the Use Text (shown when the player 'uses' the Memento).`n`n`n`bCosts`b`nYou can create a single Memento at a flat cost of `550 Supporter Points`0.  You can also create Memento Moulds, at a cost of `5500 Supporter Points`0 for the mould and the first Memento, plus `5one Supporter Point`0 and `6250 CobbleStones`0 for each of up to fifty copies of that Memento.  Single Mementos can be upgraded to Memento Moulds later on if you like.`n`n`n`bExample Memento`b`n`bName:`b Red Music Box`n`bPlural:`b Red Music Boxes`n`bDescription:`b An ornate red wooden music box, decorated with cut garnets and shiny stainless-steel edging.`n`bUse Text`b: You open up the music box.  Inside is a tiny demon, smoking a cigarette.  Noticing that his house is open, he hurriedly stamps out his smoke and launches into a stirring rendition of 'NewHome is Full of Noobs.'  You close the lid quickly.`n`nEach Memento can have 100 characters for the Name, 100 characters for the Plural name, 255 characters for the Description, and 1,000 characters for the Use Text.`n`n");
            }
            addnav("Memento Stuff");
            if ($pointsavailable >= 50) {
                addnav("Create new single Memento", "runmodule.php?module=mementos&op=new&type=single");
            } else {
                addnav("You need 50 Supporter Points for a single Memento", "");
            }
            if ($pointsavailable >= 500) {
                addnav("Create new Memento Mould", "runmodule.php?module=mementos&op=new&type=mould");
            } else {
                addnav("You need 500 Supporter Points for a Memento Mould", "");
            }
            break;
        case "makecopy":
            $giveitem = false;
            $itemid = httpget("itemid");
            $name = get_item_pref("verbosename", $itemid);
            $plural = get_item_pref("plural", $itemid);
            $desc = get_item_pref("description", $itemid);
            $usetext = get_item_pref("usetext", $itemid);
            $moulduses = get_item_pref("mouldusesleft", $itemid);
            if ($moulduses > 0) {
                if ($cstones >= $cscost) {
                    output("You've bought a new %s`0 using `6CobbleStones`0!  Would you like to buy another, or head back to the Memento Forge menu?`n`n", $name);
                    $giveitem = true;
                    increment_module_pref("spent", 250, "wcgpoints");
                    $cstones = wcgpoints_getpoints();
                    $session['user']['donationspent'] += 1;
                    //log purchase
                    $logsql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','memento_copy_cobblestone','1','none','0','" . date("Y-m-d H:i:s") . "')";
                    db_query($logsql);
                } else {
                    output("`4You don't have enough `6CobbleStones`0 to make another copy of that Memento, I'm afraid.`n`n");
                }
            }
            $pointsavailable = $session['user']['donation'] - $session['user']['donationspent'];
            if ($giveitem) {
                $prefs = get_item_prefs($itemid);
                unset($prefs["mouldusesleft"]);
                $prefs['memento_originalitem'] = $itemid;
                give_item("memento", $prefs);
                $moulduses--;
                set_item_pref("mouldusesleft", $moulduses, $itemid);
            }
            if ($moulduses > 0) {
                output("You're about a make a new copy of the Memento called `b%s`b`0.  This will cost `6250 CobbleStones`0 and `5one Supporter Point`0.  You now have `5%s Supporter Points`0 and `6%s CobbleStones`0, and this mould will make `b%s`0 more Mementos.`n`n", $name, number_format($pointsavailable), number_format($cstones), $moulduses);
                addnav("Buy");
                if ($cstones >= $cscost && $pointsavailable) {
                    addnav("Buy a copy", "runmodule.php?module=mementos&op=makecopy&itemid=" . $itemid);
                } else {
                    addnav("Not enough `6CobbleStones`0 (or you don't have a `5Supporter Point`0 left)", "");
                }
            } else {
                output("Either this mould is knackered, or this is a unique Memento.  You can't make any more copies.  However, you can make a new mould if you like, for `5500 Supporter Points`0.  This will enable you to make further copies of the Memento for `5one Supporter Point`0 plus `6250 CobbleStones`0 each.`n`n", $originalcost);
                addnav("Buy");
                if ($pointsavailable >= 500) {
                    addnav("Make a new mould", "runmodule.php?module=mementos&op=reforge&itemid=" . $itemid);
                } else {
                    addnav("Not enough `5Supporter Points`0 to make a new mould", "");
                }
            }
            addnav("Return");
            addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
            break;
        case "reforge":
            $itemid = httpget("itemid");
            output("You've successfully recreated the mould for your Memento.`n`n");
            set_item_pref("mouldusesleft", 50, $itemid);
            addnav("Return");
            addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
            $session['user']['donationspent'] += 500;
            $logsql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','memento_mould','500','none','0','" . date("Y-m-d H:i:s") . "')";
            db_query($logsql);
            break;
        case "new":
            $type = httpget('type');
            if ($type == 'single') {
                output("You're making a new unique Memento now.  Create your desired item and hit Submit.  You can use colour codes and italics just like in commentary, and you can use bold too, using the ``b switch (remember to close your bolds and italics with another ``b or ``i!).`n`nRemember to use ``n for a new line rather than pressing Enter.  Use ``n``n for a line break between paragraphs.`n`n");
                rawoutput("<form action='runmodule.php?module=mementos&op=check&type=single' method='POST'>Memento Name (maximum 100 characters): <input name='name' id='name'><br /><br />Plural (maximum 100 characters): <input name='plural' id='plural'><br /><br />Memento Description (maximum 255 characters):<br />");
                addnav("", "runmodule.php?module=mementos&op=check&type=single");
            } else {
                if ($type == 'mould') {
                    output("You're making a new Memento Mould now.  Create your desired item and hit Submit.  You can use colour codes and italics just like in commentary, and you can use bold too, using the ``b switch (remember to close your bolds and italics with another ``b or ``i!).`n`nRemember to use ``n for a new line rather than pressing Enter.  Use ``n``n for a line break between paragraphs.`n`n");
                    rawoutput("<form action='runmodule.php?module=mementos&op=check&type=mould' method='POST'>Memento Name (maximum 100 characters): <input name='name' id='name'><br /><br />Plural (maximum 100 characters): <input name='plural' id='plural'><br /><br />Memento Description (maximum 255 characters):<br />");
                    addnav("", "runmodule.php?module=mementos&op=check&type=mould");
                }
            }
            require_once "lib/forms.php";
            previewfield_countup("description");
            rawoutput("<br /><br />Text shown when using the Memento (maximum 1,000 characters):<br />");
            previewfield_countup("usetext");
            rawoutput("<br /><input type=submit>");
            addnav("Start Again");
            addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
            break;
        case "check":
            output("Here's a preview of your Memento:`n`n");
            $rname = httppost("name");
            $rplural = httppost("plural");
            $rdesc = httppost("description");
            $rusetext = httppost("usetext");
            $type = httpget("type");
            $dname = stripslashes($rname);
            $dplural = stripslashes($rplural);
            $ddesc = stripslashes($rdesc);
            $dusetext = stripslashes($rusetext);
            output("`bName:`b %s`0 (%s`0)`n`bDescription:`b %s`0`n`bUse Text:`b %s`0`n`n", $dname, $dplural, $ddesc, $dusetext);
            if (strlen($dname) <= 100 && strlen($dplural) <= 100 && strlen($ddesc) <= 255 && strlen($dusetext) <= 1000) {
                addnav("Confirm");
                if ($type == "single") {
                    addnav("Buy it! (`550 Supporter Points`0)", "runmodule.php?module=mementos&op=confirm&name=" . urlencode($rname) . "&plural=" . urlencode($rplural) . "&desc=" . urlencode($rdesc) . "&usetext=" . urlencode($rusetext) . "&type=single");
                } else {
                    if ($type == "mould") {
                        addnav("Buy it! (`5500 Supporter Points`0)", "runmodule.php?module=mementos&op=confirm&name=" . urlencode($rname) . "&plural=" . urlencode($rplural) . "&desc=" . urlencode($rdesc) . "&usetext=" . urlencode($rusetext) . "&type=mould");
                    }
                }
            } else {
                output("`4`bError: Something is too long.  Titles can be up to 100 characters, descriptions up to 255 characters, and usage texts up to 1,000 characters.`b`0`n`n");
                rawoutput("<form action='runmodule.php?module=mementos&op=check&type=" . $type . "' method='POST'>Memento Name (maximum 100 characters): <input name='name' id='name' value={$rname}><br /><br />Plural (maximum 100 characters): <input name='plural' id='plural' value={$rplural}><br /><br />Memento Description (maximum 255 characters):<br />");
                require_once "lib/forms.php";
                previewfield_countup("description", 255, $rdesc);
                rawoutput("<br /><br />Text shown when using the Memento (maximum 1,000 characters):<br />");
                previewfield_countup("usetext", 1000, $rusetext);
                rawoutput("<br /><input type=submit>");
                addnav("", "runmodule.php?module=mementos&op=check&type=" . $type);
            }
            addnav("Start Again");
            addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
            break;
        case "confirm":
            $type = httpget("type");
            $name = urldecode(httpget("name"));
            $plural = urldecode(httpget("plural"));
            $desc = urldecode(httpget("desc"));
            $usetext = urldecode(httpget("usetext"));
            $prefs = array("verbosename" => $name, "plural" => $plural, "description" => $desc, "usetext" => $usetext, "memento_author" => $session['user']['acctid']);
            if ($type == "single") {
                $cost = 50;
                output("You've made a new Memento.  You can find it in your Inventory!");
            } else {
                if ($type == "mould") {
                    $cost = 500;
                    output("You've made a mould for your new Memento, and the first Memento from that mould is now in your Inventory!");
                    $prefs['mouldusesleft'] = 50;
                }
            }
            $session['user']['donationspent'] += $cost;
            //log purchase
            $logsql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','memento_" . $type . "','" . $cost . "','none','0','" . date("Y-m-d H:i:s") . "')";
            db_query($logsql);
            //create the mould, track its id
            $id = give_item("memento", $prefs, "mementomoulds_" . $session['user']['acctid'], true);
            //debug($id);
            $prefs['memento_originalitem'] = $id;
            set_item_pref("memento_originalitem", $id, $id);
            //give the player the initial memento
            give_item("memento", $prefs);
            addnav("Return");
            addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
            break;
    }
    addnav("Return");
    addnav("Back to the Hunter's Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
    page_footer();
}
function load_inventory($acctid = false, $npcflag = false)
{
    //debug("Loading inventory");
    if (!$npcflag) {
        global $session, $itemprefs, $itemsettings, $inventory;
        if (!$acctid) {
            $acctid = $session['user']['acctid'];
        }
    } else {
        global $itemprefs, $itemsettings;
    }
    $items = get_player_items($acctid);
    if ((!count($items) || !is_array($items)) && !$npcflag) {
        debug("No items found!");
        debug("ASSIGNING STARTER ITEMS");
        //assign starting items
        give_item("bandolier1", false, $acctid);
        give_item("backpack1", false, $acctid);
        $items = get_player_items($acctid);
    }
    load_item_prefs($items);
    if (!isset($itemsettings) || !is_array($itemsettings)) {
        load_item_settings();
    }
    $inventory = $items;
    $weights = array();
    //now take settings and prefs, apply them to the item in question
    foreach ($inventory as $id => $vals) {
        if (is_array($itemsettings[$vals['item']])) {
            $inventory[$id] = array_merge($vals, $itemsettings[$vals['item']]);
        }
        if (is_array($itemprefs[$id])) {
            $inventory[$id] = array_merge($inventory[$id], $itemprefs[$id]);
        }
        if (is_array($updated_itemprefs[$id])) {
            $inventory[$id] = array_merge($inventory[$id], $updated_itemprefs[$id]);
        }
        if (!$npcflag) {
            //put items that don't have a carrier into the "main" inventory
            if (!isset($inventory[$id]['inventorylocation'])) {
                $inventory[$id]['inventorylocation'] = "main";
            }
        }
    }
    calculate_weights();
    $inventory = modulehook("load_inventory", $inventory);
    return $inventory;
}
function misterstern_run()
{
    global $session;
    switch (httpget("op")) {
        case "start":
            page_header("Mister Stern");
            $name = $session['user']['name'];
            output("\"`6Hello!`0\"`n`nYour heart puts on its running shoes and tears off around the track.  After roughly half a second of panic, you realise that the voice sounded quite friendly.  Jolly, even.  Male, British - a little upper class, perhaps, but not snooty with it.  Rather warm and sophisticated, in fact.`n`nYou look in the direction of the voice, and in the dim light you make out the outline of a figure standing behind the desk in the lobby.  You step forward.  \"`#Um, hello?`0\" you say.  \"`#I'm sorry, I thought I was alone.`0\"`n`nAs you step closer, the figure walks around from behind his desk.  \"`6I can't blame you, in this gloom,`0\" he says, walking across the room to a window and opening it.  Warm sunlight floods the lobby, little specks of dust dancing and reflecting in the air.  \"`6There,`0\" says the man.  \"`6That's better.`0\"`n`nThe tall, rather slender man wears a grey waistcoat, white shirt, and smart grey trousers.  A little pair of round-framed glasses sits on his nose, its arms connected via a chain around his neck.  When he turns to face you, you can see the outline of a pocket watch resting in his waistcoat pocket, silver chain sparkling.  His age is hard to tell.  Clearly he's been around a few years; he's old enough to make you think of the librarian or dusty old academic who can't quite bring himself to retire, despite it being more than time to do so.`n`nYou can't help but grin.  This guy is the ultimate stereotype of dusty British museum curators.`n`nHe grins back and steps towards you, hand outstretched.  \"`6Mister Havelock Stern, Stern by name but not by nature, pleased to make your acquiaintance.`0\"  You get the impression that he says this every time he meets someone - and that when he said he was pleased to meet you, he actually meant it.  You take the hand, give it a shake, and say \"`#%s`#.  Nice to meet you.`0\"`n`n\"`6Sorry to give you a fright,`0\" says Mister Stern.  \"`6Only I'd just nipped into the cupboard to put the kettle on.  I don't get many visitors here, you see.`0\"`n`n\"`#That's okay,`0\" you say, a little sheepishly.  \"`#Honestly I think I was just full of adrenaline anyway.`0\"`n`nMister Stern shows you another grin.  \"`6Aha.  Did `\$The Watcher`6 send you here, by any chance?  Blonde lady, glasses, looks somewhere in her thirties?  Always wears a red turtleneck?`0\"`n`n\"`#Utterly insane and rather frightening?`0\"`n`nMister Stern chuckles.  \"`6Yes, that's the one.  I see.  Well, you must be a new recruit, then.  Well, I remember my first day.  It's rough, isn't it?  Well, the kettle should be boiled by now, if you'd like a break from it all...?`0\"`n`nYou've been kidnapped and thrust into a war against a reality-altering machine, and now a kindly gentleman is offering you a cup of tea.  Well, what happens next?", $name);
            addnav("Mister Stern");
            addnav("I have to admit, it's all a bit confusing.  A cup of tea sounds nice.", "runmodule.php?module=misterstern&op=tea");
            addnav("No, I think I'm doing okay.  Thanks for the offer, but I'd best be on my way.", "runmodule.php?module=misterstern&op=notea");
            break;
        case "tea":
            page_header("Mister Stern");
            set_module_pref("hadtea", 1);
            output("\"`6Jolly good,`0\" says Mister Stern, and again, you get the impression that he means it.`n`n\"`6So,`0\" he says a few minutes later, while pouring and adulterating the tea, \"`6tell me honestly.  What do you think of the exhibits?`0\"`n`n\"`#To be completely honest,`0\" you say, \"`#I wouldn't have thought there would `ibe`i a museum here.  I mean, this is Improbable Island, after all...`0\" you trail off.  \"`#I still can't believe I'm actually here.  I mean, I watched the show and everything, but you never think your number's gonna come up, do you?  Anyway.  Yes, the exhibits were very nice, but they made me miss the old days a bit.`0\"`n`nMister Stern sits down and hands you your cup.  \"`6Yes,`0\" he says, taking a sip.  \"`6I know exactly what you mean.  It's quite a culture shock, isn't it?  On both sides, I mean - coming to the Island, and getting thrown back into the Renaissance practically overnight.  They're both a big blow to the system, really.`0\"`n`n\"`#Tell me about it,`0\" you mutter into your cup.`n`nMister Stern takes you literally.  \"`6I remember the day the mines went off.  I think we all do, really.  I remember waking up and wondering why my alarm clock wasn't playing.  I assumed we'd had a power cut when I saw the display was blank.`0\"  He blows on his tea.  \"`6So, of course, I checked my phone, and that was dead, too.  Although to be fair, the battery was on its way out, and I always charge it overnight.`0\"  He takes a sip.  \"`6So, I assumed that the battery had run out in the night.  I practically jumped out of bed and ran all around the house trying to find a working clock, worried that I was going to be late.`0\"  He grins.  \"`6I ran a museum in my past life too, you see.  It's become something of a habit.`0\"  You nod and grin back.  \"`6Anyway,`0\" continues Mister Stern, \"`6I picked up the landline to try to call the speaking clock, and couldn't get a dial tone.  That was when I started to think that maybe something very bad had happened.`0\"`n`nMister Stern's eyes seem to focus somewhere in the middle distance, left of your head.  \"`6I remembered I had a little travel alarm clock, powered by a nine volt battery.  I dashed upstairs and rummaged around until I found it.`0\"  He blows on his tea.  \"`6It was dead as a doornail.  I took the battery out, and tested it on my tongue.  It gave a little tingle, so I knew the battery was fine.`0\"  He sips his tea, staring off into nowhere.  \"`6In fact, it gave quite a big tingle - almost as if it had been overcharged.  And that's when I noticed the smell, coming from the alarm clock...`0\"`n`n\"`#I remember that smell,`0\" you mutter.  \"`#Burning solder.`0\"`n`nMister Stern gives you a sad little nod.  You sit in silence for a moment.`n`n\"`6When did you catch on?`0\" asks Mister Stern after some seconds.`n`nYou shrug.  \"`#What, that the world had ended?  I honestly can't remember.  It was a very busy day.  I know my neighbour didn't realise until his car didn't start.  And even then, he didn't understand what was going on.`0\"`n`n\"`6I see,`0\" sighs Mister Stern.  \"`6You know, I think I understand why I don't get many visitors here.  The memories are too much for most people.`0\"`n`nYou nod.  \"`#The other exhibits, though - the dummies, they're not bad.`0\"`n`n\"`6Yes.  Yes, we certainly do need some more exhibits, don't we?  Maybe some cheerful ones.`0\"  Mister Stern looks out of the window.  \"`6You know, there's a world of interesting things out there.  If I could get around a little more, I'd head out and find some things to show off myself.`0\"`n`n\"`#What sort of things?`0\" you ask.`n`n\"`6Oh, just anything interesting, really.  Some herbs from the KittyMorph village, maybe some artefacts from Cyber City, that sort of thing.  I'd like to get a good range of things to show to people, you know?  But since the accident, I just haven't been able to get around too much.`0\"`n`n\"`#Accident?`0\"`n`nMister Stern points to his left knee.  \"`6Shrapnel.  Shrapnel from a piece of the equipment surrounding the Improbability Drive, no less.  It's impossible to walk terribly far, and I daren't use any of these new-fangled teleporter devices - who knows how such a machine would interact with a piece of Improbability-infused metal?`0\"`n`nYou shrug.  \"`#Hell, I'm going to be heading out into the Big Bad Jungle just as soon as I've finished this tea; if I come across anything interesting, I'll be sure to let you know.`0\"`n`nMister Stern smiles.  \"`6I'm sure you'll come across a great `imany`i interesting things.  It's a jungle out there.`0\"`n`nYou grin back.`n`nA few minutes of idle chitchat later, you finish your tea, bid your farewells and leave the Museum.");
            addnav("Continue");
            addnav("Head back into the Outpost", "village.php");
            break;
        case "notea":
            page_header("Mister Stern");
            output("\"`6Right enough,`0\" says Mister Stern.  \"`6I expect you've got all sorts of monsters and creatures and things to be getting on with.  The offer remains open, though - I'm here rain or shine.`0\"`n`nYou bid your farewell and head out of the Museum.");
            addnav("Continue");
            addnav("Continue back into the Outpost", "village.php");
            break;
        case "getrelic":
            page_header("Got any Relics?");
            output("You ask if there are any interesting things handy that could help illustrate the local culture.`n`n");
            switch ($session['user']['location']) {
                case "NewHome":
                    output("`0The man behind the desk furrows his brow.  \"`1`iMuseum`i exhibits?  This'll be for that Mister Stern, won't it?`0\"  He rummages in a desk drawer.  \"`1Yup, he's been after some new stuff for his museum for a while now, or so I gather.  Now, let's see...  Ah, maybe this'll do.`0\"  He pulls out what looks like an old service revolver, rusted with age.  \"`1I've been meaning to give this to him for a while.  It's not much good as an actual weapon, but I reckon that's probably the oldest firearm on the whole Island.  Well pre-EMP.  He should like that.`0\"`n`nYou thank the man and make your farewells.");
                    give_item("stern_revolver");
                    set_module_pref("gotnh", 1);
                    break;
                case "Kittania":
                    output("`0The KittyMorph smiles.  \"`1Oh, Mister Stern must have sent you!  Here, you can have this.`0\"  She reaches into her desk drawer and hands you a dead mouse.`n`nYou stare at it for a moment.`n`n\"`1Oh!  Whoops, sorry...`0\" she takes the mouse back from your hand, giggling as she puts it back in the drawer.  \"`1That's not what I meant to give you at all!  Deary me, what on Earth would a human want with one of `ithose`i?  Here.`0\"`n`nShe hands you a dead rat.`n`nWell, it's better than nothing.  Maybe this is how KittyMorphs pay respect to one another.`n`nMaybe.");
                    give_item("stern_rat");
                    set_module_pref("gotki", 1);
                    break;
                case "New Pittsburgh":
                    output("The Zombie behind the desk nods, slowly.  She reaches under her desk, and brings up a brain in a jar.  \"`1He's a lovely man.  He can have this BRAAAAAAAAAAIIINS,`0\" she slurs.  \"`1I was saving it for my lunch, but I'm sure it'd be a good conversation piece.  I know our eating habits differ quite a bit.`0\"`n`nYou nod.  \"`#I'm sure it'll prove very useful, thanks.`0\"`n`nYou leave hastily, in case she changes her mind and decides on a fresh brain instead.");
                    give_item("stern_brain");
                    set_module_pref("gotnp", 1);
                    break;
                case "Squat Hole":
                    output("\"`1Is this for tha' fookin' old geezer in der 'umin town, yeah?`0\"`n`nYou nod.`n`n\"`1Tell 'im 'e can 'ave dis,`0\" says the Midget.  With a loud snort and a cringe-inducing squishing sound, he shifts some phlegm into his mouth and spits into his hand.  He holds it out to you.`n`n\"`1Whassa' fookin' matter, eh?`0\" he asks, seeing that you're less than enthusiastic about his gift.  \"`1I tell yer, you lot've got no fookin' `iclue`i about 'ow we live, do ya?  Thass' a `ivaluable commodity,`i is tha'!  We use it fer all sorts!  This Stern feller, 'e should consider 'imself 'ighly respected fer a gift like dis!`0\"  He looks down at his hand.  \"`1Oh, right.  Never mind, I get yer now.  Sorry mate, I completely forgot me fookin' manners.  I'll get yer a little bag, shall I?`0\"`n`nYou cringe as the Midget pours the contents of his hand into a little sandwich bag, and tosses it to you.  It splats into your hand, mercifully dry but still soft and squishy, and... `iwarm.`i`n`nYou mutter a hasty \"`#Thanks,`0\" and leave quickly before the Midget can give you anything else.");
                    give_item("stern_phlegm");
                    set_module_pref("gotsq", 1);
                    break;
                case "Pleasantville":
                    output("\"`1This would be for Mister Stern, I assume.  Fine fellow.  Very understanding, easy to talk to.  It's a terrible shame about his accident.`0\"  The Mutant behind the desk hesitates.  \"`1Although to be honest, I've no idea what I can give you.`0\"`n`nYou shrug.  \"`#Anything, really.  Anything that makes it easier to understand Mutants.`0\"`n`nThe Mutant's eyes seem to light up.  \"`1I have some poetry.  Would you like to hear it?`0\"`n`nYou shuffle your feet.  \"`#Ah, well, see, thing is, I've really got to -`0\"`n`n\"`1Black is the pit where my heart once lurked,`0\" says the Mutant, reading from a piece of paper pulled from his pocket.  \"`1`iBlack`i is the pupil of my one working eye.`0\"`n`n\"`#Oh, God...`0\"`n`n\"`1`iBlack`i is the stubbed toenail that sprouts from my left ear.  `iBlack`i is the gunge that seeps from the festering hole in my torso.  `iBLACK`i are the teeth within that festering hole, how I long for a toothbrush that will reach!`0\"`n`nYou begin to feel a little faint.`n`n\"`1`iBlack`i is the colour of my `isoul`i, the colour of my `imind`i, the colour of my heavily-altered `iT-shirt`i, the colour of my `iPAIN!`i  `iBlack`i are the sightless, staring eyes that cover my knees and my penis.`0\"`n`nGrey fuzz seems to be seeping in around the edges of your vision.  You can hear a high-pitched whine, but it doesn't drown out the sounds of the Mutant's poetry.`n`n\"`1`iMy penis!`i  Oh, cruel and sadistic fate!  My instrument of `ilove`i, my rod of passion, studded with the `iblack gems`i that drive women `iscreaming`i and `iurinating`i into the night!  The eyes, the `ieyes!`i  They do not see, they can not look in love and wonder upon a newborn babe or a majestic waterfall!  But if you cut me, do I not bleed?  If you poke my penis-eyes, do they not blink as one in soundless anguish?`0\"`n`n\"`#I'M SURE HE'LL LOVE IT!`0\" you scream.  \"`#THANK YOU VERY VERY MUCH!`0\"  You snatch the paper from his hand, and run gibbering out of the hut.");
                    give_item("stern_poetry");
                    set_module_pref("gotpl", 1);
                    break;
                case "Cyber City 404":
                    output("\"`1Affirmative.  The fleshling Stern wishes to create a permament record of your primitive, chemical-based knowledge, yes?  An excellent aspiration, given that your memories are flawed and untrustworthy.`0\"  The Robot behind the desk nods his appreciation.  \"`1I will give you this.`0\"`n`nHe hands over a tiny memory card.  \"`#Oh, thank you very much,`0\" you say.  \"`#He seems to be really into his pre-EMP technology.  What is it, exactly?`0\"`n`n\"`1Oddly enough, the collected thoughts and memories of your home town.  A complete record of every personality, ready to be transplanted into Robot bodies should the need arise.  I believe you are in there somewhere.`0\"`n`nYou stare at the card.  Your entire life, and the lives of those around you, on a memory card smaller than a suppository.  You stuff it moodily into your pocket, mutter something like \"`#Thanks,`0\" and head out of the door, leaving the Robot wondering why the display of his superior technology and mental capacity seemed to lose him a potential friend, rather than make one.`n`nHe shrugs.  It seems appropriate to do so.  He's good at shrugging.  He's practiced in front of a mirror.");
                    give_item("stern_memorycard");
                    set_module_pref("gotcc", 1);
                    break;
                case "AceHigh":
                    output("\"`1You needn't say another word,`0\" says the lady behind the desk, dressed in an immaculate Victorian suit.  \"`1I know what you're here for, and I know who sent you.  Give him this.`0\"`n`nThe green glow around her eyes seems to intensify as she pulls a coin out of her pocket.  She hands it to you, and the light dies away a little.`n`nYou turn it over.  It's an old British penny, one of the really huge ones from the 1940's.  But there's something wrong.  \"`#This is a double-headed one,`0\" you say.`n`n\"`1Flip it,`0\" says the woman, smiling.`n`nYou do as commanded.  When you catch it, both sides show tails.  \"`#Wow, that's really neat!`0\" you say, and flip it again.  It comes up heads on both sides.  \"`#You know, this is probably the best thing I've gotten on this little adventure.`0\"`n`nThe lady nods, watching you flip the coin a third time, clearly enjoying your interest in her artefact.  \"`1It's certainly a fascinating piece.  Full of rather complex equations and Improbabilities.  Each time the faces are reversed, there's a one in seven chance of folding a localised area of time and space, generating a potentially universe-shattering paradox.  Isn't that exciting?`0\"`n`nYou catch the coin and slip it into your pocket.  \"`#I'll just keep this safe in here for now.`0\"");
                    give_item("stern_penny");
                    set_module_pref("gotah", 1);
                    break;
            }
            addnav("Return");
            addnav("Back to the Outpost", "village.php");
            break;
        case "show":
            page_header("Mister Stern");
            set_module_pref("subplotcomplete", 1);
            output("\"`6My goodness!`0\" says Mister Stern, pushing his glasses further up on his nose and examining the array of objects you've just placed on his desk.  \"`6What an excellent find!  Let's see, here...  A dead rat, some phlegm, a rusty pistol, a brain, some sort of memory card, some... goodness, some Mutant poetry from the look of things...`0\"`n`n\"`#Do you think they'll be useful?`0\" you ask, somewhat dubious.`n`n\"`6Oh, yes!  These are superb!`0\" says Mister Stern.  \"`6Oh, and this must be one of those Joker coins!`0\"  He flips it into the air.`n`n\"`6My goodness!`0\" says Mister Stern, pushing his glasses further up on his nose and examining the array of objects you've just placed on his desk.  \"`6What an excellent find!  Let's see, here...  A dead rat, some phlegm, a rusty pistol, a brain, some sort of memory card, some... my goodness, some Mutant poetry from the look of things...`0\"`n`n\"`#Do you think they'll be useful?`0\" you ask, somewhat dubious.`n`n\"`6Oh, yes!  These are superb!`0\" says Mister Stern.  \"`6Oh, and this must be one of those Joker coins!`0\"  He flips it into the air.`n`nYou pull out a cigarette and light it, knowing that there are questions to be asked and answered - like what you're going to do with the rest of your life - but for the moment, at least, you're content to just lie here for a little while.`n`nA metallic creaking sound jars you out of your contemplation. You sit up, staring at the jagged edges of the Improbability Drive's remains, the jagged edges that are now trying to bend themselves back into shape...`n`n\"`6Oh, and this must be one of those Joker coins!`0\"  He flips it into the air.`n`nYou snatch the coin out of the air mid-flip.  \"`#Might want to go easy on that.`0\"`n`n\"`6Oh,`0\" says Mister Stern.  \"`6Yes, I see what you mean.  Gives one a belter of a headache, doesn't it?  Well, listen, I can't thank you enough for all this, but I want to give you your time's worth.`0\"`n`nHe hands you a pack of ten cigarettes.  Result!`n`n\"`#Well, thanks very much,`0\" you say, \"`#and I really should get going.  I've monsters to kill, and I expect you'll be wanting to arrange your exhibits and write up cards for them, and that sort of thing.`0\"`n`n\"`6Indeed, indeed.  Come back any time!  And thank you once again!`0\"");
            delete_item(has_item("stern_revolver"));
            delete_item(has_item("stern_rat"));
            delete_item(has_item("stern_brain"));
            delete_item(has_item("stern_phlegm"));
            delete_item(has_item("stern_poetry"));
            delete_item(has_item("stern_memorycard"));
            delete_item(has_item("stern_penny"));
            $session['user']['gems'] += 10;
            addnav("Continue");
            addnav("Back to the Outpost", "village.php");
            if (is_module_active("medals")) {
                require_once "modules/medals.php";
                medals_award_medal("mister_stern", "Museum Marketeer", "This player helped Mister Stern restore his museum to popularity!", "medal_museumquest.png");
            }
            break;
    }
    page_footer();
}
Example #19
0
 $attack_allowed = $AttackLegal->check();
 $attack_error = $AttackLegal->getError();
 // *** Any ERRORS prevent attacks happen here  ***
 if (!$attack_allowed) {
     //Checks for error conditions before starting.
     $error = 1;
 } else {
     if (is_string($item) || $target == "") {
         $error = 2;
     } else {
         if ($item_count < 1) {
             $error = 3;
         } else {
             /**** MAIN SUCCESSFUL USE ****/
             if ($give) {
                 give_item($username, $target, $item->getName());
                 $alternateResultMessage = "__TARGET__ will receive your {$item->getName()}.";
             } else {
                 if (!$item->isOtherUsable()) {
                     // If it doesn't do damage or have an effect, don't use up the item.
                     $resultMessage = $result = 'This item is not usable on __TARGET__, so it remains unused.';
                     $item_used = false;
                     $using_item = false;
                 } else {
                     if ($item->hasEffect('stealth')) {
                         $targetObj->addStatus(STEALTH);
                         $alternateResultMessage = "__TARGET__ is now stealthed.";
                         $targetResult = ' be shrouded in smoke.';
                     }
                     if ($item->hasEffect('vigor')) {
                         if ($targetObj->hasStatus(STR_UP1)) {
function give_item($item, $prefs = false, $acctid = false, $skipreload = false)
{
    //To maximise performance when giving items inside a loop, set $skipreload to true and then call load_inventory() immediately afterwards.  Unless of course you don't need to set prefs for the items, in which case just use give_multiple_items instead.
    global $session, $inventory, $itemsettings;
    if (!$acctid) {
        $acctid = $session['user']['acctid'];
    }
    if (get_item_setting("unique", $item)) {
        //check for duplicate items
        $sql = "SELECT * FROM " . db_prefix("items_player") . " WHERE item = '{$item}' AND owner = '{$acctid}'";
        $result = db_query($sql);
        if (db_num_rows($result)) {
            //output("`c`b`4HORRIBLE HORRIBLE ITEM SYSTEM ERROR`nSomething has gone wrong, and the item system has tried to give you an item of which you should have only one.  Like a backpack or something.  Please report this, and tell us exactly what you did!`0`b`c`n`n");
            return false;
        }
    }
    $sql = "INSERT INTO " . db_prefix("items_player") . " (item, owner) VALUES ('{$item}','{$acctid}')";
    db_query($sql);
    //get the id of the last item entered
    $key = mysql_insert_id();
    if (is_array($prefs)) {
        foreach ($prefs as $setting => $value) {
            set_item_pref($setting, $value, $key);
        }
    }
    //check whether or not this item also gives its container item, IE lodge bags, shoeboxes
    if (get_item_setting("give_container", $item)) {
        //check for the container
        if (!has_item(get_item_setting("give_container", $item), $acctid) && is_numeric($acctid)) {
            give_item(get_item_setting("give_container", $item), false, $acctid);
        }
    }
    invalidatedatacache("playeritems/playeritems_{$acctid}");
    if ($acctid == $session['user']['acctid']) {
        //saves a query over loading the inventory every time
        if (!isset($inventory) || !is_array($inventory) && !$skipreload) {
            load_inventory();
        } else {
            if (!isset($itemsettings) || !is_array($itemsettings)) {
                load_item_settings();
            }
            $inventory[$key] = $itemsettings[$item];
        }
    }
    return $key;
}
function luggagehut_run()
{
    global $session;
    page_header("The Luggage Hut");
    $backpackprefs = array("carrieritem" => "main");
    $backpack = get_items_with_prefs($backpackprefs, true);
    // debug($backpack);
    foreach ($backpack as $key => $prefs) {
        $currentbackpack = $prefs;
        $currentbackpackid = $key;
    }
    $bandolierprefs = array("carrieritem" => "fight");
    $bandolier = get_items_with_prefs($bandolierprefs, true);
    // debug($bandolier);
    foreach ($bandolier as $key => $prefs) {
        $currentbandolier = $prefs;
        $currentbandolierid = $key;
    }
    global $inventory;
    // debug($inventory);
    $tradein_main = round($currentbackpack['invshop_price'] * 0.6);
    $tradein_fight = round($currentbandolier['invshop_price'] * 0.6);
    switch (httpget('op')) {
        case "start":
            output("`0You head into the Luggage Hut.  A tall woman in her mid-twenties greets you.  From the dimensions of her mullet, you suspect she may be related to Sheila.`n`n\"`2Well, hey there!  Name's Sharon, nice to meet you.  Here for some new luggage?  We've got three different types of Backpacks and Bandoliers available.  Here, take a look around.  I can give you a trade-in value of %s cigarettes on your old backpack, and %s on your old bandolier.`0\"`n`nYou look around the shop a little, finding three different types of Bandoliers and Backpacks on sale:`n`n`bStandard Backpack`b`nA bog-standard backpack made from reasonably good materials.  Comfortably holds up to twenty kilos, and costs ten cigarettes.`n`n`bImproved Backpack`b`nA more well-designed backpack with extra pockets and good balance.  Holds up to forty kilos, and costs fifty cigarettes.`n`n`bAdvanced Backpack`b`nA superior-quality backpack designed by the famous B. P. BackPack, who changed his name by deed poll after working in the backpack design business for sixty years.  The man's completely bonkers, but he knows how to design a damned good backpack.  Comfortably holds up to eighty kilos, and costs one hundred cigarettes.`n`n`n`bStandard Bandolier`b`nA slightly more advanced version of the Basic bandolier given to new recruits.  Holds up to five kilos and costs ten cigarettes.`n`n`bImproved Bandolier`b`nThis leather bandolier looks cool, and has more pockets to store more things to use in fights.  Holds up to seven kilos and costs fifty cigarettes.`n`n`bAdvanced Bandolier`b`nThe Rolls-Royce of bandoliers, these things only tend to get purchased by the serious combat nut.  Holds up to ten kilos, and costs one hundred cigarettes.", $tradein_main, $tradein_fight);
            break;
        case "buy":
            $item = httpget('buy');
            if ($item == "backpack2" || $item == "backpack3" || $item == "backpack4") {
                $invloc = "main";
                $tradein = $tradein_main;
            } else {
                $invloc = "fight";
                $tradein = $tradein_fight;
            }
            $price = get_item_setting("invshop_price", $item);
            //debug($price);
            if ($price > $session['user']['gems'] + $tradein) {
                //todo
                output("Sharon shakes her head, her mullet swaying back and forth.  \"`2Sorry love - even with the trade-in, that's just not going to be enough.`0\"`n`nYou don't actually `ihave`i that many cigarettes.  Shame.");
            } else {
                $has = has_item($item);
                if ($has) {
                    output("Sharon smiles as she takes your cigarettes.  She pauses when she sees your old equipment.`n`n\"`2Uh, mate...  That's `iexactly`i the same as the one you're buying.  I'm not gonna take your cigs and then give you something that's no different to what you've already got - I'm not Sheila, you know?`0\"`n`nEmbarrassed, you nod, and take back your cigarettes.");
                } else {
                    output("Sharon smiles as you hand over your cigarettes and your old equipment.  \"`2Great stuff.  Here you go, one lovely new shiny piece of luggage!  Treat it well, now!`0\"");
                    $session['user']['gems'] += $tradein;
                    $session['user']['gems'] -= $price;
                    $price = $price - $tradein;
                    if ($invloc == "main") {
                        delete_item($currentbackpackid);
                    } else {
                        if ($invloc == "fight") {
                            delete_item($currentbandolierid);
                        }
                    }
                    give_item($item);
                    debuglog("spent " . $price . " cigarettes on " . $item . " at the Luggage Hut.");
                }
            }
            break;
    }
    addnav("Backpacks");
    addnav("Buy Standard Backpack", "runmodule.php?module=luggagehut&op=buy&buy=backpack2");
    addnav("Buy Improved Backpack", "runmodule.php?module=luggagehut&op=buy&buy=backpack3");
    addnav("Buy Advanced Backpack", "runmodule.php?module=luggagehut&op=buy&buy=backpack4");
    addnav("Bandoliers");
    addnav("Buy Standard bandolier", "runmodule.php?module=luggagehut&op=buy&buy=bandolier2");
    addnav("Buy Improved bandolier", "runmodule.php?module=luggagehut&op=buy&buy=bandolier3");
    addnav("Buy Advanced bandolier", "runmodule.php?module=luggagehut&op=buy&buy=bandolier4");
    addnav("Other");
    addnav("Back to the Outpost", "village.php");
    page_footer();
    return true;
}
function racejoker_dohook($hookname, $args)
{
    //yeah, the $resline thing is a hack.  Sorry, not sure of a better way
    // to handle this.
    // Pass it as an arg?
    global $session, $resline;
    $city = "AceHigh";
    $race = "Joker";
    switch ($hookname) {
        case "racenames":
            $args[$race] = $race;
            break;
        case "changesetting":
            // Ignore anything other than villagename setting changes
            if ($args['setting'] == "villagename" && $args['module'] == "racejoker") {
                if ($session['user']['location'] == $args['old']) {
                    $session['user']['location'] = $args['new'];
                }
                $sql = "UPDATE " . db_prefix("accounts") . " SET location='" . addslashes($args['new']) . "' WHERE location='" . addslashes($args['old']) . "'";
                db_query($sql);
                if (is_module_active("cities")) {
                    $sql = "UPDATE " . db_prefix("module_userprefs") . " SET value='" . addslashes($args['new']) . "' WHERE modulename='cities' AND setting='homecity'" . "AND value='" . addslashes($args['old']) . "'";
                    db_query($sql);
                }
            }
            break;
        case "chooserace":
            if ($session['user']['dragonkills'] < 12) {
                break;
            }
            output("`0You grin, and pull a six-sided die from your left ear.  <a href='newday.php?setrace={$race}{$resline}'>\"Well, let's see, shall we?\"</a>`n`n", true);
            addnav("`&Joker`0", "newday.php?setrace={$race}{$resline}");
            addnav("", "newday.php?setrace={$race}{$resline}");
            break;
        case "setrace":
            if ($session['user']['race'] == $race) {
                output("The gatekeeper's smile doesn't go away.  Instead, it freezes, locks carefully into place - and the gatekeeper begins to pray that he can persuade it to stay there until you go away, or at least until your eyes stop doing that `@green glowy thing`0.  \"`6Yes,`0\" he says, carefully.  \"`6Yes, that would be fine.`0\"`n`nYou roll your die.  It skitters along, making a clattering sound like bone on wood.  The fact that it's still four feet above the ground doesn't seem to faze the gatekeeper, or if it does, he's very good at not letting it show.`n`nIt finally comes to rest, seven spots facing the sun.  You look up and grin, teeth white and gleaming and not entirely friendly.  \"`#It seems I am a Joker!`0\" you exclaim in a breathy growl.`n`nThe gatekeeper nods, and picks up his journal.  \"`6Very good.  As you say.  Jay.  Oh.  Kay.  Are.  Ee.  Joker.  All done.`0\"  He looks up, to see you preparing to roll your die again.  He opens his mouth to ask you what you're doing, and bites his tongue.  Never ask what a Joker is doing; they might tell you.`n`nYou roll your die.  It skitters along the invisible table, bounces against an invisible wall, and comes up at two.`n`n\"`#Shame,`0\" you say.  \"`#You would have been more interesting with some additional eyes.  Still, if the die says two are enough, then who am I to disagree?`0\"`n`nYou give the gatekeeper a grin and a wink, and head into the outpost.`n`nA minute later, he remembers to exhale.  He shudders and puts the kettle on, hoping that it isn't going to turn out to be one of `ithose`i days.");
                if (is_module_active("cities")) {
                    set_module_pref("homecity", $city, "cities");
                    if ($session['user']['age'] == 0) {
                        $session['user']['location'] = $city;
                    }
                }
            }
            break;
        case "startofround-prebuffs":
            if ($session['user']['race'] == $race && $session['user']['alive']) {
                $chain = unserialize(get_module_pref("chain"));
                if (!is_array($chain)) {
                    $chain = array();
                }
                $suit = httpget("suit");
                if (!$suit) {
                    $suit = e_rand(1, 4);
                }
                switch ($suit) {
                    case 1:
                        $chain[] = "heart";
                        break;
                    case 2:
                        $chain[] = "diamond";
                        break;
                    case 3:
                        $chain[] = "spade";
                        break;
                    case 4:
                        $chain[] = "club";
                        break;
                }
                $hearts = 0;
                $diamonds = 0;
                $spades = 0;
                $clubs = 0;
                $num = 0;
                output("You draw a card from your rather Improbable deck, and add it to your hand.`n");
                foreach ($chain as $card) {
                    rawoutput("<img src=\"images/" . $card . ".png\">");
                    switch ($card) {
                        case "heart":
                            $hearts++;
                            break;
                        case "diamond":
                            $diamonds++;
                            break;
                        case "spade":
                            $spades++;
                            break;
                        case "club":
                            $clubs++;
                            break;
                    }
                    $num++;
                }
                output_notl("`n");
                if ($hearts == $num || $diamonds == $num || $spades == $num || $clubs == $num) {
                    if ($num > 1) {
                        output("`0With a grin you realise that all your cards match up - Joker tradition now allows you to expand your hand by one card!`n");
                    }
                } else {
                    if ($num > 1) {
                        output("`0The bottom card from your hand vanishes.`n");
                    }
                    array_shift($chain);
                }
                set_module_pref("chain", serialize($chain));
                //calculate and award buffs
                $bhearts = round($session['user']['maxhitpoints'] / 100 * e_rand($hearts * $hearts * $hearts / 100, $hearts * $hearts * $hearts / 5));
                $bdiamonds = e_rand($diamonds, $diamonds * $diamonds);
                $bspades = $spades * $spades * $spades * 0.005 + 1;
                $bclubs = $clubs * $clubs * $clubs * 0.005 + 1;
                if ($bhearts > 1) {
                    apply_buff("Hearts", array("regen" => $bhearts, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => 1, "expireafterfight" => 1, "effectmsg" => "The mysterious power of your Hearts aura causes you to regenerate {damage} hitpoints...`0", "schema" => "module-racejoker"));
                }
                if ($bdiamonds > 0) {
                    if ($bdiamonds == 1) {
                        output("`@The reward hopper mounted to the closest camera is briefly enveloped in crackling green lightning.  You step back and deftly catch the single Requisition token that clatters out of it, before heading straight back into the fight!`0`n");
                    } else {
                        output("`@The reward hopper mounted to the closest camera is briefly enveloped in crackling green lightning.  You step back and deftly catch the `b%s`b Requisition tokens that pour out of it, before heading straight back into the fight!`0`n", $bdiamonds);
                    }
                    $session['user']['gold'] += $bdiamonds;
                }
                if ($bspades > 1) {
                    apply_buff("Spades", array("defmod" => $bspades, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => 1, "startmsg" => "You feel an aura of protection gathering around you!", "expireafterfight" => 1, "roundmsg" => "Thanks to the power of the Spades suit, {badguy} is having trouble hitting you!", "schema" => "module-racejoker"));
                }
                if ($bclubs > 1) {
                    apply_buff("Clubs", array("atkmod" => $bclubs, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => 1, "startmsg" => "You feel a burning energy in your muscles...", "expireafterfight" => 1, "roundmsg" => "Thanks to the power of the Clubs suit, your attacks are more powerful!", "schema" => "module-racejoker"));
                }
            }
            break;
            // case "alternativeresurrect":
        // case "alternativeresurrect":
        case "stamina-newday":
            if ($session['user']['race'] == $race) {
                clear_module_pref("chain");
                racejoker_checkcity();
                //new Joker grenade -> improbabombs routine
                $bandolier = 0;
                $blprefs = array("inventorylocation" => "fight");
                $bandolier += has_item_quantity("banggrenade", $blprefs);
                $bandolier += has_item_quantity("whoomphgrenade", $blprefs);
                $bandolier += has_item_quantity("zapgrenade", $blprefs);
                $count = 0;
                $count += delete_all_items_of_type("banggrenade");
                $count += delete_all_items_of_type("whoomphgrenade");
                $count += delete_all_items_of_type("zapgrenade");
                if ($count) {
                    output("`0All of your Grenades have turned into Improbability Bombs overnight.  Well, that's what happens when you store explosives around such high levels of Improbability.`n");
                    $backpack = $count - $bandolier;
                    for ($i = 0; $i < $backpack; $i++) {
                        give_item("improbabilitybomb");
                    }
                    for ($i = 0; $i < $bandolier; $i++) {
                        give_item("improbabilitybomb", $blprefs);
                    }
                }
                //Combat buffs
                $jokerattack = e_rand(1, 20) / 10;
                $jokerdefence = e_rand(1, 20) / 10;
                $jokerregen = 0;
                $jokerregenchance = e_rand(1, 100);
                if ($jokerregenchance > 80) {
                    $jokerregen = 5 - e_rand(1, 10);
                }
                apply_buff("joker", array("name" => "Joker Bonus - Improbability", "atkmod" => $jokerattack, "defmod" => $jokerdefence, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => -1, "schema" => "module-racejoker"));
                if ($jokerregen < 0) {
                    output("`n`&Today is a bad day.  Your internal organs appear to have shifted themselves into a rather unfortunate configuration.  Internal bleeding will cause you to lose some hitpoints with every round of battle.`n`0");
                    apply_buff("jokerregen", array("regen" => $jokerregen, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => -1, "effectmsg" => "`3Your internal bleeding causes you to lose {damage} hitpoints.`0", "schema" => "module-racejoker"));
                }
                if ($jokerregen > 0) {
                    output("`n`&Today is a good day.  You appear to have discovered the secret of cellular regeneration.  You will gain hitpoints in every battle.`n`0");
                    apply_buff("jokerregen", array("regen" => $jokerregen, "allowinpvp" => 1, "allowintrain" => 1, "rounds" => -1, "effectmsg" => "`3Your accelerated cellular regeneration causes you to gain {damage} hitpoints.`0", "schema" => "module-racejoker"));
                }
                $c1 = e_rand(10, 200) / 100;
                $c2 = e_rand(10, 200) / 100;
                $c3 = e_rand(10, 200) / 100;
                $c4 = e_rand(10, 200) / 100;
                $c5 = e_rand(10, 200) / 100;
                $e1 = e_rand(10, 200) / 100;
                $e2 = e_rand(10, 200) / 100;
                $e3 = e_rand(10, 200) / 100;
                $e4 = e_rand(10, 200) / 100;
                $e5 = e_rand(10, 200) / 100;
                //Stamina Buffs
                require_once "modules/staminasystem/lib/lib.php";
                apply_stamina_buff('joker1', array("name" => "Joker Improbability Modifier: Travelling", "class" => "Travelling", "costmod" => $c1, "expmod" => $e1, "rounds" => -1, "roundmsg" => "", "wearoffmsg" => ""));
                apply_stamina_buff('joker2', array("name" => "Joker Improbability Modifier: Cooking and Carcass Cleaning", "class" => "Meat", "costmod" => $c2, "expmod" => $e2, "rounds" => -1, "roundmsg" => "", "wearoffmsg" => ""));
                apply_stamina_buff('joker3', array("name" => "Joker Improbability Modifier: Hunting", "class" => "Hunting", "costmod" => $c3, "expmod" => $e3, "rounds" => -1, "roundmsg" => "", "wearoffmsg" => ""));
                apply_stamina_buff('joker4', array("name" => "Joker Improbability Modifier: Combat", "class" => "Combat", "costmod" => $c4, "expmod" => $e4, "rounds" => -1, "roundmsg" => "", "wearoffmsg" => ""));
                apply_stamina_buff('joker5', array("name" => "Joker Improbability Modifier: ScrapBots", "class" => "ScrapBots", "costmod" => $c5, "expmod" => $e5, "rounds" => -1, "roundmsg" => "", "wearoffmsg" => ""));
            }
            break;
        case "validforestloc":
        case "validlocation":
            if (is_module_active("cities")) {
                $args[$city] = "village-{$race}";
            }
            break;
        case "moderate":
            if (is_module_active("cities")) {
                tlschema("commentary");
                $args["village-{$race}"] = sprintf_translate("City of %s", $city);
                tlschema();
            }
            break;
        case "villagetext":
            racejoker_checkcity();
            if ($session['user']['location'] == $city) {
                $args['text'] = array("`0You are standing in the heart of AceHigh.  Though relatively new, this town seems to be prospering.  The houses are built of stone and timber frames, and well-dressed gentlemen and ladies stroll about with impeccable manners.  Every now and then, one of them explodes in an astonishing flash of green light, drawing polite applause from those nearby.`n`n");
                $args['schemas']['text'] = "module-racejoker";
                $args['clock'] = "`0The great clockwork readout at the centre of the city reads `&%s`0.`n`n";
                $args['schemas']['clock'] = "module-racejoker";
                if (is_module_active("calendar")) {
                    $args['calendar'] = "`0A smaller contraption next to it reads `&%s`0, `&%s %s %s`0.`n`n";
                    $args['schemas']['calendar'] = "module-racejoker";
                }
                $args['title'] = array("%s, Home of the Jokers", $city);
                $args['schemas']['title'] = "module-racejoker";
                $args['sayline'] = "says";
                $args['schemas']['sayline'] = "module-racejoker";
                $args['talk'] = "`0Nearby some people converse politely:`n";
                $args['schemas']['talk'] = "module-racejoker";
                $new = get_module_setting("newest-{$city}", "cities");
                if ($new != 0) {
                    $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid='{$new}'";
                    $result = db_query_cached($sql, "newest-{$city}");
                    $row = db_fetch_assoc($result);
                    $args['newestplayer'] = $row['name'];
                    $args['newestid'] = $new;
                } else {
                    $args['newestplayer'] = $new;
                    $args['newestid'] = "";
                }
                if ($new == $session['user']['acctid']) {
                    $args['newest'] = "`n`0As you wander your new home, you feel your jaw dropping at the wonders around you.";
                } else {
                    $args['newest'] = "`n`0Wandering the village, jaw agape, is `&%s`0.";
                }
                $args['schemas']['newest'] = "module-racejoker";
                $args['section'] = "village-{$race}";
                $args['stablename'] = "Mike's Chop Shop";
                $args['schemas']['stablename'] = "module-racejoker";
                $args['gatenav'] = "Village Gates";
                $args['schemas']['gatenav'] = "module-racejoker";
                unblocknav("stables.php");
            }
            break;
    }
    return $args;
}
        $session['user']['gems'] -= $stakecost;
        debuglog("spent " . $stakecost . " cigarettes on a housing stake.");
        break;
    case "buymasonry":
        output("You hand over your payment.  Suzie reaches beneath the counter and brings up a heavy-looking metal toolbox.`n`n\"`6Right, 'ere you go - 'ammers, chisels, trowels, fillers, spirit level, all sorts in there.  Little packets o' cement mix an' everythin'.`0\"`n`nYou thank Suzie, and stuff the heavy toolbox into your backpack.`n`n");
        give_item('toolbox_masonry');
        $session['user']['gems'] -= $toolcost;
        break;
    case "buycarpentry":
        output("You hand over your payment.  Suzie reaches beneath the counter and brings up a heavy-looking metal toolbox.`n`n\"`6Right, 'ere you go - every type of 'and saw imaginable, planes, sandpaper, nails, drills, all sorts in there.  'ave fun with that!`0\"`n`nYou thank Suzie, and stuff the heavy toolbox into your backpack.`n`n");
        give_item('toolbox_carpentry');
        $session['user']['gems'] -= $toolcost;
        break;
    case "buydecorating":
        output("You hand over your payment.  Suzie reaches beneath the counter and brings up a heavy-looking metal toolbox splattered with paint.`n`n\"`6Right, 'ere you go - all sorts o' paint, brushes, thinners, stud finder, nails, tacks, lots o' good stuff.  'ave fun with that!`0\"`n`nYou thank Suzie, and stuff the heavy toolbox into your backpack.`n`n");
        give_item('toolbox_decorating');
        $session['user']['gems'] -= $toolcost;
        break;
    case "explain":
        output("Suzie stands up, hitching her toolbelt back up to her hips.  \"`6You wanna build a house, right?  Well, first you've gotta understand that it's not something you can really do on your own.  Ye'll have to get yer friends to help out.`0\"  She grins.  \"`6If ye've got any, o'course.  Next, you'll 'ave to sort out the tax, and stake yer claim.  It's a hundred cigs for a stake.  There can only be four houses in a square klick, so ye'd better get crackin' before all the good spots are taken.  Next, gather some wood and stone - we can lend you the tools for that, if you've got the money - bring it to yer plot o' land and start buildin'.  Or, like I say, bring it to yer plot, drop it on the floor an' kick back while your mates knock a house together for you.  Either way, you'll need carpentry an' masonry tools for that too.  All the costs are figured by the day, an' don't worry about bringing the tools back - there's a beacon inside the box that my lads'll find and bring it back for me at midnight.`0\"`n`nShe takes a sip of a very grimy cup of tea as she continues.  \"`6So it's probably not a good idea to go rentin' tools at eleven at night, although some folks do it anyway.  Lot of nutters around 'ere.  Anyway.  We pretty much just do three seperate kits for three different jobs - masonry, carpentry, an' decoratin'.  Decoratin' ones come wi' paint an' that too, and ye can use as much of it as yer like, all one price.  The masonry ones have the kit in 'em to get the rock in the first place, an' the carpentry toolboxes have gear to chop down trees too.`0\"`n`n\"`#What - ladders, band saws, axes, straps, all that stuff in one little toolbox?`0\" you say, suspicious.  \"`#It sounds a bit... well...`0\"`n`nSuzie nods.  \"`6Improbable, aye, I know.  What gets me tickled is that people'd rather stick these bloody heavy toolboxes in their backpacks than carry 'em around by the 'andles.  Well, there's nowt as queer as folk.  Now what'll it be?`0\"");
        break;
}
addnav("Services");
if ($session['user']['gems'] >= $stakecost && !has_item('housing_stake')) {
    //Ask the player if they'd like to buy a stake
    addnav("Buy a land claim stake (100 cigarettes)", "runmodule.php?module=improbablehousing&op=landregistry&sub=buystake");
} else {
    if ($session['user']['gems'] < $stakecost) {
        addnav("You don't have enough cigarettes to buy a stake", "");
    } else {
        addnav("You already have a land claim stake.", "");
    }
    improbablehousing_sethousedata($house);
} else {
    if ($takeitem) {
        if ($takeall) {
            $q = $house['data']['store'][$takeitem];
            // for ($i=0; $i<$q; $i++){
            // give_item($takeitem,false,false,true);
            // $house['data']['store'][$takeitem]-=1;
            // }
            give_multiple_items($takeitem, $q);
            $house['data']['store'][$takeitem] -= $q;
            load_inventory();
            output("Okay.  You pick up every single one, and stuff them all into your Backpack.`n`n");
        } else {
            give_item($takeitem);
            $house['data']['store'][$takeitem] -= 1;
            output("Okay.  You pick up the item and stuff it into your Backpack.`n`n");
        }
        improbablehousing_sethousedata($house);
    }
}
output("You can drop materials directly into this Dwelling, if you like.  However, once materials have been dropped in a Dwelling, they can only be used for construction within this Dwelling.  Only the Dwelling owner (or someone with an equivalent key) can remove them from the Dwelling.  This can help prevent materials from going missing unexpectedly (or, if you prefer, being pinched by Thieving Midget Bastards or Other Unsavoury Types), and it can be a nice surprise for the Dwelling owner.`n`n");
output("Currently, this Materials Store holds:`n");
addnav("Give Materials");
foreach ($house['data']['store'] as $storeitem => $number) {
    $qty = has_item_quantity($storeitem);
    if ($qty > 0) {
        $hasitems = 1;
        addnav(array("Give a %s (you have %s)", get_item_setting("verbosename", $storeitem), $qty), "runmodule.php?module=improbablehousing&op=store&giveiitem={$storeitem}&hid={$hid}&rid={$rid}");
    }
function improbablehousing_furnitureshop_run()
{
    global $session;
    page_header("Cadfael's Furniture");
    //have the beds and such allowed to be carried in backpack (insert suitable hundred-kilo-bed-in-backpack-lols) or carried by a secondary character in a new Inventory space (we'll call it Delivery Boy - will need a suitably silly photo).
    switch (httpget('op')) {
        case "start":
            output("Cadfael greets you with a preposterously strong Welsh accent.  \"`3Well hey there!  Take a look around, all one 'undred per cent natural and me own work!`0\"`n`n");
            //find items that are furniture!
            $furniture = get_items_with_settings("furniture");
            //debug($furniture);
            usort($furniture, 'sortbyprice');
            rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
            foreach ($furniture as $sort => $vals) {
                $key = $vals['item'];
                $classcount += 1;
                $class = $classcount % 2 ? "trdark" : "trlight";
                rawoutput("<tr class='{$class}'><td>");
                if ($vals['image']) {
                    rawoutput("<table width=100% cellpadding=0 cellspacing=0><tr><td width=100px align=center><img src=\"images/items/" . $vals['image'] . "\"></td><td>");
                }
                output("`b%s`b`n", stripslashes($vals['verbosename']));
                output("%s`0`n", stripslashes($vals['description']));
                if ($vals['weight']) {
                    output("Weight: %s kg`n`0", $vals['weight']);
                }
                rawoutput("<table width=100%><tr><td width=50%>");
                if ($vals['goldcost'] && $vals['gemcost']) {
                    $disp = "`b" . number_format($vals['goldcost']) . "`b Requisition and `b" . number_format($vals['gemcost']) . "`b Cigarettes";
                    $sdisp = $vals['goldcost'] . " Req, " . $vals['gemcost'] . " Cigs";
                } else {
                    if ($vals['goldcost']) {
                        $disp = "`b" . number_format($vals['goldcost']) . "`b Requisition";
                        $sdisp = $vals['goldcost'] . " Req";
                    } else {
                        $disp = "`b" . number_format($vals['goldcost']) . "`b Cigarettes";
                        $sdisp = $vals['goldcost'] . " Cigs";
                    }
                }
                if ($session['user']['gold'] >= $vals['goldcost'] && $session['user']['gems'] >= $vals['gemcost']) {
                    addnav("Buy Items");
                    addnav(array("%s (%s)", $vals['verbosename'], $sdisp), "runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key, true);
                    addnav("", "runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key);
                    rawoutput("<a href=\"runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key . "\">Buy for " . appoencode($disp) . "</a><br />");
                } else {
                    output("Price: %s`n", $disp);
                    output("`&You can't afford this item right now.`0`n");
                }
                rawoutput("</td></tr></table>");
                if ($vals['image']) {
                    rawoutput("</td></tr></table>");
                }
                rawoutput("</td></tr>");
            }
            rawoutput("</td></tr></table>");
            break;
        case "buy":
            $item = httpget("item");
            $goldcost = get_item_setting("goldcost", $item);
            $gemcost = get_item_setting("gemcost", $item);
            $name = get_item_setting("verbosename", $item);
            if ($goldcost && $gemcost) {
                $disp = "`b" . number_format($goldcost) . "`b Requisition and `b" . number_format($gemcost) . "`b Cigarettes";
            } else {
                if ($goldcost) {
                    $disp = "`b" . number_format($goldcost) . "`b Requisition";
                } else {
                    $disp = "`b" . number_format($goldcost) . "`b Cigarettes";
                }
            }
            output("Cadfael nods.  \"`3So, you're after a %s then, are ye?  That'll be %s, please.`0\"`n`n", $name, $disp);
            addnav("Confirmation");
            addnav("Confirm sale", "runmodule.php?module=improbablehousing_furnitureshop&op=confirmbuy&item=" . $item);
            addnav("Wait, I've changed my mind!", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
            break;
        case "confirmbuy":
            $item = httpget("item");
            $goldcost = get_item_setting("goldcost", $item);
            $gemcost = get_item_setting("gemcost", $item);
            $name = get_item_setting("verbosename", $item);
            $session['user']['gold'] -= $goldcost;
            $session['user']['gems'] -= $gemcost;
            give_item($item);
            output("You hand over your hard-won currency to Cadfael, who grins and says \"`3Ah, much obliged!  Pleasure doin' business... with...`0\" he stops, bemused.  \"`3Are... are you trying to fit that into a `ibackpack?`i`0\"`n`nAfter several minutes of grunting and sweating, your backpack now resembles a... well, a barely-held-together layer of canvas stretched drum-tight into the shape of a %s.  With a very small %s bent double underneath.  Cadfael shakes his head and mutters something about it taking all sorts.`n`n", $name, $session['user']['race']);
            break;
        case "drop":
            page_header("");
            $itemid = httpget('item');
            debug($itemid);
            $hid = httpget('hid');
            require_once "modules/improbablehousing/lib/lib.php";
            $house = improbablehousing_gethousedata($hid);
            $rid = httpget('rid');
            $slot = httpget('slot');
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['stamina'] = get_item_pref("sleepslot_stamina", $itemid);
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['name'] = get_item_pref("sleepslot_name", $itemid);
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['desc'] = get_item_pref("sleepslot_desc", $itemid);
            use_item($itemid);
            improbablehousing_sethousedata($house);
            addnav("Continue");
            addnav(array("Return to %s", $house['data']['rooms'][$rid]['name']), "runmodule.php?module=improbablehousing&op=interior&hid=" . $hid . "&rid=" . $rid);
            break;
    }
    if (httpget('op') != "drop") {
        addnav("Exit");
        addnav("Back to the Outpost", "village.php");
    }
    page_footer();
    return true;
}
function rail_collector_findcard()
{
    // returns false if the user has no card case, or if they've reached their cardluck limit.
    // otherwise picks a random card to give them and returns true.
    global $session;
    if (rail_hascard("cardcase")) {
        debug("Got the case");
        $cardstoday = get_module_pref("cardstoday", "rail_collector");
        if ($cardstoday < get_module_pref("cardluck", "rail_collector")) {
            $jokerchance = get_module_setting("jokerchance", "rail_collector");
            $joke = false;
            if (rail_hascard("railcard50")) {
                $joke = true;
            }
            if (!$joke && e_rand(1, $jokerchance) == 1) {
                // card is a joker
                give_item("railcard50");
            } else {
                // pick a card, any card!
                $suit = e_rand(0, 4);
                $pips = e_rand(0, 9);
                $cardgiven = "railcard" . $suit . $pips;
                give_item($cardgiven);
            }
            $cardstoday = $cardstoday + 1;
            set_module_pref("cardstoday", $cardstoday, "rail_collector");
            return true;
        } else {
            debug("No more cards for you today...");
            // output("No more cards for you today!!!");
            return false;
        }
    } else {
        // output("You have no place to put a card!");
        return false;
    }
}
<?php

global $session;
page_header("Rebooting Dwelling");
require_once "modules/improbablehousing/lib/lib.php";
$hid = httpget('hid');
$house = improbablehousing_gethousedata($hid);
$house['data'] = array("rooms" => array(), "name" => "Empty Plot belonging to " . $session['user']['name'], "buildjobs" => array(0 => array("name" => "Initial Dwelling Construction", "jobs" => array(0 => array("name" => "Add wood", "iitems" => array("wood" => 1, "toolbox_carpentry" => 1), "actions" => array("Carpentry" => 1), "req" => 100, "done" => 0, "desc" => "You set about hammering and sawing.  Before too long, the dwelling's one step closer to completion."), 1 => array("name" => "Add stone", "iitems" => array("stone" => 1, "toolbox_masonry" => 1), "actions" => array("Masonry" => 1), "req" => 25, "done" => 0, "desc" => "You set about chiseling and tinkering.  Before too long, the dwelling's one step closer to completion.")), "completioneffects" => array("changes" => array("name" => "One-room dwelling belonging to " . $session['user']['name'], "desc_exterior" => "You see a single-room dwelling belonging to " . $session['user']['name']), "newrooms" => array(0 => array("name" => "Main Room", "size" => 1, "desc" => "You're standing in a small, undecorated room.", "sleepslots" => array())), "msg" => "The dwelling is now complete!"))), "desc_exterior" => "You see a sign indicating that a plot of land has been reserved for " . $session['user']['name']);
improbablehousing_sethousedata($house);
invalidatedatacache("housing/housing_location_" . $loc);
$loc = get_module_pref("worldXYZ", "worldmapen");
output("Dwelling rebooted.  Dwelling reconstructor item granted.");
give_item("dwelling_reconstructor");
addnav("Exit");
addnav("Back to the World Map", "runmodule.php?module=worldmapen&op=continue");
page_footer();
function improbablehousing_furnitureshop_run()
{
    global $session;
    page_header("Cadfael's Furniture");
    //have the beds and such allowed to be carried in backpack (insert suitable hundred-kilo-bed-in-backpack-lols) or carried by a secondary character in a new Inventory space (we'll call it Delivery Boy - will need a suitably silly photo).
    switch (httpget('op')) {
        case "start":
            output("Cadfael greets you with a preposterously strong Welsh accent.  \"`3Well hey there!  Take a look around, all one 'undred per cent natural and me own work!`0\"`n`n");
            //find items that are furniture!
            $furniture = get_items_with_settings("furniture");
            //debug($furniture);
            usort($furniture, 'sortbyprice');
            rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
            foreach ($furniture as $sort => $vals) {
                $key = $vals['item'];
                $classcount += 1;
                $class = $classcount % 2 ? "trdark" : "trlight";
                rawoutput("<tr class='{$class}'><td>");
                if ($vals['image']) {
                    rawoutput("<table width=100% cellpadding=0 cellspacing=0><tr><td width=100px align=center><img src=\"images/items/" . $vals['image'] . "\"></td><td>");
                }
                output("`b%s`b`n", stripslashes($vals['verbosename']));
                output("%s`0`n", stripslashes($vals['description']));
                if ($vals['weight']) {
                    output("Weight: %s kg`n`0", $vals['weight']);
                }
                rawoutput("<table width=100%><tr><td width=50%>");
                if ($vals['goldcost'] && $vals['gemcost']) {
                    $disp = "`b" . number_format($vals['goldcost']) . "`b Requisition and `b" . number_format($vals['gemcost']) . "`b Cigarettes";
                    $sdisp = $vals['goldcost'] . " Req, " . $vals['gemcost'] . " Cigs";
                } else {
                    if ($vals['goldcost']) {
                        $disp = "`b" . number_format($vals['goldcost']) . "`b Requisition";
                        $sdisp = $vals['goldcost'] . " Req";
                    } else {
                        $disp = "`b" . number_format($vals['goldcost']) . "`b Cigarettes";
                        $sdisp = $vals['goldcost'] . " Cigs";
                    }
                }
                if ($session['user']['gold'] >= $vals['goldcost'] && $session['user']['gems'] >= $vals['gemcost']) {
                    addnav("Buy Items");
                    addnav(array("%s (%s)", $vals['verbosename'], $sdisp), "runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key, true);
                    addnav("", "runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key);
                    rawoutput("<a href=\"runmodule.php?module=improbablehousing_furnitureshop&op=buy&item=" . $key . "\">Buy for " . appoencode($disp) . "</a><br />");
                } else {
                    output("Price: %s`n", $disp);
                    output("`&You can't afford this item right now.`0`n");
                }
                rawoutput("</td></tr></table>");
                if ($vals['image']) {
                    rawoutput("</td></tr></table>");
                }
                rawoutput("</td></tr>");
            }
            rawoutput("</td></tr></table>");
            addnav("Custom Furniture");
            addnav("Enquire about Custom Furniture", "runmodule.php?module=improbablehousing_furnitureshop&op=custom&sub=start");
            break;
        case "buy":
            $item = httpget("item");
            $goldcost = get_item_setting("goldcost", $item);
            $gemcost = get_item_setting("gemcost", $item);
            $name = get_item_setting("verbosename", $item);
            if ($goldcost && $gemcost) {
                $disp = "`b" . number_format($goldcost) . "`b Requisition and `b" . number_format($gemcost) . "`b Cigarettes";
            } else {
                if ($goldcost) {
                    $disp = "`b" . number_format($goldcost) . "`b Requisition";
                } else {
                    $disp = "`b" . number_format($goldcost) . "`b Cigarettes";
                }
            }
            output("Cadfael nods.  \"`3So, you're after a %s then, are ye?  That'll be %s, please.`0\"`n`n", $name, $disp);
            addnav("Confirmation");
            addnav("Confirm sale", "runmodule.php?module=improbablehousing_furnitureshop&op=confirmbuy&item=" . $item);
            addnav("Wait, I've changed my mind!", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
            break;
        case "confirmbuy":
            $item = httpget("item");
            $goldcost = get_item_setting("goldcost", $item);
            $gemcost = get_item_setting("gemcost", $item);
            $name = get_item_setting("verbosename", $item);
            $session['user']['gold'] -= $goldcost;
            $session['user']['gems'] -= $gemcost;
            give_item($item);
            output("You hand over your hard-won currency to Cadfael, who grins and says \"`3Ah, much obliged!  Pleasure doin' business... with...`0\" he stops, bemused.  \"`3Are... are you trying to fit that into a `ibackpack?`i`0\"`n`nAfter several minutes of grunting and sweating, your backpack now resembles a... well, a barely-held-together layer of canvas stretched drum-tight into the shape of a %s.  With a very small %s bent double underneath.  Cadfael shakes his head and mutters something about it taking all sorts.`n`n", $name, $session['user']['race']);
            break;
        case "drop":
            page_header("");
            $itemid = httpget('item');
            debug($itemid);
            $hid = httpget('hid');
            require_once "modules/improbablehousing/lib/lib.php";
            $house = improbablehousing_gethousedata($hid);
            $rid = httpget('rid');
            $slot = httpget('slot');
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['stamina'] = get_item_pref("sleepslot_stamina", $itemid);
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['name'] = get_item_pref("sleepslot_name", $itemid);
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['desc'] = get_item_pref("sleepslot_desc", $itemid);
            $house['data']['rooms'][$rid]['sleepslots'][$slot]['multicapacity'] = get_item_pref("sleepslot_multicapacity", $itemid);
            use_item($itemid);
            improbablehousing_sethousedata($house);
            addnav("Continue");
            addnav(array("Return to %s", $house['data']['rooms'][$rid]['name']), "runmodule.php?module=improbablehousing&op=interior&hid=" . $hid . "&rid=" . $rid);
            break;
        case "custom":
            $sub = httpget('sub');
            switch ($sub) {
                case "start":
                    output("\"`3Oh yeah, I get lots of custom orders,`0\" says Cadfael, grinning.  \"`3Mostly for Mutants and Robots.  Interestin' stuff, really, tryin' to figure out where all the extra arms and legs would go.  I can make any of my furniture pieces look like just about anythin'.  Custom work'll set ye back five ciggies as a startin' price, an' goes up from there according to complexity.  You got somethin' in mind?`0\"`n`n`JCadfael can take any piece of furniture intended for sleeping on and assign a new name and description to the sleeping slot that it'll take up.  If you want your houseguests to be able to sleep on top of a bookcase, or inside a cleverly-concealed secret foldaway bed, or in a zero-gravity chamber (yes, Cadfael's carpentry skills are `ijust that good`i), then bring one of his furniture pieces here.`0`n`n");
                    $furniture = get_items_with_prefs("furniture");
                    if (is_array($furniture)) {
                        addnav("Customize Furniture");
                        foreach ($furniture as $key => $vals) {
                            addnav(array("Customize %s", $vals['verbosename']), "runmodule.php?module=improbablehousing_furnitureshop&op=custom&sub=desc&item=" . $key);
                        }
                    }
                    addnav("Return");
                    addnav("Back to the Furniture List", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
                    break;
                case "desc":
                    //get the descriptions from the player
                    $item = httpget('item');
                    output("\"`3Right, then - what'll this be called?`0\"`n`n`0Enter a title for the furniture piece here.  This is what's displayed in the nav links in your Dwelling - it'll read something like \"(your title) Available\" or \"(your title) Occupied by Admin CavemanJoe\" - you've got 25 characters to play about with, and no colour or formatting codes are allowed here.`n`n");
                    $oldtitle = get_item_pref("sleepslot_name", $item);
                    $olddesc = get_item_pref("sleepslot_desc", $item);
                    rawoutput("<form action='runmodule.php?module=improbablehousing_furnitureshop&op=custom&sub=confirm&item=" . $item . "' method='POST'>");
                    rawoutput("<input id='newtitle' name='newtitle' width='25' maxlength='25' value='" . $oldtitle . "'>");
                    output("`n`nNow enter a description for the new furniture piece.  This is what's displayed to players when they settle down for a good night's kip.  The longer the description, the more it'll cost.  You can use colour and formatting codes here - remember to use ``n for new lines.`n`n");
                    rawoutput("<textarea name='newdesc' id='newdesc' rows='6' cols='60'>" . $olddesc . "</textarea><input type=submit></form>");
                    addnav("Return");
                    addnav("Back to the Furniture List", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
                    addnav("", "runmodule.php?module=improbablehousing_furnitureshop&op=custom&sub=confirm&item=" . $item);
                    break;
                case "confirm":
                    $newtitle = httppost('newtitle');
                    $newdesc = httppost('newdesc');
                    $item = httpget('item');
                    $newdesc = str_replace("\n", "`n", $newdesc);
                    $newtitle = str_replace("`", "", $newtitle);
                    $newtitle = substr($newtitle, 0, 25);
                    $newtitle = stripslashes($newtitle);
                    $newdesc = stripslashes($newdesc);
                    //show the descriptions
                    output("Your new title is:`n%s`0`n`nYour new description is:`n%s`0`n`n", $newtitle, $newdesc);
                    $cigcost = 5 + floor(strlen($newdesc) / 50);
                    output("This much work will cost %s cigarettes.`n`n", $cigcost);
                    set_item_pref("proposed_sleepslot_name", $newtitle, $item);
                    set_item_pref("proposed_sleepslot_desc", $newdesc, $item);
                    if ($session['user']['gems'] >= $cigcost) {
                        addnav("Continue");
                        addnav("Pay the man!", "runmodule.php?module=improbablehousing_furnitureshop&op=custom&sub=confirmfinal&item=" . $item . "&cost=" . $cigcost);
                    } else {
                        output("You don't have enough cigarettes for that!`n`n");
                    }
                    addnav("Return");
                    addnav("Back to the Furniture List", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
                    break;
                case "confirmfinal":
                    //take the cigaretes, change the prefs
                    $item = httpget('item');
                    $cost = httpget('cost');
                    $session['user']['gems'] -= $cost;
                    output("Cadfael takes your cigarettes and furniture with a smile, and disappears into the back of the shop.  You hear muffled sounds of sawing, hammering, swearing and so forth, and after half an hour or so he returns.  \"`3Here you go - might not look much different `inow,`i but wait 'til you get it in yer house.`0\"`n`nYour furniture is now customized!");
                    $newtitle = get_item_pref("proposed_sleepslot_name", $item);
                    $newdesc = get_item_pref("proposed_sleepslot_desc", $item);
                    set_item_pref("verbosename", "Customized Furniture (" . $newtitle . ")", $item);
                    set_item_pref("sleepslot_name", $newtitle, $item);
                    set_item_pref("sleepslot_desc", $newdesc, $item);
                    set_item_pref("description", "This furniture was modified at Cadfael's shop in Improbable Central.", $item);
                    addnav("Return");
                    addnav("Back to the Furniture List", "runmodule.php?module=improbablehousing_furnitureshop&op=start");
                    break;
            }
            break;
    }
    if (httpget('op') != "drop") {
        addnav("Exit");
        addnav("Back to the Outpost", "village.php");
    }
    page_footer();
    return true;
}