function rail_peddler_run()
{
    global $session, $inventory;
    $op = httpget("op");
    $loc = rail_peddler_getloc();
    $hid = $loc["peddlerhid"];
    $rid = $loc["peddlerrid"];
    $price = get_module_setting("peddlerprice");
    if ($op == "buy") {
        $headertext = "Why sure, I'll take one of those!";
    } else {
        $headertext = "Go away, I'm busy.";
    }
    page_header($headertext);
    switch ($op) {
        case "buy":
            output("The scruffy vendor's eyes gleam. Was that a fla`gs`0h of green, or no? \"`2Verra wise, %s. Ye willna be sorry!`0\"`n`n", translate_inline($session['user']['sex'] ? 'lass' : 'lad'));
            give_item("cardcase");
            //			if (!$success){
            //				output("Then -- a frown. \"`2Wait, no, I canna sell t'ye. Ye'd better petition the Big Boss, tell 'im t'see what's gaen wrong wiv all dis.`0\"`n`n");
            //			} else {
            output("You have a fine leather card case. Pleased, you admire its soft texture. What an excellent purchase you have made!`n`n");
            //			}
            $session['user']['gems'] -= $price;
            break;
        case "pass":
            output("\"`2Bleedin' smart-arse.`0\" The scruffy vendor shrugs and goes off to pester someone else.`n`n");
            break;
    }
    addnav("Back to the Concourse", "runmodule.php?module=improbablehousing&op=interior&hid={$hid}&rid={$rid}");
    page_footer();
}
function avatar_showimages($set)
{
    $races = modulehook("racenames");
    rawoutput("<table cellpadding='0' cellspacing='0' border='0' bgcolor='#999999'>");
    $r = translate_inline("Race");
    $m = translate_inline("Male Image");
    $f = translate_inline("Female Image");
    rawoutput("<tr class='trhead'><th>{$r}</th><th>{$m}</th><th>{$f}</th></tr>");
    $i = 0;
    foreach ($races as $key => $race) {
        $r = strtolower($race);
        $imm = avatar_getimage($r, "male", $set);
        $imf = avatar_getimage($r, "female", $set);
        rawoutput("<tr class='" . ($i % 2 ? "trlight" : "trdark") . "'>");
        rawoutput("<th>");
        output_notl('`^');
        output($race);
        output_notl("`0");
        rawoutput("</th><td>");
        rawoutput($imm);
        rawoutput("</td><td>");
        rawoutput($imf);
        rawoutput("</td>");
        rawoutput("</tr>");
        $i++;
    }
    rawoutput("</table>");
}
function nooblube_dohook($hookname, $args)
{
    global $session, $badguy;
    switch ($hookname) {
        case "battle-defeat":
            //check to see if they're alive first, 'cause otherwise it'll add favour when they get wiped out on the FailBoat
            if ($session['user']['alive'] == false) {
                break;
            }
            //check to see if they've got any hitpoints, for stuff like the Tattoo Monster and defeating their masters
            if ($session['user']['hitpoints'] > 0) {
                break;
            }
            $maxlevel = get_module_setting("level");
            $currentlevel = $session['user']['level'];
            if ($currentlevel < $maxlevel) {
                if ($session['user']['dragonkills'] == 0) {
                    if ($session['user']['deathpower'] < 100) {
                        $session['user']['deathpower'] = get_module_setting("lube");
                    }
                    $tutormsg = translate_inline("`#What did I tell you about being careful?  Bloody newbies.  Okay, those nice gentlemen coming towards you will pick you up and drag you to my FailBoat, but don't worry about it too much.  Just come and see me below decks and I'll get you put on the next boat back to the Island.  Don't get used to it though, matey - once you hit level ten, you'll have to fight for your freedom like everyone else.");
                    if ($tutormsg) {
                        tutor_talk("%s", $tutormsg);
                    }
                }
            }
            break;
    }
    return $args;
}
function friendlist_search()
{
    global $session;
    $n = httppost("n");
    rawoutput("<form action='runmodule.php?module=friendlist&op=search' method='POST'>");
    addnav("", "runmodule.php?module=friendlist&op=search");
    if ($n != "") {
        $string = "%";
        for ($x = 0; $x < strlen($n); $x++) {
            $string .= substr($n, $x, 1) . "%";
        }
        $sql = "SELECT name,dragonkills,acctid FROM " . db_prefix("accounts") . " WHERE name LIKE '%{$string}%' AND acctid<>" . $session['user']['acctid'] . " AND locked=0 ORDER BY level,dragonkills";
        $result = db_query($sql);
        if (db_num_rows($result) > 0) {
            $ignored = rexplode(get_module_pref('ignored'));
            $friends = rexplode(get_module_pref('friends'));
            $request = rexplode(get_module_pref('request'));
            $iveignored = rexplode(get_module_pref('iveignored'));
            output("`@These users were found:`n");
            rawoutput("<table style='width:60%;text-align:center;' cellpadding='3' cellspacing='0' border='0'>");
            rawoutput("<tr class='trhead'><td>" . translate_inline("Name") . "</td><td>" . translate_inline("Operations") . "</td></tr>");
            for ($i = 0; $i < db_num_rows($result); $i++) {
                $row = db_fetch_assoc($result);
                rawoutput("<tr class='" . ($i % 2 ? "trlight" : "trdark") . "'><td>");
                output_notl($row['name']);
                rawoutput("</td><td>");
                if (in_array($row['acctid'], $ignored)) {
                    $info = translate_inline("This user has ignored you.");
                    $info .= " [<a href='runmodule.php?module=friendlist&op=ignore&ac=" . $row['acctid'] . "' class='colDkGreen'>" . translate_inline("Ignore") . "</a>]";
                    addnav("", "runmodule.php?module=friendlist&op=ignore&ac=" . $row['acctid']);
                } elseif (in_array($row['acctid'], $friends)) {
                    $info = translate_inline("This user is already in your list.");
                } elseif (in_array($row['acctid'], $request)) {
                    $info = translate_inline("This user has already requested to you.");
                } else {
                    if (in_array($row['acctid'], $iveignored)) {
                        $info = "[<a href='runmodule.php?module=friendlist&op=unignore&ac=" . $row['acctid'] . "' class='colLtRed'>" . translate_inline("Unignore") . "</a>]";
                        addnav("", "runmodule.php?module=friendlist&op=unignore&ac=" . $row['acctid']);
                    } else {
                        $info = "[<a href='runmodule.php?module=friendlist&op=ignore&ac=" . $row['acctid'] . "' class='colDkGreen'>" . translate_inline("Ignore") . "</a>]";
                        addnav("", "runmodule.php?module=friendlist&op=ignore&ac=" . $row['acctid']);
                        $info .= " - [<a href='runmodule.php?module=friendlist&op=request&ac=" . $row['acctid'] . "' class='colDkGreen'>" . translate_inline("Request") . "</a>]";
                        addnav("", "runmodule.php?module=friendlist&op=request&ac=" . $row['acctid']);
                    }
                }
                rawoutput("{$info}</td></tr>");
            }
            rawoutput("</table>");
        } else {
            output("`c`@`bA user was not found with that name.`b`c");
        }
        output_notl("`n");
    }
    output("`^`b`cFriend Search...`c`b");
    output("`n`nWho do you want to search for?");
    output("`n`nName of user: "******"<input name='n' maxlength='50' value=\"" . htmlentities(stripslashes(httppost('n'))) . "\">");
    $apply = translate_inline("Search");
    rawoutput("<input type='submit' class='button' value='{$apply}'></form>");
}
function checkban(string $login, bool $connect = false) : bool
{
    global $session;
    $accounts = db_prefix('accounts');
    $bans = db_prefix('accounts');
    $today = date('Y-m-d');
    $sql = db_query("SELECT lastip, uniquid, banoverride, superuser FROM {$accounts}\n        WHERE login = '******'");
    $row = db_fetch_assoc($sql);
    if ($row['banoverride'] || $row['superuser'] & ~SU_DOESNT_GIVE_GROTTO) {
        return false;
    }
    db_free_result($sql);
    $sql = db_query("SELECT * FROM {$bans}\n        WHERE (\n            (ipfilter = '{$row['lastip']}' OR ipfilter = '{$_SERVER['REMOTE_ADDR']}')\n            OR (uniqueid = '{$row['uniqueid']}' OR uniqueid = '{$_COOKIE['lgi']}')\n        )\n        AND (banexpire = '000-00-00' OR banexpire >= '{$today}')");
    if (db_num_rows($sql) > 0) {
        if ($connect) {
            $session = [];
            tlschema('ban');
            $session['message'] .= translate_inline('`n`4You fall under a ban currently in place on this website:');
            while ($row = db_fetch_assoc($sql)) {
                $session['message'] .= "`n{$row['banreason']}`n";
                if ($row['banexpire'] == '0000-00-00') {
                    $session['message'] .= translate_inline("`\$This ban is permanent!`0");
                } else {
                    $session['message'] .= sprintf_translate("`^This ban will be removed `\$after`^ %s.`0", date("M d, Y", strtotime($row['banexpire'])));
                }
                db_query("UPDATE {$bans}\n                    SET lasthit = '{$today} 00:00:00'\n                    WHERE ipfilter = '{$row['ipfilter']}'\n                    AND uniqueid = '{$row['uniqueid']}'\n                    ");
            }
            $session['message'] .= translate_inline("`n`4If you wish, you may appeal your ban with the petition link.");
            tlschema();
            header('Location: home.php');
        }
        return true;
    }
    return false;
}
function relativedate(string $indate) : string
{
    $lastOn = round((strtotime('now') - strtotime($indate)) / 86400, 0) . 'days';
    tlschema('datetime');
    if (substr($lastOn, 0, 2) == '1 ') {
        $lastOn = translate_inline('1 day');
    } else {
        if (date('Y-m-d', strtotime($lastOn)) == date('Y-m-d')) {
            $lastOn = translate_inline('Today');
        } else {
            if (date('Y-m-d', strtotime($lastOn)) == date('Y-m-d', strtotime('-1 day'))) {
                $lastOn = translate_inline('Yesterday');
            } else {
                if (strpos($indate, '0000-00-00') !== false) {
                    $lastOn = translate_inline('Never');
                } else {
                    $lastOn = sprintf_translate('%s days', round((strtotime('now') - strtotime($indate)) / 86400, 0));
                    rawoutput(tlbutton_clear());
                }
            }
        }
    }
    tlschema();
    return $lastOn;
}
function dwshacks_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "dwellings-list-type":
            addnav("Show Only Types");
            addnav(array("%s", translate_inline(ucfirst(get_module_setting("dwnameplural", "dwshacks")))), "runmodule.php?module=dwellings&op=list&showonly=dwshacks&ref={$args['ref']}&sortby={$args['sortby']}&order={$args['order']}");
            break;
        case "dwellings-list-interact":
            if ($args['type'] == "dwshacks" && $args['status'] == 1 && get_module_setting("maxkeys") == 123456789) {
                addnav("", "runmodule.php?module=dwellings&op=enter&dwid={$args['dwid']}");
                $tress = translate_inline("Tresspass");
                rawoutput("<a href='runmodule.php?module=dwellings&op=enter&dwid={$args['dwid']}'>{$tress}</a>");
            }
            break;
        case "dwellings-manage":
            $dwid = $args['dwid'];
            if (get_module_setting("maxkeys") == 123456789 && $args['type'] == "dwshacks") {
                blocknav("runmodule.php?module=dwellings&op=keys&dwid={$dwid}");
            }
            break;
        case "dwellings":
            if (get_module_objpref("city", $args['cityid'], "showdwshacks")) {
                output("  Along the narrow pathway, precariously placed wood planks are nailed and leaning on each other in a fashion that only leaves you to assume they are supposed to be %s.`0", translate_inline(get_module_setting("dwnameplural")));
                if ($args['allowbuy'] == 1 && $session['user']['dragonkills'] >= get_module_setting("dkreq")) {
                    $cityid = $args['cityid'];
                    addnav("Options");
                    addnav(array("Establish a %s", translate_inline(ucfirst(get_module_setting("dwname", "dwshacks")))), "runmodule.php?module=dwellings&op=buy&type=dwshacks&subop=presetup&cityid={$cityid}");
                }
            }
            break;
    }
    return $args;
}
/**
 * Outputs a list of all enemies and the player.
 *
 * @param array $enemies The enemies to be displayed.
 */
