function funddrive_dohook($hook, $args)
{
    switch ($hook) {
        case 'donation_adjustments':
            global $session;
            if ($args['amount'] > 0) {
                increment_module_setting('base', $args['amount']);
            }
            break;
        case 'everyfooter':
            $settings = get_all_module_settings();
            if (!is_array($args['paypal'])) {
                $args['paypal'] = [];
            }
            $percent = round($settings['base'] / $settings['goal'], 2) * 100;
            if ($percent > 100) {
                $percent = 100;
            }
            $fillWidth = round(1.5 * $percent, 0);
            $unfilled = 150 - $fillWidth;
            //You may want to modify the bar to fit your site's needs. - Stephen
            $bar = appoencode("{$settings['message']}`n\n                <div class='fund-drive' align='center'>\n                    <table class='fund-drive-bar' style='border: solid 1px black; background-color: black; border-collapse: collapse; width: 150px; height: 10px;'>\n                        <tr>\n                            <td class='fund-drive-filled' width='{$fillWidth}px' style='background-color: #00FF00;'>\n                            </td>\n                            <td class='fund-drive-unfilled' width='{$unfilled}px'>\n                            </td>\n                        </tr>\n                    </table>\n                </div>", true);
            array_push($args['paypal'], $bar);
            break;
    }
    return $args;
}
function emilybundle_run()
{
    global $session;
    $op = httpget("op");
    page_header("The Emily Bundle");
    $cost = get_module_setting("cost");
    $stock = get_module_setting("stock");
    $playerpoints = $session['user']['donation'] - $session['user']['donationspent'];
    switch ($op) {
        case "start":
            output("So, Improbable Island has been going for a couple of years now and it's turning into something that can keep me alive and with a roof over my head without me having to do website design.  It's turned from a hobby into a full-time job.`n`nSince then, I've gotten married, and my wife, Emily(*), has gotten increasingly frustrated with her job.  She does database work for a hospital; the pay's good, but the hours and the work itself is pretty depressing.`n`nI've noticed lately that my original goal - \"Hey, I'll write a text adventure game!\" - hasn't quite worked out the way I wanted it to, because I thought it'd be about writing.  I figured I'd have a plot, decent characters, a beginning, middle and end - you know, a story.  But lately I've been doing a lot more building of games and systems than I have building of worlds, and I'm beginning to realise that that's what I'm good at.`n`nThe Island needs a writer.`n`nA dedicated writer, so that I can be a dedicated coder.  Recently I've done all sorts of stuff with Titans, Onslaught, new Commentary, Dwellings, and all that jazz - but the last actual piece of world-building writing that I did was in Common Ground, with its time-sensitive description text.  I believe that was before Christmas.`n`nOh, and there were some lions, too.`n`nTo give you an idea of where I am right now, let's say this: the system is in place to extend that level of time-and-context-sensitive detail to every Outpost.  I just don't have any writing to go in the system.`n`nIt's not that I don't like writing, and forgive me for parping my own horn but I don't think it's that I'm not good at it (although that sentence may have been evidence to the contrary).  It's just that I have so much else to do.`n`nI need help.`n`nHey, you know... my wife is an excellent writer.`n`nHonestly I'd be doing this before too long even if I didn't need Emily to help me with the Island.  She hates her job, I love mine, and that's unfair; it's imperative that the Island support both of us if we ever want to have our own house, or raise a family.`n`nWe've done our maths and figured out how much we need per month on which to survive without Emily's workplace sorting out our health insurance (that's the biggest expense, right there), and from that, based on historical data, we've figured out how much of an advertisement boost we'd need to get the Island up to that sort of level, and from that, how much money we'd need to get together by 'x' if we want Emily to be able to quit her job by 'y', with 'y' being \"Before September.\"`n`nIn a nutshell we need to get some bread together so that we can expand our player base enough that casual everyday donations cover us both without me having to tell you all about it every time my laptop breaks, my car breaks down, or my lion gets into an argument he just can't win.`n`nSo, you can give me money so that the Island can have more juicy plot points and a better sense of place, or you can give me money so that Emily and I can be happier and spend more time together.  Both are excellent reasons.  I've got another reason for you:`n`nIntroducing the `5Emily Bundle`0!`n`nThe `5Emily Bundle`0 costs 2,500 Donator Points, and it's worth well over three times as much.  In the Emily Bundle for 2,500 Donator Points (that's twenty-five bucks, for those of you keeping track), you get:`n`n* Permanent, unlimited free Avatar picture changes (never pay to change your Avatar picture again!)`n* Permanent, unlimited free Custom Weapon changes (custom weaponry now sticks around properly!)`n* Permanent, unlimited free Custom Armour changes (likewise!)`n* Permanent, unlimited free Custom Name Colour changes`n* Permanent, inlimited free Title changes`n* Permanent, unlimited free Mount Name changes`n* Permanent, unlimited free Commentary Race Name changes`n* Ten cigarettes`n* Ten thousand Requisition tokens`n* Two extra Chronospheres`n* All your current Chronospheres refilled`n* Ten Special Comments`n* A special, strictly-limited-and-not-to-be-repeated Medal`n`nAnd if you've not already donated, you'll also get room for a ten-thousand character Extended Bio (players who've already donated already have this).`n`nNow, the Emily Bundle is limited to two hundred players.  That should give Emily and I enough of a financial boost to get this plan underway.  If something stupidly awesome happens like the whole stock running out in a day, then I might add another fifty or a hundred or so, but no more than that (I'm not going to say it's strictly limited just to stimulate demand and then make it as common as muck - I want this to be a bit special).`n`nSo, help us recruit a writer and make the Island more awesome, more quickly - grab the Emily Bundle while it's still around to grab!`n(*) Yes, I named the pickle-wench barmaid after my wife.  Looking back, I could have made a better choice for an homage.");
            addnav("Buy the Emily Bundle!");
            if ($playerpoints >= $cost) {
                addnav("Yes! (2,500 points)", "runmodule.php?module=emilybundle&op=buy");
            } else {
                addnav(array("Just %s more points!", $cost - $playerpoints), "");
            }
            break;
        case "buy":
            set_module_pref("permanent", true, "commentaryicons_customrace");
            set_module_pref("permanent", true, "titlechange");
            set_module_pref("permanent", true, "namedmount");
            set_module_pref("permanent", true, "namecolor");
            set_module_pref("permanent", true, "avatar");
            set_module_pref("permanentarmor", true, "customeq");
            set_module_pref("permanentweapon", true, "customeq");
            $session['user']['gems'] += 10;
            $session['user']['goldinbank'] += 10000;
            $curspheres = get_module_pref("slots", "daysave");
            set_module_pref("slots", $curspheres + 2, "daysave");
            set_module_pref("days", $curspheres + 2, "daysave");
            increment_module_pref("commentsleft", 10, "specialcomments");
            require_once "modules/medals.php";
            medals_award_medal("emilybundle", "Emily Bundle Supporter", "This player bought the Emily Bundle, supporting Improbable Island and its admin!", "medal_emilybundle.png");
            $session['user']['donationspent'] += $cost;
            increment_module_setting("stock", -1);
            set_module_pref("bought", 1);
            output("You've got the Emily Bundle!  Thank you so much for supporting the Island.  Have fun!`n`n");
            //todo: medal, take points, diminish stock, output thankyou
            break;
    }
    addnav("Return");
    addnav("L?Return to the Lodge", "lodge.php");
    page_footer();
}
function findthebrain_run()
{
    global $session;
    page_header("Find The Brain");
    $op = httpget("op");
    switch ($op) {
        case "start":
            output("You wander over to a wall-mounted, glass-fronted wooden box.  Behind the glass, six holes are cut into the wood.  Below the glass, six coin slots gape invitingly.  A plate mounted to the bottom of the machine reads:`n`n`3`bINSTRUCTIONS`b`n1) Insert coins into slots`n2) Turn Handle`n3) BRAAAAAINS`n`n`bRULES`b`nWhen the handle is turned, a brain symbol will appear.  If your coin was in the slot corresponding to where the brain appears, the machine will pay five coins back.  You may bet on as many slots as you like.  In each round of play, multiple brains can appear, and multiple prizes can be paid.`0`n`nYou take this to mean that if you bet on all six slots, and all six slots contain brains, you'll win 30 coins back.  Which, given that each token is worth 10 Req, translates to 300 Requisition tokens.  Nice.`n`n");
            addnav("Forget it");
            addnav("Turn away", "runmodule.php?module=pub_newpittsburgh&op=continue");
            $brains = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0);
            $bets = array();
            findthebrain_showboard($brains, $bets);
            break;
        case "play":
            //get bets
            $bets = array();
            $post = httpallpost();
            foreach ($post as $beton) {
                $bets[$beton] = true;
            }
            $brains = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0);
            $amountbet = count($bets) * 10;
            //check the player made a bet
            if (!$amountbet) {
                output("You didn't bet anything!`n`n");
                findthebrain_showboard($brains, $bets);
                addnav("That's enough");
                addnav("Turn away", "runmodule.php?module=pub_newpittsburgh&op=continue");
                break;
            }
            increment_module_setting("played", $amountbet);
            //check the player has enough money to cover the bet
            if ($session['user']['gold'] >= $amountbet) {
                //play the game!
                if ($amountbet == 10) {
                    $cointxt = "token";
                    $slottxt = "slot";
                } else {
                    $cointxt = "tokens";
                    $slottxt = "slots";
                }
                output("You insert your %s into the relevant %s and turn the handle.  There's a series of satisfying clanking and ratcheting sounds, and then a metal plate appears in a window, painted to look like a brain.`n`n", $cointxt, $slottxt);
                $session['user']['gold'] -= $amountbet;
                $choose = 1;
                $bonuschance = e_rand(0, 100);
                while ($bonuschance > 82) {
                    $choose += 1;
                    $bonuschance = e_rand(0, 100);
                }
                for ($i = 0; $i < $choose; $i++) {
                    $chosen = e_rand(1, 6);
                    if (!$brains[$chosen] && $i > 0) {
                        output("There's a quiet sound of a spring straining against pressure, and then another brain shoots into place with a `ikerchunk.`i`n`n");
                    }
                    $brains[$chosen] = 1;
                }
                foreach ($bets as $key => $value) {
                    if ($brains[$key]) {
                        $wonreq += 50;
                    }
                }
                if ($wonreq) {
                    output("A bell rings, and tokens clatter into the payout slot.  You won %s Requisition!`n`n", $wonreq);
                    $session['user']['gold'] += $wonreq;
                    increment_module_setting("won", $wonreq, "findthebrain");
                } else {
                    output("You didn't win anything this time...`n`n");
                }
            } else {
                output("You don't have enough money to cover that bet!`n`n");
            }
            findthebrain_showboard($brains, $bets);
            addnav("That's enough");
            addnav("Turn away", "runmodule.php?module=pub_newpittsburgh&op=continue");
            break;
    }
    page_footer();
}
function titans_kill_titan($titan)
{
    global $session;
    //debug("Killing Titan!");
    //debug($titan);
    if (!$titan['battlelog']['killed']) {
        //debug("Titan is not dead, let's fix that!");
        $titan['battlelog']['killingblow_name'] = $session['user']['name'];
        $titan['battlelog']['killingblow_acctid'] = $session['user']['acctid'];
        $titan['battlelog']['killed'] = 1;
        $now = time();
        $titan['battlelog']['timeofdeath'] = $now;
        //determine lifetime, update averages, alter maximum Titan hitpoints if necessary
        $lifetime = $now - $titan['battlelog']['timeofbirth'];
        $desiredlifetime = get_module_setting("desiredlifetime", "titans");
        $curhp = get_module_setting("titanhp", "titans");
        $curspawnchance = get_module_setting("spawnchance", "titans");
        $curtotaltitans = get_module_setting("totaltitans", "titans");
        $curtotaltime = get_module_setting("totallifetime", "titans");
        $newtotaltitans = $curtotaltitans + 1;
        $newtotaltime = $curtotaltime + $lifetime;
        $avglifetime = $newtotaltime / $newtotaltitans;
        //allow a large deviation in the current data before immediately changing
        if ($lifetime < $desiredlifetime * 0.5) {
            $newhp = $curhp * 1.05;
        } else {
            if ($lifetime > $desiredlifetime * 2) {
                $newhp = $curhp * 0.95;
            } else {
                $newhp = $curhp;
            }
        }
        //allow a small deviation in the historical data before changing
        if ($lifetime < $desiredlifetime * 0.95) {
            $newhp = round(ceil($curhp * 1.05), -2);
            increment_module_setting("spawnchance", 1, "titans");
        } else {
            if ($lifetime > $desiredlifetime * 1.05) {
                $newhp = round(floor($curhp * 0.95), -2);
                if ($curspawnchance > 1) {
                    increment_module_setting("spawnchance", -1, "titans");
                }
            }
        }
        if ($newhp > 1000000) {
            set_module_setting("titanhp", $newhp, "titans");
        }
        set_module_setting("totaltitans", $newtotaltitans, "titans");
        set_module_setting("totallifetime", $newtotaltime, "titans");
        titans_award_req($titan);
        titans_set_titan($titan);
    }
    output("`0The Titan falls to the earth with a mighty crash, and lies still.  All combatants are immediately issued a Requisition reward to their bank accounts.  Offshore, `4The Watcher`0 smiles.`n`n");
    addnav("Crisis averted!");
    addnav("Back to the Map", "runmodule.php?module=worldmapen&op=continue");
    return $titan;
}
function clatter_run()
{
    global $session;
    if (httpget('op') == "virgin") {
        page_header("What a curious-looking device.");
        $bk = getsetting('barkeep', '`tCedrik');
        rawoutput("<img src=\"images/clatter/clatterboard.jpg\" align=right>");
        set_module_pref("virgin", 0);
        output("You head over to the bar and ask %s what the deal is with that weird-looking box thingy on the wall.`n`n%s grins.  \"`%You like it, then?  Built it meself.  It's all relays, no IC's at all.  Runs off an old car battery.`0\"`n`n\"`#It's very nice, yes,`0\" you say carefully, \"`#but what `iis`i it, %s?`0\"`n`n%s beams proudly.  \"`%I just thought of a name fer it this mornin' - I'm gonna call it \"Clatter!\"  You put a coin in the top, see, and it goes down that nailboard.  If it comes out the very middle on the last row of nails, you get to keep it!`0\"`n`nYou frown.  \"`#I'm not sure I like those odds, %s.`0\"`n`n\"`%Ah, there's the clever bit.  Y'see those circles dotted around the nailboard?  If yer coin goes over one o' them on the way down, an electromagnetic slide fires some more coins out at the top.  It's all about chain reactions, y'see.`0\"`n`nYou stroke your chin thoughtfully.  \"`#What sort of coins does it take?`0\"`n`n\"`%It only takes these tokens here, behind the bar.  You can buy 'em from me for 20 Req each, one at a time.`0\"`n`n\"`#Wait, `ione at a time?`i  Doesn't that mean you have to hang around the machine for ages whenever someone plays it?  Who minds the bar?`0\"`n`n%s shrugs.  \"`%Corporal Punishment talked me into doin' it that way.  He kept on at me about savin' clicks and keepin' things simple for the player.  I didn't understand a bloody word of it, but y'know, he's persuasive.  Manages to talk folks out of walking around with their fists strapped together behind their backs, y'know, stuff like that.`0\" %s stares off into the middle distance for a moment. \"`%Not sure where that weird little habit started.  Seems all the cool kids were doin' it at one point.  But yeah, I sell the tokens to ya one at a time.`0\"  You raise a finger and open your mouth, and %s cuts you off.  \"`%`iTrust me,`i it's just `ieasier`i this way.  Anyway, the coins go in the top, an' then if they go over a target, it'll light up.  Next time a coin goes over that target, it'll fire out some more coins an' maybe light up another target.  So d'you fancy a go, or what?`0\"`n`n", $bk, $bk, $bk, $bk, $bk, $bk, $bk, $bk);
    } else {
        page_header("Clatter");
    }
    if (httpget('op') == "start") {
        output("The Clatter machine lurks in the corner, tempting you with promises of easy wealth.");
    }
    $woncoins = 0;
    if (httpget('op') == "play") {
        $session['user']['gold'] -= 20;
        $lit = unserialize(get_module_pref("lit"));
        if (!isset($lit[1])) {
            $lit = array();
            $lit[1] = 0;
            $lit[2] = 0;
            $lit[3] = 0;
            $lit[4] = 0;
            $lit[5] = 0;
            $lit[6] = 0;
            $lit[7] = 0;
        }
        $coinsinplay = 1;
        $totalcoinsplayed = 0;
        output("You plonk down twenty Requisition tokens onto the bar, and blink.  A single Clatter token sits in a beery puddle.  You pick it up and put it into the slot on the top of the machine.`n`n");
        increment_module_setting("played");
        while ($coinsinplay > 0) {
            $msg = "";
            $coinsinplay--;
            $totalcoinsplayed++;
            $start = mt_rand(0, 1);
            if ($start) {
                $coinposition = 6;
            } else {
                $coinposition = 8;
            }
            // output("Dropping coin %s`n",$totalcoinsplayed);
            rawoutput("<table width=100% cellpadding=0 cellspacing=2><tr><td>");
            if ($totalcoinsplayed == 1) {
                $msg .= "Your beer-soaked coin clatters down the nailboard, ";
            } else {
                $msg .= "An electromagnetic slide fires with a satisfying KER-CHUNK, and a new coin appears at the top of the nailboard.  It descends upon its merry way, ";
            }
            $bonus = 0;
            for ($i = 1; $i <= 7; $i++) {
                if (mt_rand(0, 1)) {
                    $coinposition++;
                } else {
                    $coinposition--;
                }
                //bounce coins off edges
                if ($coinposition > 13) {
                    $coinposition = 12;
                }
                if ($coinposition < 1) {
                    $coinposition = 2;
                }
                //award bonuses
                if ($i == 3 && ($coinposition == 3 || $coinposition == 11)) {
                    $bonus = 1;
                    $msg .= "passing through the first target and closing the switch.  ";
                    if ($lit[3]) {
                        $msg .= "A relay clicks open and turns off the lamp, while incrementing a counter.  `n";
                        $coinsinplay += 1;
                        if (!$lit[7]) {
                            $msg .= "The lamp behind the centre target turns on.`n";
                        }
                        $lit[7] = 1;
                        $lit[3] = 0;
                    } else {
                        $msg .= "A relay clicks closed and the lamps behind the top set of targets switch on.  The next time a coin goes across either of these targets, a bonus coin will be awarded.`n";
                        $lit[3] = 1;
                    }
                } else {
                    if ($i == 5 && $coinposition == 7) {
                        $bonus = 1;
                        $msg .= "passing through the centre target and closing the switch.  ";
                        if ($lit[5]) {
                            $msg .= "A relay clicks open and turns off the lamp, and three clicks from deep inside the machine suggests a counter is incrementing.`n";
                            $coinsinplay += 3;
                            if (!$lit[7]) {
                                $msg .= "The lamps behind the lower targets turn on.`n";
                            }
                            $lit[5] = 0;
                            $lit[7] = 1;
                        } else {
                            $msg .= "A relay clicks closed and the lamp behind the center target turns on.  The next time a coin goes across this target, three bonus coins will be awarded.`n";
                            $lit[5] = 1;
                        }
                    } else {
                        if ($i == 7 && ($coinposition == 1 || $coinposition == 13)) {
                            if (!$bonus) {
                                $msg .= "completely missing the one-bonus and three-bonus targets and falling into one of the side channels.  ";
                            } else {
                                $msg .= "As a further awesomeness, the coin then drops down one of the side channels.  ";
                            }
                            $bonus = 1;
                            if ($lit[7]) {
                                $msg .= "A relay clicks open and turns off the lamp, and two clicks from deep inside the machine suggests a counter is incrementing.`n";
                                $coinsinplay += 2;
                                if (!$lit[5]) {
                                    $msg .= "The lamp behind the center target turns on.`n";
                                }
                                $lit[7] = 0;
                                $lit[5] = 1;
                            } else {
                                $msg .= "A relay clicks closed and the lamps behind the bottom set of targets switch on.  The next time a coin goes across either of these targets, two bonus coins will be awarded.`n";
                                $lit[7] = 1;
                            }
                        }
                    }
                }
                //output image
                rawoutput("<img src=\"images/clatter/" . $i . "-" . $coinposition . "-" . $lit[$i] . ".jpg\"><br />");
            }
            // end individual coin drop
            if ($coinposition == 7 && $bonus) {
                $msg .= "`nThe coin clatters into the centre channel, and falls into the payout chute.  Immediately a hairy hand from behind the bar grabs it and thrusts twenty Requisition tokens towards you.`n`n";
                $woncoins++;
                increment_module_setting("won");
            } else {
                if ($coinposition == 7) {
                    $msg .= "missing every single target before being returned to you via the Payout chute at the bottom of the machine.  Immediately a hairy hand from behind the bar grabs it and thrusts twenty Requisition tokens towards you.`n`n";
                    $woncoins++;
                    increment_module_setting("won");
                } else {
                    if (!$bonus) {
                        $msg .= "completely failing to do any good whatsoever and simply disappearing into the depths of the machine.  Bah.`n`n";
                    } else {
                        $msg .= "The coin falls into the depths of the machine.`n`n";
                    }
                }
            }
            rawoutput("</td><td>");
            output("%s`n`n", $msg);
            rawoutput("</td></tr></table>");
        }
        // end page load
        set_module_pref("lit", serialize($lit));
        $winnings = $woncoins * 20;
        $session['user']['gold'] += $winnings;
        if ($winnings) {
            output("`nYou have won a total of %s Requisition tokens this time, minus your 20 Requisition stake.", $winnings);
            if ($winnings == 20) {
                output("  In other words, you broke even.  Huzzah!");
            }
        } else {
            output("`nYou didn't win anything this time.");
        }
    }
    addnav("Clatter");
    if ($session['user']['gold'] >= 20) {
        addnav("Play Clatter", "runmodule.php?module=clatter&op=play");
        //addnav("Play Flash version","runmodule.php?module=clatterflash&op=play");
    } else {
        addnav("You can't afford to gamble right now.", "");
    }
    addnav("Walk Away", "inn.php");
    page_footer();
}
function commentaryicons_customrace_run()
{
    require_once "lib/sanitize.php";
    require_once "lib/names.php";
    global $session;
    $op = httpget("op");
    page_header("Custom Races");
    $costfirst = get_module_setting("initialpoints");
    $costsub = get_module_setting("extrapoints");
    $costperm = get_module_setting("permanent");
    $hasperm = get_module_pref("permanent");
    $playerpoints = $session['user']['donation'] - $session['user']['donationspent'];
    switch ($op) {
        case "change":
            output("Want to change your Custom Race?  No problem.  Enter your desired race in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom race naming and return to default, game-supplied race names)`n`n");
            rawoutput("<form action='runmodule.php?module=commentaryicons_customrace&op=confirm&sub=change' method='POST'>");
            $race = get_module_pref("customrace");
            rawoutput("<input id='input' name='newrace' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=commentaryicons_customrace&op=confirm&sub=change");
            break;
        case "firstchange":
            output("Changing your Custom Race will affect how other players see you.  In commentary areas, your race will show up as whatever you select here (the icon will be a little silver question mark, with the name of your race embedded in hover text like the other Race icons).  In the game mechanics, your race will be unchanged.  Think of it like a costume; you'll still be a %s inside, but your friends will think of you as whatever you enter in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom race naming and return to default, game-supplied race names)`n`n", $session['user']['race']);
            rawoutput("<form action='runmodule.php?module=commentaryicons_customrace&op=confirm&sub=firstchange' method='POST'>");
            $race = get_module_pref("customrace");
            rawoutput("<input id='input' name='newrace' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=commentaryicons_customrace&op=confirm&sub=firstchange");
            break;
        case "permanent":
            output("Buying permanent free changes means you'll pay %s points now, and then you can change your custom race as often as you like without paying again.`n`n", $costperm);
            addnav("Unlimited Custom Race changes");
            if ($playerpoints >= $costperm) {
                addnav(array("Buy permanent access (%s Points)", $costperm), "runmodule.php?module=commentaryicons_customrace&op=set&type=perm");
            } else {
                addnav(array("Sorry, but you need %s more points to do that.", $costperm - $playerpoints), "");
            }
            addnav("Cancel", "lodge.php");
            break;
        case "confirm":
            $newrace = httppost("newrace");
            $sub = httpget("sub");
            $newrace = str_replace("`", "", $newrace);
            $newrace = comment_sanitize($newrace);
            $newrace = substr($newrace, 0, 25);
            output("Your new custom race is:`n%s`nWould you like to set your new Race now?", $newrace);
            addnav("Confirm");
            switch ($sub) {
                case "change":
                    if ($hasperm) {
                        addnav("Set Custom Race (free)", "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    } else {
                        addnav(array("Set Custom Race (%s Points)", $costsub), "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    }
                    break;
                case "firstchange":
                    if ($hasperm) {
                        addnav("Set Custom Race (free)", "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    } else {
                        addnav(array("Set Custom Race (%s Points)", $costfirst), "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=firstchange");
                    }
                    break;
            }
            break;
        case "set":
            $newrace = rawurldecode(httpget("newrace"));
            switch (httpget("type")) {
                case "change":
                    output("Your custom race has been set to %s!`n`n", $newrace);
                    set_module_pref("customrace", $newrace);
                    increment_module_pref("numchanges");
                    if (!get_module_pref("permanent")) {
                        $session['user']['donationspent'] += $costsub;
                        increment_module_setting("totalpoints", $costsub);
                    }
                    break;
                case "firstchange":
                    output("Your custom race has been set to %s!`n`n", $newrace);
                    set_module_pref("customrace", $newrace);
                    increment_module_pref("numchanges");
                    if (!get_module_pref("permanent")) {
                        $session['user']['donationspent'] += $costfirst;
                        increment_module_setting("totalpoints", $costfirst);
                    }
                    break;
                case "perm":
                    output("You've got permanent free custom race changes!  Woo!`n`n");
                    set_module_pref("permanent", 1);
                    $session['user']['donationspent'] += $costperm;
                    break;
            }
            break;
    }
    addnav("Return");
    addnav("L?Return to the Lodge", "lodge.php");
    page_footer();
}
function timeandweather_update()
{
    $now = time();
    $last = get_module_setting("lastupdate", "timeandweather");
    $change = get_module_setting("changeevery", "timeandweather");
    $changeat = $last + $change;
    //debug($changeat);
    if ($now > $changeat) {
        set_module_setting("lastupdate", $now, "timeandweather");
        //time to change the weather
        $old = get_module_setting("currentweather", "timeandweather");
        set_module_setting("lastweather", $old, "timeandweather");
        $new = e_rand(-2, 2);
        increment_module_setting("currentweather", $new, "timeandweather");
        if (get_module_setting("currentweather", "timeandweather") > 7) {
            set_module_setting("currentweather", 7, "timeandweather");
        } else {
            if (get_module_setting("currentweather", "timeandweather") < 1) {
                set_module_setting("currentweather", 1, "timeandweather");
            }
        }
    }
}
function doubleorquits_run()
{
    global $session;
    page_header("Twice as much or git tae f**k");
    $op = httpget("op");
    $sub = httpget("sub");
    switch ($op) {
        case "start":
            output("You wander over to a wall-mounted wooden box, covered in carved graffiti.  The window in the front is so grimy you can barely see in, and some wag has daubed in the dust a misspelled plea for somebody to give it a quick wipe.  Fat chance.`n`nChlamydia sees you examining the machine.  She scuttles across the bar towards you.  \"`2It's one o' them double or quits games, but we've called it 'Twice as much or git tae f**k,' luv.  Ye put yer money in the slot an' turn the 'andle, an' 'alf the time it gives yer twice as much back.  It's dead easy, petal, you've jus' gotta know when te stop.`0\"  She gestures over her shoulder.  \"`2It'd do nowt but pay out all me profits, 'cept these silly buggers 'ere never know when tae say enough's enough.  Twenny Req a go, darlin'.`0\"`n`nSo it's a very basic double-or-nothing type game.  Well, it'd `ihave`i to be simple, otherise your average Midget wouldn't be able to play it.`n`n");
            if ($session['user']['race'] != "Midget") {
                output("You kneel down in front of the machine - it's mounted at bellybutton height - and contemplate whether to play or not.`n`n");
            } else {
                output("You know for damned certain that you're smarter than the average Midget.  You stare up at the machine, wondering which way to turn the handle.`n`n");
            }
            rawoutput("<img src='images/doubleorquits/doubleorquits_lose.jpg'><br />");
            if ($session['user']['gold'] >= 20) {
                addnav("Play");
                addnav("Play (20 Req)", "runmodule.php?module=doubleorquits&op=play");
            } else {
                addnav("Play");
                addnav("Ah, but you do not have twenty Requisition tokens, do you?", "");
            }
            addnav("Forget it");
            addnav("Turn away", "runmodule.php?module=pub_squathole&op=continue");
            break;
        case "play":
            $session['user']['gold'] -= 20;
            increment_module_setting("played", 20);
            if (e_rand(0, 100) > 50) {
                rawoutput("<img src='images/doubleorquits/doubleorquits_40.jpg'><br /><br />");
                output("`bYou won!`b  The machine offers you 40 Req, or a chance to gamble it for a chance to get 80 Req.`n`n");
                addnav("Buttons");
                addnav("Gamble", "runmodule.php?module=doubleorquits&op=gamble&prize=80");
                addnav("Accept", "runmodule.php?module=doubleorquits&op=accept&prize=40");
            } else {
                rawoutput("<img src='images/doubleorquits/doubleorquits_lose.jpg'><br /><br />");
                output("`bYou lost!`b`n`n");
                if ($session['user']['gold'] >= 20) {
                    addnav("Play");
                    addnav("Play (20 Req)", "runmodule.php?module=doubleorquits&op=play");
                }
                addnav("That's enough");
                addnav("Turn away", "runmodule.php?module=pub_squathole&op=continue");
            }
            break;
        case "gamble":
            $prize = httpget('prize');
            if (e_rand(0, 1)) {
                $newprize = $prize * 2;
                rawoutput("<img src='images/doubleorquits/doubleorquits_" . $prize . ".jpg'><br /><br />");
                output("`bYou won!`b  The machine offers you %s Req, or a chance to gamble it for a chance to get %s Req.`n`n", $prize, $newprize);
                addnav("Buttons");
                addnav("Gamble", "runmodule.php?module=doubleorquits&op=gamble&prize={$newprize}");
                addnav("Accept", "runmodule.php?module=doubleorquits&op=accept&prize={$prize}");
            } else {
                rawoutput("<img src='images/doubleorquits/doubleorquits_lose.jpg'><br /><br />");
                output("You lost the gamble.  Shoulda taken what it offered.`n`n");
                if ($session['user']['gold'] >= 20) {
                    addnav("Play");
                    addnav("Play (20 Req)", "runmodule.php?module=doubleorquits&op=play");
                }
                addnav("That's enough");
                addnav("Turn away", "runmodule.php?module=pub_squathole&op=continue");
            }
            break;
        case "accept":
            $prize = httpget('prize');
            increment_module_setting("won", $prize);
            $session['user']['gold'] += $prize;
            output("You turn the 'accept' handle, and %s Requisition tokens are vomited out of the machine.  The payout hopper being stuffed full of cigarette ends and random detritus, the tokens clatter noisly on the floor.`n`n", $prize);
            if ($session['user']['gold'] >= 20) {
                addnav("Play again");
                addnav("Play (20 Req)", "runmodule.php?module=doubleorquits&op=play");
            }
            addnav("That's enough");
            addnav("Turn away", "runmodule.php?module=pub_squathole&op=continue");
            break;
    }
    debug(get_module_setting("played"));
    debug(get_module_setting("won"));
    page_footer();
}
function mouseracing_run()
{
    global $session;
    page_header("Mouse Racing");
    $jackpot = get_module_setting("jackpot");
    $op = httpget("op");
    switch ($op) {
        case "start":
            output("You wander over to a wall-mounted, glass-fronted wooden box.  Five brightly-coloured metal mouse shapes sit behind the glass, and five coin slots are mounted invitingly to their left.  Each mouse sits across a long, thin channel that runs across the board towards a chequered line.  Beneath each of these channels is another one, angled slightly upwards.  On each mouse is a number that represents how many times your stake each mouse will pay if you win.`n`nA set of numeric reels at the bottom of the machine shows the current payoff for the purple mouse - a handsome `5%s`0 Requisition tokens.`n`nMiu-Miu sees you eyeballing the machine.  \"`2It's ten Req a token, love.  They're right here, behind the bar.`0\"`n`nWill you play?  And if so, how many tokens?  You can bet on any mouse or combination or mice, and each mouse that you bet on will need its own 10-Req token.  Check the boxes and Bet!`n`n", number_format($jackpot));
            addnav("Forget it");
            addnav("Turn away", "runmodule.php?module=pub_kittania&op=continue");
            $mice = array(1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1);
            $bets = array();
            mouseracing_showboard($mice, $bets, $jackpot);
            break;
        case "play":
            $jackpot = httpget("jackpot");
            //get bets
            $bets = array();
            $post = httpallpost();
            foreach ($post as $beton) {
                $bets[$beton] = true;
            }
            $finish = 30;
            $mice = array(1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1);
            $winnings = array(1 => 20, 2 => 40, 3 => 60, 4 => 80, 5 => $jackpot);
            $slidevals = array(1 => 42, 2 => 34, 3 => 30, 4 => 28, 5 => 20);
            $amountbet = count($bets) * 10;
            //check the player made a bet
            if (!$amountbet) {
                output("You didn't bet anything!`n`n");
                mouseracing_showboard($mice, $bets, $jackpot);
                addnav("That's enough");
                addnav("Turn away", "runmodule.php?module=pub_kittania&op=continue");
                break;
            }
            increment_module_setting("played", $amountbet);
            //check the player has enough money to cover the bet
            if ($session['user']['gold'] >= $amountbet) {
                //play the game!
                if ($amountbet == 10) {
                    $cointxt = "token";
                    $slottxt = "slot";
                } else {
                    $cointxt = "tokens";
                    $slottxt = "slots";
                }
                output("You insert your %s into the relevant %s and press the \"Start\" button.  A low hum can be heard, which builds up to a high-pitched whine.  A long arm swipes across the board from right to left, pushing the mice back to their starting positions, before retracting back into its slot on the right-hand side.`n`nYou hear what sounds like a clutch mechanism engaging, and the whine dips in pitch a little, and then there's a ferocious clatter as five little steel ball bearings are violently propelled against plates behind the mice, one ball for each mouse.  After bouncing off the plates, the balls roll back down towards the flywheels that flicked them.  Depending on the position of the flywheel notches in the split-second in which the ball makes contact, the ball sometimes fires out so fast you can't see it move; other times it barely make it to the mouse.`n`nThe mouse at the top seems to be held in place with a little less tension, and the ones below look like they're held increasingly tightly.  The red mouse jerks along the track a few centimeters every time its ball makes contact, while the purple mouse barely seems to notice the impacts.`n`nYou watch the mice scuttle jerkily along the track as the machine clatters away.  It makes a hell of a racket, just like a good arcade machine should.`n`n", $cointxt, $slottxt);
                $session['user']['gold'] -= $amountbet;
                $running = true;
                $wonreq = 0;
                $jackpot += 5;
                while ($running) {
                    $mouse = e_rand(1, 5);
                    $slidenom = $slidevals[$mouse] * 10;
                    $slide = e_rand($slidenom / 2, $slidenom * 2);
                    $slide = $slide / 100;
                    $mice[$mouse] += $slide;
                    if ($mice[$mouse] >= 5 && !$seen5) {
                        $seen5 = true;
                        mouseracing_showboard($mice);
                    }
                    if ($mice[$mouse] >= 10 && !$seen10) {
                        $seen10 = true;
                        mouseracing_showboard($mice);
                    }
                    if ($mice[$mouse] >= 15 && !$seen15) {
                        $seen15 = true;
                        mouseracing_showboard($mice);
                    }
                    if ($mice[$mouse] >= 20 && !$seen20) {
                        $seen20 = true;
                        mouseracing_showboard($mice);
                    }
                    if ($mice[$mouse] >= 25 && !$seen25 && $mice[$mouse] < 30) {
                        $seen25 = true;
                        mouseracing_showboard($mice);
                    }
                    if ($mice[$mouse] >= $finish) {
                        $running = false;
                        if (array_key_exists($mouse, $bets)) {
                            $wonreq += $winnings[$mouse];
                            if ($mouse == 5) {
                                set_module_setting("jackpot", 200, "mouseracing");
                                $jackpot = 200;
                            }
                        }
                        mouseracing_showboard($mice, $bets, $jackpot);
                    }
                }
                if ($wonreq) {
                    output("A bell rings, and tokens clatter into the payout slot.  You won %s Requisition!`n`n", $wonreq);
                    $session['user']['gold'] += $wonreq;
                    increment_module_setting("won", $wonreq, "mouseracing");
                } else {
                    output("You didn't win anything this time...`n`n");
                }
                increment_module_setting("jackpot", 5, "mouseracing");
            } else {
                output("You don't have enough money to cover that bet!`n`n");
                mouseracing_showboard($mice, $bets, $jackpot);
            }
            addnav("That's enough");
            addnav("Turn away", "runmodule.php?module=pub_kittania&op=continue");
            break;
    }
    page_footer();
}
function timeandweather_update()
{
    $now = time();
    $last = get_module_setting("lastupdate", "timeandweather");
    $change = get_module_setting("changeevery", "timeandweather");
    $changeat = $last + $change;
    //debug($changeat);
    $changein = $changeat - $now;
    //debug($changein);
    //$changeat = 0;
    if ($now > $changeat) {
        set_module_setting("lastupdate", $now, "timeandweather");
        //time to change the weather
        $old = get_module_setting("currentweather", "timeandweather");
        set_module_setting("lastweather", $old, "timeandweather");
        if ($old == 1) {
            $new = e_rand(0, 2);
        } else {
            if ($old == 2) {
                $new = e_rand(-1, 2);
            } else {
                if ($old == 6) {
                    $new = e_rand(-2, 1);
                } else {
                    if ($old == 7) {
                        $new = e_rand(-2, 0);
                    } else {
                        //trend towards the sun
                        //$new = e_rand(-2,2);
                        $new = e_rand(-2, 1);
                    }
                }
            }
        }
        increment_module_setting("currentweather", $new, "timeandweather");
        if (get_module_setting("currentweather", "timeandweather") > 7) {
            set_module_setting("currentweather", 7, "timeandweather");
        } else {
            if (get_module_setting("currentweather", "timeandweather") < 1) {
                set_module_setting("currentweather", 1, "timeandweather");
            }
        }
    }
}