function monsterrepellentspray_use($args)
{
    global $session;
    if ($args['context'] == "fight") {
        apply_buff('rspray_fight', array("startmsg" => "`#You pull out a can of Monster Repellent Spray, and spray it liberally on the enemy!`n", "name" => "`^Repellent Spray Attack", "rounds" => 10, "badguyatkmod" => 0.4, "badguydefmod" => 0.4, "roundmsg" => "{badguy} is coughing, choking and all runny-nosed, and cannot attack or defend as effectively!", "wearoff" => "The effects of your Monster Repellent Spray seem to have worn off...`n", "expireafterfight" => 1, "schema" => "iitems-catcher"));
    } else {
        apply_buff('rspray_normal', array("name" => "`^Repellent Spray", "rounds" => -1, "badguyatkmod" => 0.8, "badguydefmod" => 0.8, "roundmsg" => "{badguy} can't stand the smell of your Monster Repellent Spray, and doesn't want to get too close!", "schema" => "iitems-catcher"));
        set_item_pref("encounterchance", 50, "worldmapen");
        output("You liberally douse yourself with an entire can of Monster Repellent Spray.  For the rest of this game day, your chances of encountering a monster on the Island Map have been halved, and monsters you do encounter will be reluctant to attack you as hard.`n`n");
    }
    return $args;
}
function hunterslodge_healthinsurance_use($args)
{
    global $session;
    $id = $args['id'];
    $expirationtime = get_item_pref("expiration_timestamp", $id);
    if (!$expirationtime) {
        $expires = time() + 604800;
        set_item_pref("expiration_timestamp", $expires, $id);
        output("`0This is the first time you've used this certificate.  It will expire exactly one week from now.`n`n");
    } else {
        if (time() > $expirationtime) {
            output("This certificate has now expired!`n`n");
            delete_item($id);
        } else {
            require_once "lib/datetime.php";
            $expirein = reltime($expirationtime, false);
            output("This certificate will expire in %s.`n`n", $expirein);
        }
    }
    $args['destroyafteruse'] = false;
    return $args;
}
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 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 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);
        }
    }
    if ($acctid == $session['user']['acctid']) {
        //saves a query over loading the inventory every time
        if (!isset($inventory) || !is_array($inventory)) {
            load_inventory();
        } else {
            if (!isset($itemsettings) || !is_array($itemsettings)) {
                load_item_settings();
            }
            $inventory[$key] = $itemsettings[$item];
        }
    }
    return $key;
}
function improbablehousing_mementos_run()
{
    global $session;
    page_header("Memento Effects");
    $hid = httpget("hid");
    $rid = httpget("rid");
    $itemid = httpget("itemid");
    require_once "modules/improbablehousing/lib/lib.php";
    $house = improbablehousing_gethousedata($hid);
    $roomname = $house['data']['rooms'][$rid]['name'];
    $roomdesc = $house['data']['rooms'][$rid]['desc'];
    $pointsavailable = $session['user']['donation'] - $session['user']['donationspent'];
    switch (httpget('op')) {
        case "start":
            output("You can specify some Effect Text to be shown when a player with a specific Memento enters this room.  This costs one Supporter Point per two characters of Effect Text that you want to use.  The extra text cost is independent of the cost to create Mementos (so if you have thirty Mementos, all alike, you only pay once for the effect text).  For example, if you'd made a Memento called 'Bucket of Soapy Frogs' and gave it to someone, you could set things up so that a frog could leap out of the bucket and whisper a secret password to the bearer of this frog when they enter this room.  Each room can have a different thing happen with a different Memento, and each Memento can have something different happen in any given room - the only limit is your own imagination.`n`nHere's a list of all the Mementos that currently exist that were made by you, along with the Effect Text they'll output when the bearer enters this room.`n`n");
            //get all the current Mementos in the game that were made by this player
            $sql = "SELECT * FROM " . db_prefix("items_prefs") . " WHERE setting='memento_author' AND value='" . $session['user']['acctid'] . "'";
            $result = db_query($sql);
            $preload = array();
            while ($row = db_fetch_assoc($result)) {
                $preload[$row['id']] = $row['id'];
            }
            load_item_prefs($preload);
            //debug($preload);
            //group them together by original memento
            $originals = array();
            foreach ($preload as $id) {
                $original = get_item_pref("memento_originalitem", $id);
                if ($original) {
                    $originals[$original] = get_item_prefs($id);
                }
            }
            //debug($originals);
            rawoutput("<table width=100% style='border: dotted 1px #000000;'>");
            $classcount = 1;
            foreach ($originals 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']));
                if ($prefs["memento_dwellingtrigger_" . $hid . "_" . $rid]) {
                    output("`bExtra text for this room:`b`n%s`0`n`n", $prefs["memento_dwellingtrigger_" . $hid . "_" . $rid]);
                }
                rawoutput("<a href='runmodule.php?module=improbablehousing_mementos&op=settext&itemid=" . $id . "&hid=" . $hid . "&rid=" . $rid . "'>Set dwelling text</a>");
                addnav("", "runmodule.php?module=improbablehousing_mementos&op=settext&itemid=" . $id . "&hid=" . $hid . "&rid=" . $rid);
                rawoutput("</td></tr>");
            }
            rawoutput("</table>");
            //okay it's getting late and you're f*****g falling asleep.  Do this in the morning:
            /*
            Get the text that the player wants, and put it in set_item_pref("memento_dwellingtrigger_".$hid."_".$rid);
            			Copy that pref to all the Mementos that are copies of the same original
            */
            break;
        case "settext":
            require_once "lib/forms.php";
            output("You're about to set the Effect Text associated with this Memento, in this room, of this Dwelling.  When a player enters this room with this Memento, this text will be added on to the end of your room description.  You can use all the same colour and formatting codes that you use when Decorating.`n`n");
            //previewfield("newtext","`~",false,false,array("type"=>"textarea", "class"=>"input", "cols"=>"60", "rows"=>"9", "onKeyDown"=>"sizeCount(this);"));
            rawoutput("<form action='runmodule.php?module=improbablehousing_mementos&op=preview&itemid=" . $itemid . "&hid=" . $hid . "&rid=" . $rid . "' method='POST'>");
            addnav("", "runmodule.php?module=improbablehousing_mementos&op=preview&itemid=" . $itemid . "&hid=" . $hid . "&rid=" . $rid);
            previewfield_countup("newtext");
            rawoutput("<br /><input type=submit>");
            rawoutput("</form>");
            addnav("Back");
            addnav("Memento Effects Main Menu", "runmodule.php?module=improbablehousing_mementos&op=start&hid={$hid}&rid={$rid}");
            break;
        case "preview":
            $newtext = httppost("newtext");
            output("The new Effect Text you've chosen to apply is shown below.`n`n-----`n%s`n-----`0`n`n`bRemember`b, this Effect Text applies `ionly`i to this particular Memento (%s`0), in conjunction with this particular room (%s`0).`n`n", $newtext, get_item_pref("verbosename", $itemid), $roomname);
            $cost = ceil(strlen($newtext) / 2);
            output("Total cost: `5`b%s`b Supporter Points`0", $cost);
            if ($pointsavailable >= $cost) {
                addnav("Continue");
                addnav("Buy it!", "runmodule.php?module=improbablehousing_mementos&op=buy&itemid=" . $itemid . "&hid=" . $hid . "&rid=" . $rid . "&text=" . urlencode($newtext));
            } else {
                addnav("Oh dear.");
                addnav("Not enough Supporter Points!", "");
            }
            addnav("Back");
            addnav("Memento Effects Main Menu", "runmodule.php?module=improbablehousing_mementos&op=start&hid={$hid}&rid={$rid}");
            break;
        case "buy":
            $newtext = httpget('text');
            debug($newtext);
            $newtext = urldecode($newtext);
            debug($newtext);
            $cost = ceil(strlen($newtext) / 2);
            $session['user']['donationspent'] += $cost;
            //log purchase
            $sql = "INSERT INTO " . db_prefix("purchaselog") . " (acctid,purchased,amount,data,giftwrap,timestamp) VALUES ('" . $session['user']['acctid'] . "','memento_housing_interaction','" . $cost . "','none','0','" . date("Y-m-d H:i:s") . "')";
            //get all the items like this and apply the pref to all of them
            $sql = "SELECT * FROM " . db_prefix("items_prefs") . " WHERE setting='memento_originalitem' AND value='" . $itemid . "'";
            $result = db_query($sql);
            while ($row = db_fetch_assoc($result)) {
                set_item_pref("memento_dwellingtrigger_" . $hid . "_" . $rid, $newtext, $row['id']);
            }
            set_item_pref("memento_dwellingtrigger_" . $hid . "_" . $rid, $newtext, $itemid);
            output("Your new Effect Text is set!");
            addnav("Back");
            addnav("Memento Effects Main Menu", "runmodule.php?module=improbablehousing_mementos&op=start&hid={$hid}&rid={$rid}");
            break;
    }
    addnav("Back");
    addnav("Return to the Dwelling", "runmodule.php?module=improbablehousing&op=interior&hid={$hid}&rid={$rid}");
    page_footer();
    return true;
}
function mementos_feelgood_run()
{
    global $session;
    page_header("Memento Attributes");
    $mould = httpget('mould');
    $itemname = get_item_pref("verbosename", $mould);
    require_once "modules/mementos_feelgood/attributes.php";
    $attributes = mementos_feelgood_getattributes();
    switch (httpget('op')) {
        case "choosestat":
            output("`bWhat are Memento Attributes for?`b`nLet someone know how you feel about them by giving them a special Memento with a stat enhancement.  Like Mementos in themselves, these stat enhancements don't do anything to your character's abilities - they're intended only as trifles to flatter and delight.`n`nSee someone engage in a particularly special bit of rhyming roleplay?  Give them a Red Music Box of +1 Musical Mastery.  If someone else gives the player another Memento with the Musical Mastery stat attached, then their Bio will show that they have two points in Musical Mastery.  You get the idea, I'm sure - it's a tool for showing your appreciation or admiration in a playful way.`n`n`bNo really, what are Memento Attributes `ifor?`i  What do they `ido?`i`b`nThey make people feel good.  That's it!`n`n`bHow much do they cost?`b`nNothing!  They're free!  You can only apply one Attribute to any given Memento type, mind - and you can't change your mind afterwards, so choose carefully.`n`n`bHow to use them`b`nFigure out what you want your Memento to mean, and look for something in the list below that's a good match.  When you click, that Attribute will be applied to all the Mementos that came out of this Mould, and all the Mementos that will ever come out of it in the future.`n`n");
            foreach ($attributes as $key => $vals) {
                rawoutput("<strong><a href='runmodule.php?module=mementos_feelgood&op=confirm&assignstat=" . $key . "&mould=" . $mould . "'></strong>" . stripslashes(appoencode($vals['name'])) . "</a>: " . stripslashes(appoencode($vals['description'])) . "<br />");
                addnav("", "runmodule.php?module=mementos_feelgood&op=confirm&assignstat=" . $key . "&mould=" . $mould);
            }
            break;
        case "confirm":
            $assignstat = httpget('assignstat');
            $statname = $attributes[$assignstat]['name'];
            output("You're about to assign the Attribute \"%s\" to the Memento mould \"%s\".  Are you sure you want to do that?", $statname, $itemname);
            addnav("Yes!");
            addnav("Do it!", "runmodule.php?module=mementos_feelgood&op=confirmfinal&assignstat=" . $assignstat . "&mould=" . $mould);
            addnav("No wait hang on");
            addnav("That's not what I want to do AT ALL.", "runmodule.php?module=mementos_feelgood&op=choosestat&mould=" . $mould);
            break;
        case "confirmfinal":
            $assignstat = httpget('assignstat');
            output("Attribute applied!");
            //get all the items like this and apply the pref to all of them
            $sql = "SELECT * FROM " . db_prefix("items_prefs") . " WHERE setting='memento_originalitem' AND value='" . $mould . "'";
            $result = db_query($sql);
            while ($row = db_fetch_assoc($result)) {
                debug("Setting pref for itemid " . $row['id']);
                set_item_pref("memento_feelgood_attribute", $assignstat, $row['id']);
            }
            set_item_pref("memento_feelgood_attribute", $assignstat, $mould);
            break;
    }
    addnav("Return");
    addnav("Memento Forge", "runmodule.php?module=mementos&op=start");
    page_footer();
    return true;
}
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;
}