function improbablehousing_show_build_jobs($house)
{
    //run through the build jobs and show percentage to completion, along with navs to use the relevant item and its associated Stamina cost.
    //For easyness, don't allow the player to build if they're in Amber stamina
    $jobs = $house['data']['buildjobs'];
    require_once "modules/staminasystem/lib/lib.php";
    $storestock = $house['data']['store'];
    $displayjobs = array();
    if (count($jobs)) {
        foreach ($jobs as $key => $vals) {
            if (!isset($displayjobs[$vals['name']])) {
                addnav(array("%s", $vals['name']));
                foreach ($vals['jobs'] as $skey => $svals) {
                    $cando = 1;
                    $displayjobs[$vals['name']][$svals['name']]['req'] = $svals['req'];
                    $displayjobs[$vals['name']][$svals['name']]['done'] = $svals['done'];
                    //check completion
                    if ($svals['completed']) {
                        $cando = 0;
                    }
                    //Check Stamina
                    if (get_stamina() < 100) {
                        $cando = 0;
                        $nostam = 1;
                        $displayjobs[$vals['name']][$svals['name']]['nostamina'] = true;
                    }
                    $store = array();
                    $player = array();
                    foreach ($svals['iitems'] as $ikey => $iitem) {
                        $store[$ikey] = $house['data']['store'][$ikey];
                        if (has_item($ikey)) {
                            $player[$ikey] = 1;
                        }
                    }
                    //check that each item required is present in either the store or the player's inventory... this could be neater...
                    $svals['useplayer'] = true;
                    foreach ($svals['iitems'] as $ikey => $iitem) {
                        if (!$store[$ikey] && !$player[$ikey]) {
                            $cando = 0;
                            $displayjobs[$vals['name']][$svals['name']]['noitem'] = true;
                        }
                        if ($store[$ikey] > 0) {
                            $svals['usestore'] = true;
                        }
                        if (!$player[$ikey]) {
                            $svals['useplayer'] = false;
                        }
                    }
                    // debug($store);
                    // debug($player);
                    if ($cando) {
                        $scost = 0;
                        foreach ($svals['actions'] as $akey => $action) {
                            $scost += stamina_getdisplaycost($akey);
                        }
                        if ($svals['useplayer']) {
                            addnav(array("%s (`Q%s%%`0)", $svals['name'], $scost), "runmodule.php?module=improbablehousing&op=build&hid=" . $house['id'] . "&job=" . $key . "&subjob=" . $skey);
                        }
                        if ($svals['usestore']) {
                            addnav(array("%s (using store) (`Q%s%%`0)", $svals['name'], $scost), "runmodule.php?module=improbablehousing&op=build&hid=" . $house['id'] . "&job=" . $key . "&subjob=" . $skey . "&store=true");
                        }
                    }
                }
            }
        }
    }
    if (count($displayjobs)) {
        output("`b`0Current Construction Jobs`b`n");
        foreach ($displayjobs as $job => $sub) {
            output_notl("`0->%s`n", $job);
            foreach ($sub as $sjob => $vals) {
                $jobout = "<table><tr><td>";
                require_once "lib/bars.php";
                $bar = fadebar($vals['done'], $vals['req']);
                if ($vals['completed']) {
                    $jobout .= "-->" . $sjob . " </td><td>" . $bar . "</td> ";
                } else {
                    $jobout .= "-->" . $sjob . " </td><td>" . $bar . "</td><td> " . $vals['done'] . "/" . $vals['req'] . " ";
                    if ($vals['nostamina']) {
                        $jobout .= "(you don't have enough Stamina to do this job) ";
                    }
                    if ($vals['noitem']) {
                        $jobout .= "(you don't have all the items you need to do this job) ";
                    }
                }
                $jobout .= "</td></tr></table>";
                rawoutput($jobout);
            }
            output_notl("`n");
        }
        output_notl("`n");
    }
    if ($nostam) {
        output("You have the brains to know that doing construction work when you're anything but wide awake is an idea so bad you're not even willing to entertain it.`n`n");
    }
}
/**
 * Returns the current character stats or (if the character isn't logged in) the currently online players
 * Hooks provided:
 *		charstats
 *
 * @return array The current stats for this character or the list of online players
 */