function show_enemies($enemies)
{
    global $enemycounter, $session;
    foreach ($enemies as $index => $badguy) {
        if (isset($badguy['istarget']) && $badguy['istarget'] == true && $enemycounter > 1) {
            $ccode = "`#";
        } else {
            $ccode = "`2";
        }
        if (isset($badguy['hidehitpoints']) && $badguy['hidehitpoints'] == true) {
            $health = "???";
        } else {
            $health = $badguy['creaturehealth'];
        }
        if ($session['user']['alive']) {
            output("%s%s%s%s's Hitpoints%s (Level %s): `6%s`0`n", $ccode, isset($badguy['istarget']) && $badguy['istarget'] && $enemycounter > 1 ? "*" : "", $badguy['creaturename'], $ccode, $ccode, $badguy['creaturelevel'], $badguy['creaturehealth'] > 0 ? $health : translate_inline("`7DEAD`0"));
        } else {
            output("`2%s`2's Soulpoints: `6%s`0`n", $badguy['creaturename'], $badguy['creaturehealth'] > 0 ? $health : translate_inline("`7DEFEATED`0"));
        }
    }
    if ($session['user']['alive']) {
        output("`2YOUR Hitpoints: `6%s`0`n", $session['user']['hitpoints']);
    } else {
        output("`2YOUR Soulpoints: `6%s`0`n", $session['user']['hitpoints']);
    }
}
function friendlist_unignore()
{
    global $session;
    $ac = httpget('ac');
    $ignored = rexplode(get_module_pref('ignored', 'friendlist', $ac));
    $iveignored = rexplode(get_module_pref('iveignored'));
    if (in_array($ac, $iveignored)) {
        $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid={$ac} AND locked=0";
        $result = db_query($sql);
        if (db_num_rows($result) > 0) {
            $row = db_fetch_assoc($result);
            $info = sprintf_translate("%s`Q has been removed from your list.", $row['name']);
            require_once "lib/systemmail.php";
            $t = array("`\$Ignore List Removal");
            $mailmessage = array("%s`0`@ has removed you from %s ignore list.", $session['user']['name'], $session['user']['sex'] ? translate_inline("her") : translate_inline("his"));
            systemmail($ac, $t, $mailmessage);
        } else {
            $info = translate_inline("That user no longer exists...");
        }
    }
    $ignored = array_diff($ignored, array($session['user']['acctid']));
    $ignored = rimplode($ignored);
    set_module_pref('ignored', $ignored, 'friendlist', $ac);
    if (in_array($ac, $iveignored)) {
        $iveignored = array_diff($iveignored, array($ac));
        $iveignored = rimplode($iveignored);
        set_module_pref('iveignored', $iveignored);
    }
    output_notl($info);
}
function monsterkills_run()
{
    page_header("Most Monster Kills");
    $acc = db_prefix("accounts");
    $mp = db_prefix("module_userprefs");
    $sql = "SELECT {$acc}.name AS name,\r\n\t\t{$acc}.acctid AS acctid,\r\n\t\t{$mp}.value AS kills,\r\n\t\t{$mp}.userid FROM {$mp} INNER JOIN {$acc}\r\n\t\tON {$acc}.acctid = {$mp}.userid \r\n\t\tWHERE {$mp}.modulename = 'monsterkills' \r\n\t\tAND {$mp}.setting = 'kills' \r\n\t\tAND {$mp}.value > 0 ORDER BY ({$mp}.value+0)\t\r\n\t\tDESC limit " . get_module_setting("list") . "";
    $result = db_query($sql);
    $rank = translate_inline("Kills");
    $name = translate_inline("Name");
    output("`n`b`c`@Most`\$ Monster `@Kills`n`n`c`b");
    rawoutput("<table border='0' cellpadding='2' cellspacing='1' align='center'>");
    rawoutput("<tr class='trhead'><td align=center>{$name}</td><td align=center>{$rank}</td></tr>");
    for ($i = 0; $i < db_num_rows($result); $i++) {
        $row = db_fetch_assoc($result);
        if ($row['name'] == $session['user']['name']) {
            rawoutput("<tr class='trhilight'><td>");
        } else {
            rawoutput("<tr class='" . ($i % 2 ? "trdark" : "trlight") . "'><td align=left>");
        }
        output_notl("%s", $row['name']);
        rawoutput("</td><td align=right>");
        output_notl("%s", $row['kills']);
        rawoutput("</td></tr>");
    }
    rawoutput("</table>");
    addnav("Back to HoF", "hof.php");
    villagenav();
    page_footer();
}
function faqmute_dohook($hookname, $args)
{
    global $session;
    $seen = get_module_pref("seenfaq");
    switch ($hookname) {
        case "insertcomment":
            if (!$seen && !$session['user']['dragonkills']) {
                $args['mute'] = 1;
                $mutemsg = "`n`\$You have to read the FAQ before you can post comments. You can find it in any town.`0`n`n";
                $mutemsg = translate_inline($mutemsg);
                $args['mutemsg'] = $mutemsg;
            }
            break;
        case "faq-posttoc":
            if (!$seen) {
                set_module_pref("seenfaq", true);
            }
            break;
        case "bioinfo":
            $id = $args['acctid'];
            $seen = get_module_pref("seenfaq", false, $id);
            if (httpget("op") == "faqmute") {
                set_module_pref("seenfaq", false, false, $id);
                output("`nPlayer's FAQ seen status reset.`n");
            } elseif ($session['user']['superuser'] & SU_EDIT_COMMENTS && $seen && !$args['dragonkills']) {
                addnav("Mute Player Options");
                addnav("FAQmute player", "bio.php?char=" . $id . "&ret=" . rawurlencode(httpget("ret")) . "&op=faqmute");
            }
            break;
    }
    return $args;
}
function dhms($secs, $dec = false)
{
    if ($dec === false) {
        $secs = round($secs, 0);
    }
    return (int) ($secs / 86400) . translate_inline("d", "datetime") . (int) ($secs / 3600 % 24) . translate_inline("h", "datetime") . (int) ($secs / 60 % 60) . translate_inline("m", "datetime") . $secs % 60 . ($dec ? substr($secs - (int) $secs, 1) : "") . translate_inline("s", "datetime");
    //use multiple translate_inlines as this function is not called too often...if you deactive stats...
}
function lovers_chat_seth()
{
    global $session;
    if (httpget("act") == "") {
        output("You make your way over to where %s`0 is sitting, ale in hand.", getsetting("bard", "`^Seth"));
        output("Sitting down, and waiting for %s`0 to finish a song, you light your pipe.", getsetting("bard", "`^Seth"));
        addnav("Ask about your manliness", "runmodule.php?module=lovers&op=chat&act=armor");
        addnav("Discuss Sports", "runmodule.php?module=lovers&op=chat&act=sports");
    } elseif (httpget("act") == "sports") {
        output("You and %s`0 spend some time talking about the recent dwarf tossing competition.", getsetting("bard", "`^Seth"));
        output("Not wanting to linger around another man for too long, so no one \"wonders\", you decide you should find something else to do.");
    } else {
        $charm = $session['user']['charm'] + e_rand(-1, 1);
        output("%s`0 looks you up and down very seriously.", getsetting("bard", "`^Seth"));
        output("Only a friend can be truly honest, and that is why you asked him.");
        switch ($charm) {
            case -3:
            case -2:
            case -1:
            case 0:
                $msg = translate_inline("You make me glad I'm not gay!");
                break;
            case 1:
            case 2:
            case 3:
                $msg = translate_inline("I've seen some handsome men in my day, but I'm afraid you aren't one of them.");
                break;
            case 4:
            case 5:
            case 6:
                $msg = translate_inline("I've seen worse my friend, but only trailing a horse.");
                break;
            case 7:
            case 8:
            case 9:
                $msg = translate_inline("You're of fairly average appearance my friend.");
                break;
            case 10:
            case 11:
            case 12:
                $msg = translate_inline("You certainly are something to look at, just don't get too big of a head about it, eh?");
                break;
            case 13:
            case 14:
            case 15:
                $msg = translate_inline("You're quite a bit better than average!");
                break;
            case 16:
            case 17:
            case 18:
                $msg = translate_inline("Few women would be able to resist you!");
                break;
            default:
                $msg = translate_inline("I hate you, why, you are simply the most handsome man ever!");
        }
        output("Finally he reaches a conclusion and states, \"%s`0\"", $msg);
    }
}
function do_forced_nav($anonymous, $overrideforced)
{
    global $baseaccount, $session, $REQUEST_URI;
    rawoutput("<!--\nAllowAnonymous: " . ($anonymous ? "True" : "False") . "\nOverride Forced Nav: " . ($overrideforced ? "True" : "False") . "\n-->");
    if (isset($session['loggedin']) && $session['loggedin']) {
        $sql = "SELECT *  FROM " . db_prefix("accounts") . " WHERE acctid = '" . $session['user']['acctid'] . "'";
        $result = db_query($sql);
        if (db_num_rows($result) == 1) {
            $session['user'] = db_fetch_assoc($result);
            $baseaccount = $session['user'];
            $session['bufflist'] = unserialize($session['user']['bufflist']);
            if (!is_array($session['bufflist'])) {
                $session['bufflist'] = array();
            }
            $session['user']['dragonpoints'] = unserialize($session['user']['dragonpoints']);
            $session['user']['prefs'] = unserialize($session['user']['prefs']);
            if (!is_array($session['user']['dragonpoints'])) {
                $session['user']['dragonpoints'] = array();
            }
            if (is_array(unserialize($session['user']['allowednavs']))) {
                $session['allowednavs'] = unserialize($session['user']['allowednavs']);
            } else {
                $session['allowednavs'] = array($session['user']['allowednavs']);
            }
            if (!$session['user']['loggedin'] || date("U") - strtotime($session['user']['laston']) > getsetting("LOGINTIMEOUT", 900)) {
                $session = array();
                redirect("index.php?op=timeout", "Account not logged in but session thinks they are.");
            }
        } else {
            $session = array();
            $session['message'] = translate_inline("`4Error, your login was incorrect`0", "login");
            redirect("index.php", "Account Disappeared!");
        }
        db_free_result($result);
        //check the nav exists in the session's allowednavs array
        if (isset($session['allowednavs'][$REQUEST_URI]) && $session['allowednavs'][$REQUEST_URI] && $overrideforced !== true) {
            //The nav is fine
            //clear the navs - more navs will be added as the script the player is currently viewing loads and executes
            $session['allowednavs'] = array();
        } else {
            if ($overrideforced !== true) {
                //This nav is not fine at all.  Redirect the player to badnav.php.
                $session['badnav'] = 1;
                redirect("badnav.php", "Navigation not allowed to {$REQUEST_URI}");
            }
        }
    } else {
        if (!$anonymous) {
            $session['message'] = translate_inline("You are not logged in, this may be because your session timed out.", "login");
            redirect("index.php?op=timeout&nli=true", "Not logged in: {$REQUEST_URI}");
        }
    }
}
function tip()
{
    global $tipid;
    $tip = translate_inline("Tip");
    output_notl("<div style='cursor: pointer; cursor: hand; display: inline;' onMouseOver=\"tip{$tipid}.style.visibility='visible'; tip{$tipid}.style.display='inline';\" onMouseOut=\"tip{$tipid}.style.visibility='hidden'; tip{$tipid}.style.display='none';\">`i[ `b{$tip}`b ]`i", true);
    rawoutput("<div class='debug' id='tip{$tipid}' style='position: absolute; width: 200px; max-width: 200px; float: right;'>");
    $args = func_get_args();
    call_user_func_array("output", $args);
    rawoutput("</div></div>");
    rawoutput("<script language='JavaScript'>var tip{$tipid} = document.getElementById('tip{$tipid}'); tip{$tipid}.style.visibility='hidden'; tip{$tipid}.style.display='none';</script>");
    $tipid++;
}
function dwellingscostsp_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "dwellings-buy-valuecheck":
            $typeid = get_module_setting("typeid", $args['type']);
            $paidsp = abs((int) httppost('paidsp'));
            if ($paidsp < 0) {
                $paidsp = 0;
            }
            $pointsavailable = $session['user']['donation'] - $session['user']['donationspent'];
            if ($pointsavailable < $paidsp) {
                $args['allowpay'] = 0;
                blocknav("runmodule.php?module=dwellings&op=build&type=" . $args['type'] . "&dwid=" . $args['dwid'] . "");
                output("`nYou do not have that many site points.");
            } elseif ($paidsp > get_module_objpref("dwellingtypes", $typeid, "spcost") - get_module_objpref("dwellings", $args['dwid'], "spspent")) {
                $args['allowpay'] = 0;
                blocknav("runmodule.php?module=dwellings&op=build&type=" . $args['type'] . "&dwid=" . $args['dwid'] . "");
                output("`nYou have tried to spend more site points than you need to.");
            }
            break;
        case "dwellings-buy-setup":
            $typeid = get_module_setting("typeid", $args['type']);
            $paidsp = abs((int) httppost('paidsp'));
            if ($paidsp < 0) {
                $paidsp = 0;
            }
            $spent = get_module_objpref("dwellings", $args['dwid'], "spspent") + $paidsp;
            set_module_objpref("dwellings", $args['dwid'], "spspent", $spent);
            $session['user']['donationspent'] += $paidsp;
            if ($spent != get_module_objpref("dwellingtypes", $typeid, "spcost")) {
                $args['finished'] = 0;
            }
            break;
        case "dwellings-pay-costs":
            $typeid = get_module_setting("typeid", $args['type']);
            $costsp = get_module_objpref("dwellingtypes", $typeid, "spcost") - get_module_objpref("dwellings", $args['dwid'], "spspent");
            if ($costsp) {
                output("`#%s Site Points`0`n", $costsp);
            }
            break;
        case "dwellings-pay-input":
            $typeid = get_module_setting("typeid", $args['type']);
            $costsp = get_module_objpref("dwellingtypes", $typeid, "spcost") - get_module_objpref("dwellings", $args['dwid'], "spspent");
            $sp = translate_inline("Site Points");
            if ($costsp) {
                rawoutput("{$sp}: <input id='input' name='paidsp' width=5><br>");
            }
            break;
    }
    return $args;
}
function mysticalshop_buffs_run()
{
    global $session;
    $title = translate_inline("Equipment Buffs Manager");
    page_header($title);
    $op = httpget('op');
    $id = httpget("id");
    $from = "runmodule.php?module=mysticalshop_buffs&";
    if ($op == "editor") {
        require_once "modules/mysticalshop_buffs/editor.php";
    }
    page_footer();
}
function forest($noshowmessage = false)
{
    global $session, $playermount;
    tlschema("forest");
    //	mass_module_prepare(array("forest", "validforestloc"));
    addnav("Heal");
    addnav("H?Hospital Tent", "healer.php");
    addnav("Fight");
    addnav("L?Look for Something to Kill", "forest.php?op=search");
    if ($session['user']['level'] > 1) {
        addnav("S?Go Slumming", "forest.php?op=search&type=slum");
    }
    addnav("T?Go Thrillseeking", "forest.php?op=search&type=thrill");
    if (getsetting("suicide", 0)) {
        if (getsetting("suicidedk", 10) <= $session['user']['dragonkills']) {
            addnav("*?Search `\$Suicidally`0", "forest.php?op=search&type=suicide");
        }
    }
    if ($session['user']['level'] >= 15 && $session['user']['seendragon'] == 0) {
        // Only put the green dragon link if we are a location which
        // should have a forest.   Don't even ask how we got into a forest()
        // call if we shouldn't have one.   There is at least one way via
        // a superuser link, but it shouldn't happen otherwise.. We just
        // want to make sure however.
        $isforest = 0;
        $vloc = modulehook('validforestloc', array());
        foreach ($vloc as $i => $l) {
            if ($session['user']['location'] == $i) {
                $isforest = 1;
                break;
            }
        }
        if ($isforest || count($vloc) == 0) {
            addnav("G?`@Seek Out the Green Dragon", "forest.php?op=dragon");
        }
    }
    addnav("Other");
    villagenav();
    if ($noshowmessage != true) {
        $foresttext = array();
        tlschema();
        $foresttext[] = translate_inline("The Jungle, home to the vicious creatures of Doktor Improbable's obscene laboratories - and to various evildoers of all descriptions.`n`nThe thick foliage of the jungle restricts your view to only a few yards in most places.  The paths would be imperceptible except for your trained eye.  You move as silently as a soft breeze across the thick moss covering the ground, wary to avoid stepping on a twig or any of the numerous pieces of bleached bone that populate the jungle floor, lest you betray your presence to one of the vile beasts that wander this place.`n`nThen you think \"`#Sod it,`0\" and tear off looking for something to kill.`n`n");
        $foresttext = modulehook("forest-desc", $foresttext);
        output($foresttext);
    }
    modulehook("forest", array());
    module_display_events("forest", "forest.php");
    addnav("Inventory");
    addnav("View your Inventory", "inventory.php?items_context=forest");
    tlschema();
}
function clanform()
{
    rawoutput("<form action='clan.php?op=new&apply=1' method='POST'>");
    addnav("", "clan.php?op=new&apply=1");
    output("`b`cNew Clan Application Form`c`b");
    output("Clan Name: ");
    rawoutput("<input name='clanname' maxlength='50' value=\"" . htmlentities(stripslashes(httppost('clanname')), ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "\">");
    output("`nShort Name: ");
    rawoutput("<input name='clanshort' maxlength='5' size='5' value=\"" . htmlentities(stripslashes(httppost('clanshort')), ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "\">");
    output("`nNote, color codes are permitted in neither clan names nor short names.");
    output("The clan name is shown on player bios and on clan overview pages while the short name is displayed next to players' names in comment areas and such.`n");
    $apply = translate_inline("Apply");
    rawoutput("<input type='submit' class='button' value='{$apply}'></form>");
}
function mysticalshop_run()
{
    global $session;
    $shop = get_module_setting('shopname');
    $op = httpget('op');
    $from = 'runmodule.php?module=mysticalshop&';
    page_header(full_sanitize($shop));
    $what = httpget('what');
    $cat = httpget('cat');
    if (!is_numeric($cat)) {
        $cat = 0;
    }
    $names = translate_inline(array(0 => 'Rings', 1 => 'Amulets', 2 => 'Weapons', 3 => 'Armor', 4 => 'Cloaks', 5 => 'Helmets', 6 => 'Gloves', 7 => 'Boots', 8 => 'Miscellanea'));
    require_once "./modules/mysticalshop/run/case_{$op}.php";
    page_footer();
}
function marriage_plist($op)
{
    $stuff = explode(',', get_module_pref('proposals'));
    $n = 0;
    if (get_module_pref("proposals") != "") {
        output("`@The following people have proposed to you... click to marry, or reject them!`n`n`c");
        rawoutput("<table cellpadding='3' cellspacing='0' border='0'>");
        rawoutput("<tr class='trhead'><td colspan='7' align='center'><center>");
        output("Proposals");
        rawoutput("</center></td></tr>");
        $marry = translate_inline("`0[`@Marry`0]");
        $reject = translate_inline("`0[`\$Reject`0]");
        foreach ($stuff as $val) {
            if ($val != "") {
                $sql = "SELECT name,marriedto FROM " . db_prefix("accounts") . " WHERE acctid='{$val}' AND locked=0";
                $res = db_query($sql);
                $row = db_fetch_assoc($res);
                //We need this row[marriedto] added to prevent people from marrying someone who's already married
                if (db_num_rows($res) != 0 && $row['marriedto'] == 0) {
                    $n++;
                    rawoutput("<tr " . ($n % 2 ? "trlight" : "trdark") . "><td><a href='runmodule.php?module=marriage&op=" . $op . "&target=" . $val . "&op2=marry'>");
                    output_notl("%s", $marry);
                    rawoutput("</a></td><td><center>");
                    output_notl("`^%s`0", $row['name']);
                    rawoutput("</center></td><td><a href='runmodule.php?module=marriage&op=" . $op . "&target=" . $val . "&op2=reject'>");
                    output_notl("%s", $reject);
                    rawoutput("</a></td>");
                    addnav("", "runmodule.php?module=marriage&op=" . $op . "&target=" . $val . "&op2=marry");
                    addnav("", "runmodule.php?module=marriage&op=" . $op . "&target=" . $val . "&op2=reject");
                }
            }
        }
        if ($n == 0) {
            rawoutput("<tr><td><center>");
            output("`^Aww! No one wants to marry you.");
            rawoutput("</center></td></tr>");
        }
    } else {
        output_notl("`c");
        rawoutput("<table><tr><td><center>");
        output("`^Aww! No one wants to marry you.");
        rawoutput("</center></td></tr>");
    }
    output_notl('</table>', true);
    output_notl("`c");
}
function checkban($login = false)
{
    global $session;
    if (isset($session['banoverride']) && $session['banoverride']) {
        return false;
    }
    if ($login === false) {
        $ip = $_SERVER['REMOTE_ADDR'];
        $id = $_COOKIE['lgi'];
    } else {
        $sql = "SELECT lastip,uniqueid,banoverride,superuser FROM " . db_prefix("accounts") . " WHERE login='******'";
        $result = db_query($sql);
        $row = db_fetch_assoc($result);
        if ($row['banoverride'] || $row['superuser'] & ~SU_DOESNT_GIVE_GROTTO) {
            $session['banoverride'] = true;
            return false;
        }
        db_free_result($result);
        $ip = $row['lastip'];
        $id = $row['uniqueid'];
    }
    $sql = "SELECT * FROM " . db_prefix("bans") . " where ((substring('{$ip}',1,length(ipfilter))=ipfilter AND ipfilter<>'') OR (uniqueid='{$id}' AND uniqueid<>'')) AND (banexpire='0000-00-00' OR banexpire>='" . date("Y-m-d") . "')";
    $result = db_query($sql);
    if (db_num_rows($result) > 0) {
        $session = array();
        tlschema("ban");
        $session['message'] .= translate_inline("`n`4You fall under a ban currently in place on this website:`n");
        while ($row = db_fetch_assoc($result)) {
            $session['message'] .= $row['banreason'] . "`n";
            if ($row['banexpire'] == '0000-00-00') {
                $session['message'] .= translate_inline("  `\$This ban is permanent!`0");
            } else {
                $session['message'] .= sprintf_translate("  `^This ban will be removed `\$after`^ %s.`0", date("M d, Y", strtotime($row['banexpire'])));
            }
            $sql = "UPDATE " . db_prefix("bans") . " SET lasthit='" . date("Y-m-d H:i:s") . "' WHERE ipfilter='{$row['ipfilter']}' AND uniqueid='{$row['uniqueidid']}'";
            db_query($sql);
            $session['message'] .= "`n";
        }
        $session['message'] .= translate_inline("`4If you wish, you may appeal your ban with the petition link.");
        tlschema();
        header("Location: index.php");
        exit;
    }
    db_free_result($result);
}
function innchat_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "innchatter":
            $id = $session['user']['acctid'];
            if (e_rand(1, 2) == 1) {
                $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE locked=0 AND acctid != '{$id}' ORDER BY rand(" . e_rand() . ") LIMIT 1";
            } else {
                $sql = "SELECT creaturename AS name FROM " . db_prefix("masters") . " WHERE 1 ORDER BY rand(" . e_rand() . ") LIMIT 1";
            }
            // Only let this hit the database once every 10 minute if we're
            // using data caching.  Otherwise it could be expensive.  If they
            // hit it multiple times within ten minutes, it'll use the same
            // random name of player or master.  We'll invalidate the name when someone's name changes
            // for any reason.
            $res = db_query_cached($sql, "innchat-names");
            $row = db_fetch_assoc($res);
            // Give 2 out of X (currently 7 (5+these 2)) chances of hearing about
            // a player.
            $noplayers = translate_inline("loneliness in town");
            if ($row['name'] == "") {
                $row['name'] = $noplayers;
            }
            $args[] = $row['name'];
            $args[] = $row['name'];
            $args[] = translate_inline("Frequently Asked Questions");
            $args[] = translate_inline("dwarf tossing");
            $args[] = translate_inline("YOU");
            $args[] = getsetting("villagename", LOCATION_FIELDS);
            $args[] = translate_inline("today's weather");
            $args[] = translate_inline("the elementary discord of being");
            // "Das elementare Zerwürfnis des Seins" no idea if that makes any sense in english. (Ok, it doesn't make sense in german too.) It's from a "Jägermeister" commercial spot :)
            break;
        case "namechange":
        case "dragonkill":
            // Someone just did a dragonkill or had their name changed.  Since it
            // it could have been this person, we'll just invalidate the cache
            invalidatedatacache("innchat-names");
            break;
    }
    return $args;
}
function nicecomments_dohook_private($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "commentary":
            $text = $args['commentline'];
            $his = translate_inline("his");
            $her = translate_inline("her");
            $o = $session['user']['sex'] ? $her : $his;
            if (get_module_setting("do_emotes")) {
                $full_emotes = array("hehe" => ":chuckles.", "haha" => ":laughs.", "lol" => ":laughs heartily!", "gtg" => ":needs to depart.", "bbiab" => ":will return momentarily.", "bbias" => ":will return momentarily.", "rot?fl" => ":plops right on the ground, laughing.", "lmao|rot?flmao" => ":laughs so hard, {$o} posterior falls off.", "wtf" => ":looks confused.");
                $partial_emotes = array("hehe" => "That's funny", "haha" => "That's funny", "bbl" => "I'll be back later.", "omg" => "Goodness!", "gtg" => "I need to leave.", "wtf" => "I'm confused", "omfg" => "Wow!", "atm" => "at the moment", "wb" => "Welcome back", "omgwtf|wtfomg" => "Oh my heavens!", "brb" => "I'll be right back.", "bbias" => "I'll be right back.", "bbiab" => "I'll be right back.", "yom" => "Ye Olde Mail", "motd" => "Message of the Day", "dk" => "Drive Kill", "dks" => "Drive Kills", "ty" => "thank you", "rng" => "random number generator", "lvl" => "level", "g2g" => "got to go");
                foreach ($full_emotes as $pattern => $replacement) {
                    $text = preg_replace("/^({$pattern})(one|eleven|[.!1])*\$/i", $replacement, $text);
                }
                foreach ($partial_emotes as $pattern => $replacement) {
                    $text = preg_replace("/\\b({$pattern})\\b/i", "{$replacement} ", $text);
                }
            }
            if (get_module_setting("do_aol")) {
                $partial_emotes = array("u" => "you", "r" => "are", "ur" => "you are", "ru" => "are you", "ne *1" => "any one", "ne" => "any", "(n[o0][o0]b|newb)" => "new player", "a\\/?s\\/?l" => "Tell me about yourself.", "(some?|sum) *(won|1)" => "someone", "(som|sum)" => "some", "wun" => "one");
                foreach ($partial_emotes as $pattern => $replacement) {
                    $text = preg_replace("/\\b({$pattern})\\b/i", "{$replacement} ", $text);
                }
            }
            if (get_module_setting("do_caps")) {
                //we don't force small caps on short text strings.
                if (strlen($text) > 5) {
                    //test to see if there are too many caps:
                    $allletters = preg_replace("/[^a-zA-Z]/", "", $text);
                    $allcaps = preg_replace("/[a-z]/", "", $allletters);
                    if (strlen($allcaps) >= strlen($allletters) / 2) {
                        //too many caps.
                        $text = preg_replace("/\\b([a-zA-Z0-9])([a-zA-Z0-9]*)\\b/e", "'\\1'.strtolower('\\2')", $text);
                    }
                }
            }
            $args['commentline'] = $text;
            break;
    }
    return $args;
}
function friendlist_faq()
{
    $c = translate_inline("Return to the Contents");
    output_notl("`#<strong><center><a href='petition.php?op=faq'>{$c}</a></center></strong>`0", true);
    addnav("", "petition.php?op=faq");
    rawoutput("<hr>");
    output("`c`&`bQuestions about Friend Lists`b`c`n");
    output("`^1. Where is it?`n");
    output("`@Just click the link at the top of the mail page.`n`n");
    output("`^2. What is it for?`n");
    output("`@You can send requests to add someone to both of your lists.`nIf the other user accepts, you will be able to see their status, location, and whether or not they are logged in.`n`n");
    output("`^3. Anything else?`n");
    output("`@You can ignore players that harass you, to prevent them from sending you mail.`nYou can ignore Admin, however their mails will still come through.`n`n");
    if (get_module_setting('allowStat')) {
        output("`^4. Sure that's it?`n");
        output("`@Oh, I forgot!;) You can turn on a preference to see how many of your friends are online.");
    }
    rawoutput("<hr>");
    output_notl("`#<strong><center><a href='petition.php?op=faq'>{$c}</a></center></strong>`0", true);
}
function lovers_dohook($hookname, $args)
{
    global $session;
    $partner = get_partner();
    switch ($hookname) {
        case "newday":
            set_module_pref("seenlover", 0);
            if ($session['user']['marriedto'] == 4294967295.0) {
                $dk = $session['user']['dragonkills'];
                // 0.7 seemed to be a perfect balance of no loss of charm.
                // 1.0 was too much.
                $dk = max(1, round(0.85 * sqrt($dk), 0));
                $charmloss = e_rand(1, $dk);
                $session['user']['charm'] -= $charmloss;
                output("`n`%You're  married,  so there's no reason to keep up that perfect image, and you let yourself go a little today ( You lose `\$%s charmpoint(s)`%).`n", $charmloss);
                if ($session['user']['charm'] <= 0) {
                    output("`bWhen  you  wake  up, you find a note next to you, reading`n`5Dear %s`5,`n", $session['user']['name']);
                    output("Despite  many  great  kisses, I find that I'm simply no longer attracted to you the way I used to be.`n`n");
                    output("Call  me fickle, call me flakey, but I need to move on.");
                    output("There are other warriors in the land, and I think some of them are really hot.");
                    output("So it's not you, it's me, etcetera etcetera.`n`n");
                    output("No hard feelings, Love,`n%s`b`n", $partner);
                    addnews("`\$%s`\$ has left %s`\$ to pursue \"other interests.\"`0", $partner, $session['user']['name']);
                    $session['user']['marriedto'] = 0;
                    $session['user']['charm'] = 0;
                }
            }
            break;
        case "inn":
            addnav("Things to do");
            if ($session['user']['sex'] == SEX_MALE) {
                addnav(array("F?Flirt with %s", $partner), "runmodule.php?module=lovers&op=flirt");
                addnav(array("Chat with %s", translate_inline(getsetting("bard", "`^Seth"))), "runmodule.php?module=lovers&op=chat");
            } else {
                addnav(array("F?Flirt with %s", $partner), "runmodule.php?module=lovers&op=flirt");
                addnav(array("Gossip with %s", translate_inline(getsetting("barmaid", "`%Violet"))), "runmodule.php?module=lovers&op=chat");
            }
            break;
    }
    return $args;
}
function dwcastles_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "dwellings-list-type":
            addnav("Show Only Types");
            addnav(array("%s", ucfirst(translate_inline(get_module_setting("dwnameplural", "dwcastles")))), "runmodule.php?module=dwellings&op=list&showonly=dwcastles&ref={$args['ref']}&sortby={$args['sortby']}&order={$args['order']}");
            break;
        case "dwellings":
            if (get_module_objpref("city", $args['cityid'], "showdwcastles")) {
                output("  High on the far hills, you see waving flags of the glorious %s`0 of the rich and fabulous.", translate_inline(get_module_setting("dwnameplural")));
                if ($args['allowbuy'] == 1 && $session['user']['dragonkills'] >= get_module_setting("dkreq")) {
                    $cityid = $args['cityid'];
                    addnav("Options");
                    addnav(array("Establish a %s", ucfirst(translate_inline(get_module_setting("dwname", "dwcastles")))), "runmodule.php?module=dwellings&op=buy&type=dwcastles&subop=presetup&cityid={$cityid}");
                }
            }
            break;
    }
    return $args;
}
function friendlist_deny()
{
    global $session;
    $ignored = rexplode(get_module_pref('ignored'));
    $friends = rexplode(get_module_pref('friends'));
    $request = rexplode(get_module_pref('request'));
    $ac = httpget('ac');
    $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid={$ac} AND locked=0";
    $result = db_query($sql);
    if (in_array($ac, $friends)) {
        $info = translate_inline("That user has been removed.");
        require_once "lib/systemmail.php";
        $t = "`\$Friend List Removal";
        $mailmessage = array("%s`0`@ has deleted you from %s Friend List.", $session['user']['name'], $session['user']['sex'] ? translate_inline("her") : translate_inline("his"));
        $friends = array_diff($friends, array($ac));
        $friends = rimplode($friends);
        set_module_pref('friends', $friends);
        $act = $session['user']['acctid'];
        $friends = rexplode(get_module_pref('friends', 'friendlist', $ac));
        $friends = array_diff($friends, array($act));
        $friends = rimplode($friends);
        set_module_pref('friends', $friends, 'friendlist', $ac);
        invalidatedatacache("friendliststat-" . $session['user']['acctid']);
        invalidatedatacache("friendliststat-" . $ac);
    } else {
        $info = translate_inline("That user has been denied.");
        require_once "lib/systemmail.php";
        $t = "`\$Friend Request Denied";
        $mailmessage = array("%s`0`@ has denied you your Friend Request.", $session['user']['name']);
        $request = array_diff($request, array($ac));
        $request = rimplode($request);
        set_module_pref('request', $request);
    }
    if (db_num_rows($result) > 0) {
        systemmail($ac, $t, $mailmessage);
        $row = db_fetch_assoc($result);
        $info = sprintf_translate("%s has been removed", $row['name']);
    }
    output_notl($info);
}
function friendlist_ignore()
{
    global $session;
    $iveignored = rexplode(get_module_pref('iveignored'));
    $friends = rexplode(get_module_pref('friends'));
    $request = rexplode(get_module_pref('request'));
    $ac = httpget('ac');
    $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid={$ac} AND locked=0";
    $result = db_query($sql);
    if (db_num_rows($result) > 0 && in_array($ac, $friends)) {
        $row = db_fetch_assoc($result);
        require_once "lib/systemmail.php";
        $t = "`\$Friend List Ignore";
        $mailmessage = array("%s`0`@ has added you to %s ignore list.", $session['user']['name'], $session['user']['sex'] ? translate_inline("her") : translate_inline("his"));
        systemmail($ac, $t, $mailmessage);
        $friends = array_diff($friends, array($ac));
        invalidatedatacache("friendliststat-" . $session['user']['acctid']);
        invalidatedatacache("friendliststat-" . $ac);
    }
    $friends = rimplode($friends);
    set_module_pref('friends', $friends);
    $ignored = rexplode(get_module_pref('ignored', 'friendlist', $ac));
    $ignored[] = $session['user']['acctid'];
    $ignored = rimplode($ignored);
    set_module_pref('ignored', $ignored, 'friendlist', $ac);
    $act = $session['user']['acctid'];
    $friends = rexplode(get_module_pref('friends', 'friendlist', $ac));
    $friends = array_diff($friends, array($act));
    $friends = rimplode($friends);
    set_module_pref('friends', $friends, 'friendlist', $ac);
    if (in_array($ac, $request)) {
        $request = array_diff($request, array($ac));
        $request = rimplode($request);
        set_module_pref('request', $request);
    }
    $iveignored[] = $ac;
    $iveignored = rimplode($iveignored);
    set_module_pref('iveignored', $iveignored);
    output("You have ignored that user, they can no longer YoM you");
}
function redirect($location, $reason = false)
{
    global $session, $REQUEST_URI;
    // This function is deliberately not localized.  It is meant as error
    // handling.
    if (strpos($location, "badnav.php") === false) {
        //deliberately html in translations so admins can personalize this, also in once scheme
        $session['allowednavs'] = array();
        addnav("", $location);
        $session['output'] = "<a href=\"" . HTMLEntities($location, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "\">" . translate_inline("Click here.", "badnav") . "</a>";
        $session['output'] .= translate_inline("<br><br>If you cannot leave this page, notify the staff via <a href='petition.php'>petition</a> and tell them where this happened and what you did. Thanks.", "badnav");
    }
    restore_buff_fields();
    $session['debug'] .= "Redirected to {$location} from {$REQUEST_URI}.  {$reason}<br>";
    saveuser();
    @header("Location: {$location}");
    //echo "<html><head><meta http-equiv='refresh' content='0;url=$location'></head></html>";
    //echo "<a href='$location'>$location</a><br><br>";
    //echo $location;
    //echo $session['debug'];
    exit;
}