function charstats()
{
    global $session, $playermount, $companions;
    wipe_charstats();
    $u =& $session['user'];
    if ($session['loggedin']) {
        $u['hitpoints'] = round($u['hitpoints'], 0);
        $u['experience'] = round($u['experience'], 0);
        $u['maxhitpoints'] = round($u['maxhitpoints'], 0);
        // $spirits=array(-6=>"Resurrected",-2=>"Very Low",-1=>"Low","0"=>"Normal",1=>"High",2=>"Very High");
        // if ($u['alive']){ }else{ $spirits[(int)$u['spirits']] = "DEAD"; }
        //calculate_buff_fields();
        reset($session['bufflist']);
        $atk = $u['attack'];
        $def = $u['defense'];
        $buffcount = 0;
        $buffs = "";
        while (list($key, $val) = each($session['bufflist'])) {
            if (isset($val['suspended']) && $val['suspended']) {
                continue;
            }
            if (isset($val['atkmod'])) {
                $atk *= $val['atkmod'];
            }
            if (isset($val['defmod'])) {
                $def *= $val['defmod'];
            }
            // Short circuit if the name is blank
            if ($val['name'] > "" || $session['user']['superuser'] & SU_DEBUG_OUTPUT) {
                tlschema($val['schema']);
                if ($val['name'] == "") {
                    $val['name'] = "DEBUG: {$key}";
                }
                if (is_array($val['name'])) {
                    $val['name'][0] = str_replace("`%", "`%%", $val['name'][0]);
                    $val['name'] = call_user_func_array("sprintf_translate", $val['name']);
                } else {
                    //in case it's a string
                    $val['name'] = translate_inline($val['name']);
                }
                if ($val['rounds'] >= 0) {
                    // We're about to sprintf, so, let's makes sure that
                    // `% is handled.
                    //$n = translate_inline(str_replace("`%","`%%",$val['name']));
                    $b = translate_inline("`#%s `7(%s rounds left)`n", "buffs");
                    $b = sprintf($b, $val['name'], $val['rounds']);
                    $buffs .= appoencode($b, true);
                } else {
                    $buffs .= appoencode("`#{$val['name']}`n", true);
                }
                tlschema();
                $buffcount++;
            }
        }
        if ($buffcount == 0) {
            $buffs .= appoencode(translate_inline("`^None`0"), true);
        }
        $atk = round($atk, 2);
        $def = round($def, 2);
        if ($atk < $u['attack']) {
            $atk = round($u['attack'], 1) . "`\$" . round($atk - $u['attack'], 1);
        } else {
            if ($atk > $u['attack']) {
                $atk = round($u['attack'], 1) . "`@+" . round($atk - $u['attack'], 1);
            } else {
                // They are equal, display in the 1 signifigant digit format.
                $atk = round($atk, 1);
            }
        }
        if ($def < $u['defense']) {
            $def = round($u['defense'], 1) . "`\$" . round($def - $u['defense'], 1);
        } else {
            if ($def > $u['defense']) {
                $def = round($u['defense'], 1) . "`@+" . round($def - $u['defense'], 1);
            } else {
                // They are equal, display in the 1 signifigant digit format.
                $def = round($def, 1);
            }
        }
        addcharstat("Vital Info");
        //health bar
        if ($u['alive']) {
            $cur = $u['hitpoints'];
            $realmax = $u['maxhitpoints'];
            $cur_adjustment = check_temp_stat("hitpoints", 1);
            $max_adjustment = check_temp_stat("maxhitpoints", 1);
        } else {
            $cur = $u['soulpoints'];
            $realmax = $u['level'] * 5 + 50;
            $cur_adjustment = check_temp_stat("soulpoints", 1);
            $max_adjustment = "";
        }
        if ($pct > 60) {
            $ccode = "`@";
        } elseif ($pct > 25) {
            $ccode = "`^";
        } else {
            $ccode = "`\$";
        }
        $hicode = "`&";
        if (!$u['alive']) {
            $ccode = "`7";
        }
        require_once "lib/bars.php";
        $hpbar = fadebar($cur, $realmax);
        $stat = "{$ccode} {$cur} {$cur_adjustment} `0/ {$realmax} {$max_adjustment}<br />" . $hpbar;
        if ($u['alive']) {
            addcharstat("Hitpoints", $stat);
            addcharstat("Attack", $atk . check_temp_stat("attack", 1));
            addcharstat("Defence", $def . check_temp_stat("defense", 1));
        } else {
            addcharstat("Adrenaline", $stat);
            addcharstat("Attack", 10 + round(($u['level'] - 1) * 1.5));
            addcharstat("Defence", 10 + round(($u['level'] - 1) * 1.5));
        }
        // addcharstat("Turns", $u['turns'].check_temp_stat("turns",1));
        // addcharstat("Attack", $atk.check_temp_stat("attack",1));
        // addcharstat("Defence", $def.check_temp_stat("defense",1));
        if (count($companions) > 0) {
            addcharstat("Companions");
            foreach ($companions as $name => $companion) {
                if ($companion['hitpoints'] > 0 || isset($companion['cannotdie']) && $companion['cannotdie'] == true) {
                    if ($companion['hitpoints'] < 0) {
                        $companion['hitpoints'] = 0;
                    }
                    if ($companion['hitpoints'] < $companion['maxhitpoints']) {
                        $color = "`\$";
                    } else {
                        $color = "`@";
                    }
                    if (isset($companion['suspended']) && $companion['suspended'] == true) {
                        $suspcode = "`7 *";
                    } else {
                        $suspcode = "";
                    }
                    addcharstat($companion['name'], $color . $companion['hitpoints'] . "`7/`&" . $companion['maxhitpoints'] . "{$suspcode}`0");
                }
            }
        }
        addcharstat("Personal Info");
        if ($u['alive']) {
            addcharstat("Requisition", number_format($u['gold'] . check_temp_stat("gold", 1)));
            addcharstat("Cigarettes", number_format($u['gems'] . check_temp_stat("gems", 1)));
        } else {
            addcharstat("Cage Fights", $u['gravefights'] . check_temp_stat("gravefights", 1));
            addcharstat("Favour", number_format($u['deathpower'] . check_temp_stat("deathpower", 1)));
        }
        if ($u['alive']) {
            addcharstat("Level", "`b" . $u['level'] . check_temp_stat("level", 1) . "`b");
            //exp bar
            require_once "lib/experience.php";
            $min = exp_for_next_level($u['level'] - 1, $u['dragonkills']);
            $req = exp_for_next_level($u['level'], $u['dragonkills']);
            $exp = round($session['user']['experience'], 0) . check_temp_stat("experience", 1);
            if ($exp < $min) {
                $min = $exp;
            }
            if ($req - $min > 0) {
                $nonpct = floor(($req - $exp) / ($req - $min) * 100);
            } else {
                $nonpct = 0;
            }
            $pct = 100 - $nonpct;
            if ($pct > 100) {
                $pct = 100;
                $nonpct = 0;
            }
            if ($pct < 0) {
                $pct = 0;
                $nonpct = 100;
            }
            if ($exp >= $req) {
                $color = "blue";
                if ($session['user']['level'] == 1 && $session['user']['dragonkills'] == 0) {
                    $expmsg = "<br />You have enough experience to level up!  Challenge your master in the Dojo!";
                }
            } else {
                $color = "white";
            }
            addcharstat("Experience", number_format($u['experience'] . check_temp_stat("experience", 1)) . "/{$req}<br /><table style='border: solid 1px #000000;' bgcolor='red'  cellpadding='0' cellspacing='0' width='70' height='5'><tr><td width='{$pct}%' bgcolor='{$color}'></td><td width='{$nonpct}%'></td></tr></table>{$expmsg}");
            addcharstat("Equipment Info");
            addcharstat("Weapon", $u['weapon']);
            addcharstat("Armor", $u['armor']);
            if ($u['hashorse']) {
                addcharstat("Creature", $playermount['mountname'] . "`0");
            }
        }
        require_once "lib/datetime.php";
        $gt = gametimedetails();
        addcharstat("Game State");
        addcharstat("Game Time", gmdate("g:i a", $gt['gametime']));
        addcharstat("New day in:", date("H:i:s", secondstonextgameday()));
        modulehook("charstats");
        $charstat = getcharstats($buffs);
        if (!is_array($session['bufflist'])) {
            $session['bufflist'] = array();
        }
        return $charstat;
    } else {
        $ret = "";
        if ($ret = datacache("charlisthomepage")) {
        } else {
            $onlinecount = 0;
            // If a module wants to do it's own display of the online chars,
            // let it.
            $list = modulehook("onlinecharlist", array());
            if (isset($list['handled']) && $list['handled']) {
                $onlinecount = $list['count'];
                $ret = $list['list'];
            } else {
                $sql = "SELECT name,alive,location,sex,level,laston,loggedin,lastip,uniqueid FROM " . db_prefix("accounts") . " WHERE locked=0 AND loggedin=1 AND laston>'" . date("Y-m-d H:i:s", strtotime("-" . getsetting("LOGINTIMEOUT", 900) . " seconds")) . "' ORDER BY level DESC";
                $result = db_query($sql);
                $ret .= appoencode(sprintf(translate_inline("`bOnline Characters (%s players):`b`n"), db_num_rows($result)));
                while ($row = db_fetch_assoc($result)) {
                    $ret .= appoencode("`^{$row['name']}`n");
                    $onlinecount++;
                }
                db_free_result($result);
                if ($onlinecount == 0) {
                    $ret .= appoencode(translate_inline("`iNone`i"));
                }
            }
            savesetting("OnlineCount", $onlinecount);
            savesetting("OnlineCountLast", strtotime("now"));
            updatedatacache("charlisthomepage", $ret);
        }
        return $ret;
    }
}
        $actinfo = process_action("Decorating");
        if ($actinfo['lvlinfo']['levelledup']) {
            output("`n`c`b`0You gained a level in Decorating!  You are now level %s!  This action will cost fewer Stamina points now.`b`c`n", $actinfo['lvlinfo']['newlvl']);
        }
        $house['data']['rooms'][$rid]['dec']['done'] += 1;
        //check if the job's done
        if ($house['data']['rooms'][$rid]['dec']['done'] == $house['data']['rooms'][$rid]['dec']['req']) {
            output("The decorating job is completed!  You step back and admire your work.  Pretty nice!`n`n");
            $house['data']['rooms'][$rid]['desc'] = $house['data']['rooms'][$rid]['dec']['desc'];
            unset($house['data']['rooms'][$rid]['dec']);
            $eraseroomdec = "DELETE FROM " . db_prefix("room_prefs") . " WHERE pref = 'dec' AND hid = '{$hid}' AND rid = '{$rid}'";
            db_query($eraseroomdec);
        } else {
            output("You set about painting and decorating.  Before too long, the room is one step closer to being fully decorated.`n`n");
            require_once "lib/bars.php";
            $bar = fadebar($house['data']['rooms'][$rid]['dec']['done'], $house['data']['rooms'][$rid]['dec']['req'], 150, 5);
            rawoutput("Decoration completion status: " . $bar);
            addnav("Decorate some more?");
            require_once "modules/staminasystem/lib/lib.php";
            if (get_stamina() == 100) {
                $cost = stamina_getdisplaycost("Decorating");
                addnav(array("Decorate some more (`Q%s%%`0)", $cost), "runmodule.php?module=improbablehousing&op=decorate&subop=decorate&hid={$hid}&rid={$rid}");
            } else {
                addnav("You're too tired to do any more sprucing up right now.", "");
            }
        }
        improbablehousing_sethousedata($house);
        break;
}
improbablehousing_bottomnavs($house);
page_footer();
function donationextend_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "donation":
            require_once "lib/gamelog.php";
            gamelog("Donation registered by donationextend");
            $amt = $args['amt'];
            $id = $args['id'];
            $kitty = get_module_setting("kitty");
            $newkitty = $kitty + $amt;
            set_module_setting("kitty", $newkitty);
            //set last player
            if (!get_module_pref("user_shy", "donationextend", $id)) {
                $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid='{$id}'";
                $result = db_query_cached($sql, "donationextend_lastdonator", 300);
                $row = db_fetch_assoc($result);
                $name = $row['name'] . "`0";
                set_module_setting("lastdonator", $name);
            } else {
                set_module_setting("lastdonator", "Anonymous");
            }
            break;
        case "everyfooter":
            //debug($args,true);
            // Set up and decrement the kitty
            require_once "lib/bars.php";
            $last = get_module_setting("lasttick");
            $ext1 = get_module_setting("extend1cost");
            $player = get_module_setting("lastdonator");
            $player = appoencode(stripslashes($player));
            $elapsed = time() - $last;
            $dropped = 0;
            $droppertenseconds = get_module_setting("extend1cost") / 8640;
            if ($elapsed > 10) {
                $dropped = $droppertenseconds;
            }
            $oldkitty = get_module_setting("kitty");
            $newkitty = $oldkitty - $dropped;
            if ($newkitty < 0) {
                $newkitty = 0;
            }
            //set up display output
            $out = "";
            $sql = "SELECT count(acctid) AS c FROM " . db_prefix("accounts") . " WHERE locked=0";
            $result = db_query_cached($sql, "donationextend_totalplayers", 1800);
            $row = db_fetch_assoc($result);
            $totalplayers = $row['c'];
            if ($newkitty > $ext1) {
                $ext2 = get_module_setting("extend2cost");
                if ($newkitty > $ext2) {
                    $over = $newkitty - $ext2;
                    $bar = simplebar($over, $ext2, 70, 5, "AA00AA", "FFFFFF");
                    $overdisp = number_format($over / 100, 2);
                    //represent as time left to end of Special Extend period
                    $droppersec = get_module_setting("extend1cost") / 86400;
                    $secsleft = round($over / $droppersec);
                    $expirationtime = time() + $secsleft;
                    require_once "lib/datetime.php";
                    $expirein = reltime($expirationtime, false);
                    $out .= "<span style='font-size:smaller'><strong>Special Extend active!</strong><br />" . $bar . "Thank you for your support!  Special Extend expires in " . $expirein . "<br /><a href='runmodule.php?module=donationextend' target='_blank' onclick=\"" . popup("runmodule.php?module=donationextend") . ";return false;\">(what's a Special Extend?)</span></a>";
                } else {
                    $moreneeded = $ext2 - $newkitty;
                    $bar = simplebar($newkitty - $ext1, $ext2 - $ext1, 70, 5, "00FF00", "AA00AA");
                    $moredisp = number_format($moreneeded / 100, 2);
                    $out .= "<span style='font-size:smaller'><strong>Extended Play active!</strong><br />" . $bar . "\$" . $moredisp . " more for <a href='runmodule.php?module=donationextend' target='_blank' onclick=\"" . popup("runmodule.php?module=donationextend") . ";return false;\">Special Extend</a>!</span>";
                }
            } else {
                $moreneeded = $ext1 - $newkitty;
                $moredisp = number_format($moreneeded / 100, 2);
                $bar = fadebar($newkitty, $ext1, 57);
                $perplayer = $moreneeded / 100 / $totalplayers;
                if ($perplayer > 1) {
                    $perplayerdisp = "about " . round($moreneeded / $totalplayers, 4) . " cents per player";
                } else {
                    $perplayerdisp = "about \$" . number_format($moreneeded / 100 / $totalplayers, 2) . " per player";
                }
                $out .= $bar;
                if ($newkitty > 0) {
                    $out .= "<span style='font-size:smaller'>\$" . $moredisp . " more (" . $perplayerdisp . ") for <a href='runmodule.php?module=donationextend' target='_blank' onclick=\"" . popup("runmodule.php?module=donationextend") . ";return false;\">Extended Play</a>!</span>";
                } else {
                    if ($session['user']['loggedin']) {
                        $out .= "<span class='colDkRed'><strong>The kitty is empty!</strong></span>  Improbable Island is entirely dependant on your donations to survive.  When the meter is empty, the Island and its creators are in trouble!  Someone please chuck a couple of bucks in the hat!";
                    }
                }
            }
            global $template;
            //debug($template);
            if (strpos($template['footer'], "{paypal_extras}")) {
                //if (isset($template['{paypal_extras}'])){
                //debug("Yes!");
                $rep = "paypal_extras";
            } else {
                //debug("No!");
                $rep = "paypal";
            }
            //$rep = "paypal_extras";
            //insert display output into page
            if (!array_key_exists($rep, $args) || !is_array($args[$rep])) {
                $args[$rep] = array();
            }
            array_push($args[$rep], $out);
            //write values back to database
            if ($elapsed > 10) {
                set_module_setting("lasttick", time());
                set_module_setting("kitty", $newkitty);
            }
            //debug($args,true);
            addcharstat("Misc");
            addcharstat("Misc", "testing testing woohoo!");
            break;
        case "stamina-newday":
            $kitty = get_module_setting("kitty");
            if ($kitty >= get_module_setting("extend1cost")) {
                require_once "modules/staminasystem/lib/lib.php";
                $bonus = get_module_setting("extend1amt");
                if ($kitty > get_module_setting("extend2cost")) {
                    $bonus += get_module_setting("extend2amt");
                    output("`0Because Improbable Island's players have been especially generous, today is a `b`5Special Extended Play`0`b day - you `2gain`0 some Stamina!`n`n");
                } else {
                    output("`0Because Improbable Island's server costs and advertising budget have been covered quite nicely by donations, today is an `b`2Extended Play`0`b day - you `2gain`0 some Stamina!`n`n");
                }
                if ($session['user']['donation'] > 0) {
                    $bonus = $bonus * 2;
                }
                addstamina($bonus);
            }
            break;
    }
    return $args;
}