My first thought is that visit_url() should not be used. The charpane loads way too often to be checking something that won't usually change.
My first thought is that visit_url() should not be used. The charpane loads way too often to be checking something that won't usually change.
You can use have_outfit on a list of outfits to see which ones you have I guess. I think that works with custom outfits as well.
What browser are you using?
chit.character.avatar true
chit.character.title true
chit.checkversion true
chit.disable false
chit.effects.classicons none
chit.effects.layout songs,buffs,intrinsics
chit.effects.showicons true
chit.effects.usermap false
chit.familiar.hats spangly sombrero,sugar chapeau
chit.familiar.pants spangly mariachi pants,double-ice britches,BRICKO pants,pin-stripe slacks,Studded leather boxer shorts,Monster pants,Sugar shorts
chit.familiar.protect false
chit.familiar.weapons time sword
chit.floor.layout update
chit.helpers.dancecard true
chit.helpers.semirare true
chit.helpers.wormwood stats,spleen
chit.kol.coolimages false
chit.quests.hide false
chit.roof.layout character,stats,familiar
chit.stats.layout muscle,myst,moxie|hp,mp,axel|liver,stomach,spleen|mcd|trail
chit.stats.showbars true
chit.toolbar.layout trail,quests,elements
chit.toolbar.moods true
chit.walls.layout helpers,effects,modifiers
/*
Brick for ChIT to display outfit selection screen.
Created by Infinius on Kol (InfiniusDev on KolMafia.us forums)
Tested against Chez' ChIT (Character Info Toolbox) 0.7.3.4
Recommended installation steps:
0. Make sure ChIT is installed in mafia (run it once to be sure)
1. Make a folder called ChitBricks in mafia's script folder.
2. Make a subfolder beneath that called ChitBrickOutfits
3. Put these files in that subfolder:
* ChitBrick.Outfits.Shared.ash
* ChitBrick.Outfits.Caching.ash
* ChitBrick.Outfits.Plugin.ash
4. Ensure the following code is changed in charpane.ash:
requires changes to bakeBricks() as per
http://kolmafia.us/showthread.php?7594-Character-Info-Toolbox&p=82353&viewfull=1#post82353
Bale stated support in next version.
(see bakeBricksChanges.txt)
5. Add the import for this brick to charpane.ash in the relay folder
* import <ChitBrick.Outfits.Plugin.ash>
6. Change the line for wall layout in "vars_yourcharactername.txt" in the data folder
* e.g. chit.walls.layout helpers,effects,pluginOutfits
7. re-load the relay browser
Description:
A brick for the wall of ChIT which allows you to quickly change into a
standard or custom outfit from lists ("s" and "c", respectively) in the
character pane.
Acknowledgements:
* Thanks to Chez & Bale for creating such a visually appealing, easy to
modify script.
* Thanks to Soluzar for the nudge to take a peek at ChIT in the first place.
* Thanks to PeKaJe for the incessant scripting questions in Old CW's chat forum.
How it works:
The rendering only works when a user is not in battle. A request is made
to the inventory page for the two outfit lists, and scraped for the
outfits.
If the user is in battle (or somewhere else they can't get those lists),
they recieve a message instead of the select lists.
When the user selects an outfit, a raw ajax GET is made to the inventory
page, with the outfit id. This is how the vanilla interface changes
outfits. The problem with this is that because the selection is done
client-side, there's no way to know/keep track of what the current
outfit is (unless possibly by modifying the inventory page as well?
This may be out of scope for this plugin.).
There's not currently a way to identify that the outfit has changed,
aside from possibly appending a querystring to the charpane url to
indicate this. I'm not sure how often that pane is refreshed in other
ways though, which may blow away the current selection.
Known issues:
Note that manually refreshing the charpane tends to wipe away the
querystring, meaning that the drop list will lose its selection.
using visit_url in GetInventoryPage() for some reason prevents 2-page
skills (e.g. lure minions) from working. Don't know why this is, but
caching was introduced to alleviate this; when the charpane uses the
cache, the skills work. While it's loading the skills won't; the
charpane should autorefresh when using the 'during-caching' part, which
should allow the skills to always work now.
Now driven by config files where:
standard outfits also defined in code here; this may not yet
be a complete list of outfits.
*/
script "ChIT Brick Outfit Selector";
notify "Infinius";
import <ChitBrick.Outfits.Shared.ash>
import <ChitBrick.Outfits.Caching.ash>
string chitBrickOutfitsVersion = "0.0.1.8";
/////////////////////////////////////////////////GLOBALS
OutfitList standardOutfitMap;
OutfitList customOutfitMap;
boolean doForceCharPaneRefresh = false;
/////////////////////////////////////////////////CONSTANTS
debug=false; //defined in shared
/*
defaultCacheRefreshMS = 60000 is 60 seconds;
how often to update custom outfits; if the charpane is refreshed
prior to this, it will use the disk-cached custom outfits.
*/
int defaultCacheRefreshMS = 60000;
//communicate the selected outfit AFTER applying it...
string OUTFIT_QUERY_PARAMETER="outfitId";
//The idea behind this was to store the most recently equipped outfit.
// TODO: explore feasibility of this.
//FUTURE: boolean AllowCachedCurrentOutfit = true;
string OutfitBrickConfigurationFile = "CustomOutfitBrickConfiguration.txt";
string CachedMapFile = "CustomOutfitCache.txt";
int [ string ] brickConfigurationMap;
//brickConfigurationMap["LastCustomOutfitRetrievedGameDay"];
//brickConfigurationMap["LastCustomOutfitRetrievedGameTime"];
/////////////////////////////////////////////////METHODS TO GET OUTFITS
void InitializeBrickConfiguration() {
debug("initializing configuration");
if (!file_to_map(OutfitBrickConfigurationFile, brickConfigurationMap)){
//we don't have config settings; initialize with force-refresh:
debug("has never been initialized.");
brickConfigurationMap["LastCustomOutfitRetrievedGameDay"] = -1;
brickConfigurationMap["LastCustomOutfitRetrievedGameTime"] = 0 - defaultCacheRefreshMS;
} else {
debug("loaded configuration from cache."); }
}
void RefreshBrickConfiguration(){
debug("saving last poll time.");
brickConfigurationMap["LastCustomOutfitRetrievedGameDay"] = gameday_to_int();
brickConfigurationMap["LastCustomOutfitRetrievedGameTime"] = gametime_to_int();
map_to_file(brickConfigurationMap, OutfitBrickConfigurationFile);
debug("refreshed configuration map");
}
boolean ShouldRefreshCache(){
boolean shouldRefresh = false;
int currentDay = gameday_to_int();
int currentTime = gametime_to_int();
int lastUpdatedDay = brickConfigurationMap["LastCustomOutfitRetrievedGameDay"];
int lastUpdatedTime = brickConfigurationMap["LastCustomOutfitRetrievedGameTime"];
debug("checking if should refresh.");
debug("current day, time: "+currentDay+" ; "+currentTime);
debug("lastUpdated day, time: "+lastUpdatedDay+" ; "+lastUpdatedTime);
if (lastUpdatedDay != currentDay || (currentTime - lastUpdatedTime) > defaultCacheRefreshMS){
debug("should be updated");
shouldRefresh = true;
} else {
debug("should not be updated");
}
return shouldRefresh;
}
boolean InitializeCustomOutfitList(){
OutfitList outfits;
outfits.ListType = "Custom";
outfits.OutfitCount = 0;
boolean canLoad = true;
Outfit [ int ] cachedOutfits;
if (!file_to_map(CachedMapFile, cachedOutfits)) {
debug("no custom outfit cache found; loading");
boolean canLoad = DoCacheCustomOutfits();
if (!canLoad){
print("Cannot load initial outfit list at this time.", "red");
}
file_to_map(CachedMapFile, cachedOutfits);
} else {
debug("custom outfit cache found");
//invalidate the cache here; it'll go stale eventually.
if (ShouldRefreshCache()){
debug("cache is stale; try to refresh.");
/*note; should also force charpane to rerender so
skills aren't broken. */
canLoad = DoCacheCustomOutfits();
debug("can load:"+canLoad);
if (canLoad){
RefreshBrickConfiguration();
doForceCharPaneRefresh = true;
} else {
//during battle you cannot go to the inventory page.
print("Cannot update cache at this time.", "blue");
}
}
debug("found and loaded cached outfits.");
}
debug("completed trying to get custom outfits");
//outfits = AddOutfitTo(outfits, "(select a custom outfit)", 0); no need; already in list.
for i from 1 to count(cachedOutfits) by 1 {
outfits = AddOutfitTo(outfits, cachedOutfits[i].Name, cachedOutfits[i].OutfitId);
}
customOutfitMap = outfits;
return canLoad;
}
boolean InitializeStandardOutfitList(){
OutfitList outfits;
outfits.ListType = "Standard";
outfits.OutfitCount = 0;
outfits = AddOutfitTo(outfits, "(select a standard outfit)", 0);
//outfits = AddOutfitIfExistsTo(outfits, "Outfit Name", integerOfOutfitOnEquipmentPage);
outfits = AddOutfitIfExistsTo(outfits,"Antique Arms And Armor",29);
outfits = AddOutfitIfExistsTo(outfits,"Black Armaments",35);
outfits = AddOutfitIfExistsTo(outfits,"Bugbear Costume",1 );
outfits = AddOutfitIfExistsTo(outfits,"Cold Comforts",80);
outfits = AddOutfitIfExistsTo(outfits,"eXtreme Cold-Weather Gear",7 );
outfits = AddOutfitIfExistsTo(outfits,"Filthy Hippy Disguise",2 );
outfits = AddOutfitIfExistsTo(outfits,"Frat Boy Ensemble",3 );
outfits = AddOutfitIfExistsTo(outfits,"Frat Warrior Fatigues",33);
outfits = AddOutfitIfExistsTo(outfits,"Glad Bag Glad Rags",28);
outfits = AddOutfitIfExistsTo(outfits,"Hot and Cold Running Ninja Suit",6 );
outfits = AddOutfitIfExistsTo(outfits,"Hot Daub Ensemble",86);
outfits = AddOutfitIfExistsTo(outfits,"Knob Goblin Elite Guard Uniform",5 );
outfits = AddOutfitIfExistsTo(outfits,"Knob Goblin Harem Girl Disguise",4 );
outfits = AddOutfitIfExistsTo(outfits,"Mining Gear",8 );
outfits = AddOutfitIfExistsTo(outfits,"Swashbuckling Getup",9 );
outfits = AddOutfitIfExistsTo(outfits,"War Hippy Fatigues",32);
outfits = AddOutfitIfExistsTo(outfits,"Wax Wardrobe",85);
outfits = AddOutfitIfExistsTo(outfits,"Yendorian Finery",16);
standardOutfitMap = outfits;
return true;
}
boolean GetOutfitLists(){
boolean isSuccessful = true;
isSuccessful = InitializeCustomOutfitList();
isSuccessful = isSuccessful && InitializeStandardOutfitList();
return isSuccessful;
}
/////////////////////////////////////////////////List Rendering
void RenderOutfit(buffer result, Outfit outfitMap){
result.append("<option value="+outfitMap.OutfitId+">");
result.append(outfitMap.Name);
result.append("</option>");
}
void RenderOutfitList(buffer result, OutfitList outfitListMap){
//onChange='onOutfitSelected();'
string selectId=outfitListMap.ListType+"OutfitSelector";
result.append("<select id='"+selectId+"' style='width:100%;' onchange=\"onOutfitSelected(this, '"+selectId+"')\">");
if (outfitListMap.OutfitCount > 0){
for i from 1 to outfitListMap.OutfitCount by 1 {
RenderOutfit(result, outfitListMap.Outfits[i]);
}
}
result.append('</select>');
}
/////////////////////////////////////////////////////////SERVER COMMUNICATION:
void RenderJavascriptSelectionHandlers(buffer result){
result.append("<script type='text/javascript'>\n");
AddHttpGetHelperTo(result);
result.append("function onOutfitSelected(list, listId){ \n");
//don't know why the next line doesn't work (at least in firefox... need to check
// this out either in isolation, or with FireBug.
//List is fine, list.options is fine, and even list.selectedIndex is fine, but
// the iterator for options given selected index seems to fail.
//result.append(" var chosenOption = list.options[list.selectedIndex].value; \n");
//HACK: use getElementById instead; passed in listId as well.
//result.append(" alert(document.getElementById(listId).value); \n");
//would it be really bad here to import/use jquery?
// do I have to worry about cross-site scripting issues if loading it directly from google?
result.append(" var outfitId = document.getElementById(listId).value; "+NEWLINE);
//Figure out out to post an equipment change with a given index. Sample packet from Fiddler2:
//
// GET http://127.0.0.1:60080/inv_equip.php?action=outfit&which=2&whichoutfit=-20 HTTP/1.1
// Host: 127.0.0.1:60080
// User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
// Accept-Language: en-US,en;q=0.5
// Accept-Encoding: gzip, deflate
// Connection: keep-alive
// Referer: http://127.0.0.1:60080/inventory.php?which=2
// Cookie: charpwd=[redacted 3-digit int]; chatpwd=[redacted 3-digit int]
result.append(" var url = 'inv_equip.php?action=outfit&which=2&whichoutfit='+outfitId; "+NEWLINE);
result.append(" var resultHtml = httpGet(url); "+NEWLINE);
//Tell the next load of the character pane which outfit id to select.
//TODO: grab the outfitid from the url, and replace any existing value.
// bug: if another brick tries to do this as is, the line below
// would wipe out their querystring!
result.append(" window.location = 'charpane.php?"+OUTFIT_QUERY_PARAMETER+"='+outfitId; "+NEWLINE);
//TODO: parse last outfit set & save it in a file for easy refreshing to current outfit.
// problems with this? What if they used the vanilla interface?
result.append(" } \n");
result.append("</script>");
}
void RenderApplyCurrentSelectedOutfit(buffer result){
result.append("<script type='text/javascript'> " +NEWLINE);
//getParameterByName TAKEN FROM UserId 999 at:
//http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values
result.append("function getParameterByName(name) " +NEWLINE);
result.append("{ "+NEWLINE);
result.append(" var match = RegExp('[?&]' + name + '=([^&]*)') " +NEWLINE);
result.append(" .exec(window.location.search); " +NEWLINE);
result.append(" return match && decodeURIComponent(match[1].replace(/\\+/g, ' ')); " +NEWLINE);
result.append("} " +NEWLINE);
result.append("function selectByOptionValue(aList, anOptionValue) "+NEWLINE);
result.append("{ "+NEWLINE);
result.append(" console.log('looking for:'+anOptionValue); "+NEWLINE);
result.append(" for (var curOption = 0; curOption< aList.options.length; curOption++) "+NEWLINE);
result.append(" { "+NEWLINE);
result.append(" console.log(aList.options[curOption]); "+NEWLINE);
result.append(" if (aList.options[curOption].value === anOptionValue) "+NEWLINE);
result.append(" { "+NEWLINE);
result.append(" console.log('value found:'+anOptionValue); "+NEWLINE);
result.append(" aList.options[curOption].selected = true; "+NEWLINE);
result.append(" break; "+NEWLINE);
result.append(" } "+NEWLINE);
result.append(" } "+NEWLINE);
result.append("} "+NEWLINE);
result.append("function selectOutfit(outfitId) "+NEWLINE);
result.append("{ "+NEWLINE);
result.append(" if (outfitId) "+NEWLINE); //null if none previously selected.
result.append(" { "+NEWLINE);
result.append(" var listS = document.getElementById('StandardOutfitSelector'); "+NEWLINE);
result.append(" var listC = document.getElementById('CustomOutfitSelector'); "+NEWLINE);
result.append(" selectByOptionValue(listS,outfitId); "+NEWLINE);
result.append(" selectByOptionValue(listC,outfitId); "+NEWLINE);
result.append(" } "+NEWLINE);
result.append("} "+NEWLINE);
result.append("function getCurrentSelectedOutfit() "+NEWLINE);
result.append("{ "+NEWLINE);
result.append(" var whichOutfit = getParameterByName('"+OUTFIT_QUERY_PARAMETER+"'); "+NEWLINE);
result.append(" return whichOutfit; "+NEWLINE);
result.append("} "+NEWLINE);
//execute the selection.
result.append("selectOutfit(getCurrentSelectedOutfit()); "+NEWLINE);
result.append("</script>");
}
void RenderInstructionToImmediatelyRefresh(buffer result) {
result.append("<script type='text/javascript'> " +NEWLINE);
result.append(" window.location.reload(); "+NEWLINE);
result.append("</script>");
}
/////////////////////////////////////////////////Constructor Method:
buffer pluginoutfits() {
buffer result; //return value
InitializeBrickConfiguration(); //needed to poll if we've scraped custom outfits recently.
boolean hasOutfitsNow = GetOutfitLists(); //false if in battle, for example.
RenderJavascriptSelectionHandlers(result);
result.append("<table id='chit_outfits' class='chit_brick nospace'>");
result.append("<tr><th colspan='2'>Outfits ("+chitBrickOutfitsVersion+")</th></tr>");
if (hasOutfitsNow && doForceCharPaneRefresh){
debug("need to refresh pane so skills are not broken");
RenderInstructionToImmediatelyRefresh(result);
} else if (!hasOutfitsNow){
debug("during battle; cannot display outfits");
result.append("<tr><td colspan='2'>Outfits cannot be changed now.</td></tr>");
}
else {
debug("standard rendering");
result.append("<tr><td width='5%'>S</td><td width='95%'>");
RenderOutfitList(result, standardOutfitMap);
result.append("</td></tr>");
result.append("<tr><td width='5%'>C</td><td width='95%'>");
RenderOutfitList(result, customOutfitMap);
result.append("</td></tr>");
//ApplyCurrentSelectedOutfit(GetCurrentSelectedOutfit()); //not implemented server-side.
RenderApplyCurrentSelectedOutfit(result);
}
result.append("</table>");
return result;
}
print("Imported Brick Plugin: Infinius' Chit Brick Outfits (pluginOutfits)");
/*
Script to house data types & methods shared across scripts
*/
/////////////////////////////////////////////////CONSTANTS
//used for writing javascript
string NEWLINE = "\n";
/////////////////////////////////////////////////DATA TYPES
record Outfit {
string Name;
string OutfitId;
};
record OutfitList {
int Index; //0 or 1
string ListType; //Standard or Custom
Outfit [ int ] Outfits;
int OutfitCount;
};
Outfit OutfitFactory(string name, string outfitId){
Outfit anOutfit;
anOutfit.Name = name;
anOutfit.OutfitId = outfitId;
return anOutfit;
}
/////////////////////////////////////////////////HELPERS
boolean debug;
void debug(string s)
{
if (debug) { print(s, "blue"); }
}
/////////////////////////////////////////////////DATA TYPE METHODS
OutfitList AddOutfitTo(OutfitList aList, string name, string outfitId){
Outfit anOutfit = OutfitFactory(name, outfitId);
aList.OutfitCount = aList.OutfitCount + 1;
aList.Outfits[aList.OutfitCount] = anOutfit;
return aList;
}
OutfitList AddOutfitIfExistsTo(OutfitList aList, string name, string outfitId){
if (have_outfit(name)){
aList = AddOutfitTo(aList, name, outfitId);
} else {
print("You do not have outfit: "+name, "red");
}
return aList;
}
//////////////////////////////////STANDARD JAVASCRIPT HELPER METHODS
void AddHttpGetHelperTo(buffer result){
//function below taken from: http://stackoverflow.com/questions/247483/http-get-request-in-javascript
// stack overflow username: Pistos
result.append(NEWLINE);
result.append("function httpGet(theUrl) "+NEWLINE);
result.append("{ "+NEWLINE);
result.append(" var xmlHttp = null; "+NEWLINE);
result.append(" "+NEWLINE);
result.append(" xmlHttp = new XMLHttpRequest(); "+NEWLINE);
result.append(" xmlHttp.open( 'GET', theUrl, false ); "+NEWLINE);
result.append(" xmlHttp.send( null ); "+NEWLINE);
result.append(" return xmlHttp.responseText; "+NEWLINE);
result.append("} "+NEWLINE);
}
/*
Script to cache custom outfits from inventory page
The reason for doing this is that there is a bug in KOL where
the skills page can break if visit_url is made to any of the
relay browser's pages.
The only way to get custom outfits is to scrape the inventory
page. The ID's change every time a custom outfit is re-saved
which would make modifying the script tedious, if they
were hard-coded. This script file handles the work of the
scraping and saving to a map file (the "cache" of
custom outfits on disk).
*/
/////////////////////////////////////////////////CLASS:
record OutfitsCacheCustom {
OutfitList StandardOutfitMap;
OutfitList CustomOutfitMap;
string CustomOutfitListCache;
};
OutfitsCacheCustom this; //sort of support for 'this'.
this.CustomOutfitListCache = "CustomOutfitCache.txt";
/////////////////////////////////////////////////METHODS TO GET OUTFITS
string GetInventoryPage(){
int EQUIPMENT_PAGE_INDEX = 2;
//NOTE: this will break the skills page from working for certian skills.
string result = visit_url("inventory.php?which="+EQUIPMENT_PAGE_INDEX);
return result;
}
OutfitList ParseCustomOutfitsFrom(string optionsHtml){
//<option value=0>(select an outfit)</option>
//debug(optionsHtml); //see the html that's being scraped.
matcher outfitMatcher = create_matcher("option value\=(.*?)>(.*?)</option>",optionsHtml);
OutfitList parsedList;
parsedList.ListType = "Custom";
int currentOutfitCount = 0;
while (outfitMatcher.find()){
currentOutfitCount = currentOutfitCount + 1;
Outfit currentOutfit = OutfitFactory(outfitMatcher.group(2), outfitMatcher.group(1));
parsedList.Outfits[currentOutfitCount] = currentOutfit;
debug("added "+outfitMatcher.group(2));
}
parsedList.OutfitCount = currentOutfitCount;
debug("total count:"+parsedList.OutfitCount);
return parsedList;
}
boolean GetOutfitListsFromPage(){
boolean isSuccessful = true;
/* From the relay browser, this is what custom outfits look like; this matches
source running through relay, and viewing frame source.
<form name=outfit2 action=inv_equip.php><input type=hidden name=action value="outfit"><input type=hidden name=which value=2><b>Custom:</b> </td><td><select style="width: 250px" name=whichoutfit><option value=0>(select a custom outfit)</option><option value=-457>Backup</option><option value=-495>Best Fighter</option><option value=-20>Item Drop</option><option value=-503>OldOutfit</option><option value=-497>Scaling</option></select></td><td> <input class=button type=submit value="Dress Up!"><br></form
*/
string inventoryPageHtml = GetInventoryPage(); //THIS PREVENTS 2-page skills!!
matcher outfitSelectMatcher = create_matcher("name=outfit2 action=inv_equip.php(.*?)</select>", inventoryPageHtml);
if (outfitSelectMatcher.find()){
this.CustomOutfitMap = ParseCustomOutfitsFrom(outfitSelectMatcher.group(1));
}
if (this.CustomOutfitMap.OutfitCount == 0) {
debug("no outfits at this time.");
isSuccessful = false;
}
return isSuccessful;
}
/////////////////////////////////////////////////Constructor Method:
boolean DoCacheCustomOutfits() {
boolean isSuccessful = false;
boolean hasOutfitsNow = GetOutfitListsFromPage(); //false if in battle, for example.
if (hasOutfitsNow) {
debug("saving custom outfits to disk");
debug("count of custom outfits:"+this.CustomOutfitMap.OutfitCount);
map_to_file(this.CustomOutfitMap.Outfits, this.CustomOutfitListCache, true); //save list to disk, in compact mode.
isSuccessful = true;
} else {
debug("unable to find custom outifts");
}
debug("completed caching custom outfits");
return isSuccessful;
}
//TESTING THIS BY RUNNING THE SCRIPT BY ITSELF RESULTS IN DIFFERENT HTML!
// (VANILLA VS. RELAY HTML)
//DoCacheCustomOutfits(); //entry point for this script;
/*
BELOW IS THE CHANGED bakeBricks function as per:
http://kolmafia.us/showthread.php?7594-Character-Info-Toolbox&p=82353&viewfull=1#post82353
*/
void bakeBricks() {
bakeHeader();
bakeFooter();
if (inValhalla) {
bakeValhalla();
} else {
foreach layout in $strings[roof, walls, floor, toolbar] {
string prefname = "chit." + layout + ".layout";
layout = vars[prefname].to_lower_case().replace_string(" ", "");
string [int] bricks = split_string(layout,",");
string brick;
for i from 0 to (bricks.count()-1) {
brick = bricks[i];
if (!(chitBricks contains brick)) {
switch (brick) {
//if they were cased the same as the method, we could just rely on
//purely dynamic calls.
case "character": bakeCharacter(); break;
case "stats": bakeStats(); break;
case "familiar": bakeFamiliar(); break;
case "trail": bakeTrail(); break;
case "quests": bakeQuests(); break;
case "effects": bakeEffects(); break;
case "mcd": bakeMCD(); break;
case "substats": bakeSubstats(); break;
case "organs": bakeOrgans(); break;
case "modifiers": bakeModifiers(); break;
case "elements": bakeElements(); break;
//we really don't know about the brick; try to dynamically load it.
//note: casing MUST match between brickname and bakebrickname function.
default:
if (index_of(brick,"plugin")==0) {
chitBricks[brick] = call buffer brick(); //e.g. pluginoutfits();
}
break;
}
}
}
}
}
bakeToolBar();
}
For some reason, I can't click on my HP/MP bars for autorecovery. "Add HP/MP restore links to the left side pane" is checked in mafia's preferences, but I can't find a CHiT var that might enable this feature.
If it was "unintentional" does that mean it should be fixed in the new builds?That was an unintentional mafia change to make the link have "restore+HP" instead of "restore+hp", and the same for MP.
So I am sad to say that your last fix to CHIT did not fix the extreme meter for Skyelf. Here is her latest html for the frame. Hope it helps.
Is it too late for her to try the attached build? 'Cause I've changed a lot of parsing since my last release. Though I find her continuing problem completely baffling. Do you have a clue why her charpane is somehow different from everyone's else? I cannot even find a valid difference to explain the failure.
If anyone can look over the problem I would be very happy if they could explain why it doesn't work for Skyelf.
So this version was much closer. There is a space where the extreme meter should be, but then there is a broken image. Here is a screenshot so you can see.
For some reason, only the effects are showing up for me - see screenshot. I've got the latest script, latest mafia daily and the latest zlib. Help?
http://i.imgur.com/qEYt7.jpg
<html><head>
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<link rel="stylesheet" type="text/css" href="http://images.kingdomofloathing.com/styles.css">
<style type="text/css">
#nudges div { position: relative; padding: 0px; }
#nudges div .close { position: absolute; top: -2px; right: -10px; border: 1px solid black; }
</style>
<script language="Javascript" src="/basics.js"></script><link rel="stylesheet" href="/basics.css" />
<link rel="stylesheet" href="chit.css">
</head>
<script src="/images/scripts/window.js"></script>
<script type="text/javascript" src="/images/scripts/jquery-1.3.1.min.js"></script>
<script language=Javascript src="/images/scripts/keybinds.min.2.js"></script>
<script language=Javascript src="/images/scripts/window.20111231.js"></script>
<script language="javascript">function chatFocus(){if(top.chatpane.document.chatform.graf) top.chatpane.document.chatform.graf.focus();}
if (typeof defaultBind != 'undefined') { defaultBind(47, 2, chatFocus); defaultBind(190, 2, chatFocus);defaultBind(191, 2, chatFocus); defaultBind(47, 8, chatFocus);defaultBind(190, 8, chatFocus); defaultBind(191, 8, chatFocus); }</script><script language=Javascript src="/images/scripts/jquery-1.3.1.min.js"></script>
<script type="text/javascript">
var todo = [];
function nextAction() {
var next_todo = todo.shift();
if (next_todo) {
eval(next_todo);
}
}
function dojax(dourl, afterFunc, hoverCaller, failureFunc) {
$.ajax({
type: 'GET', url: dourl, cache: false,
global: false,
success: function (out) {
nextAction();
if (out.match(/no\|/)) {
var parts = out.split(/\|/);
if (failureFunc) failureFunc(parts[1]);
else $('#ChatWindow').append('<font color="green">Oops! Sorry, Dave, you appear to be ' + parts[1] + '.</font><br />' + "\n");
return;
}
if (hoverCaller) {
float_results(hoverCaller, out);
if (afterFunc) { afterFunc(); }
return;
} var $eff = $(top.mainpane.document).find('#effdiv');
if ($eff.length == 0) {
var d = top.mainpane.document.createElement('DIV');
d.id = 'effdiv';
var b = top.mainpane.document.body;
if ($('#content_').length > 0) {
b = $('#content_ div:first')[0];
}
b.insertBefore(d, b.firstChild);
$eff = $(d);
}
$eff.find('a[name="effdivtop"]').remove().end()
.prepend('<a name="effdivtop"></a><center>' + out + '</center>').css('display','block');
if (!window.dontscroll || (window.dontscroll && dontscroll==0)) {
top.mainpane.document.location = top.mainpane.document.location + "#effdivtop";
}
if (afterFunc) { afterFunc(); }
}
});
}
var CURFAM = 92;
var FAMILIARFAVES = [["Values of Beta Will Give Rise To Dom","Baby Bugged Bugbear","babybugbug",124],["Chatapa Chocha Cho","El Vibrato Megadrone","megadrone",81],["Elvis Lives","Jumpsuited Hound Dog","hounddog",69],["Star","He-Boulder","heboulder",113],["Brit Shix (6775)","BRICKO chick","brickochick",123],["But I Very Seldom Follow It","Frumious Bandersnatch","bandersnatch",105],["Gnome Chomsky","Ancient Yuletide Troll","crimbotroll",65] ];
</script>
<script type="text/javascript">
var turnsplayed = 645836;
var turnsthisrun = 28240;
var rollover = 1351222200;
var rightnow = 1351212057;
var playerid = 1075489;
var pwdhash = "6385f5dd2aef25cc1eb6f124330877d3";
var hide_nudges = true;
$(document).ready(function () {
$('.showall').live('click',function () {
var hidden = $(this).attr('rel');
var hd = hidden.split(/,/);
for (var i=0; i< hd.length; i++) {
deleteCookie(hd[i], '');
}
document.location = 'charpane.php?foo=' + escape(Math.random());
});
if (hide_nudges) $('#nudges td div').hover(
function () {
if (!hide_nudges) return;
var ht = '<a href="#" class="close"><img alt="Hide" title="Hide" src="http://images.kingdomofloathing.com/closebutton.gif" /></a>';
var c = $(ht);
$(this).append(c);
c.click(function () {
var key = $(this).parents('tr:first').attr('rel');
$(this).parents('tr:first').remove();
setCookie(key, 1);
});
},
function () {
if (!hide_nudges) return;
$(this).find('.close').remove();
}
);
});
</script>
<script language=Javascript src="/images/scripts/charpane.4.js"></script>
<script type="text/javascript" src="/images/scripts/cookie.20100120.js"></script>
<script type="text/javascript">
jQuery(function ($) {
$(window).resize(function () {
var winW = 300;
if (document.body && document.body.offsetWidth) { winW = document.body.offsetWidth; }
if (document.compatMode=='CSS1Compat' && document.documentElement && document.documentElement.offsetWidth ) { winW = document.documentElement.offsetWidth; }
if (window.innerWidth && window.innerHeight) { winW = window.innerWidth; }
setCookie('charpwd', winW, 365, true);
});
})
</script>
<script type="text/javascript" src="chit.js"></script>
<body onload="updateSafetyText();" bgcolor=white text=black link=black alink=black vlink=black onload='startup();'>
<center id='rollover' class=tiny style='color: red; cursor: pointer;' onClick='doc("maintenance");'></center><div id="chit_house"><div id="chit_roof" class="chit_chamber"></div><div id="chit_walls" class="chit_chamber"><table id="chit_effects" class="chit_brick nospace"><thead><tr><th colspan="4">Effects</th></tr></thead><tbody class="buffs"><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/string.gif" width=30 height=30 onClick='eff("2d6d3ab04b40e1523aa9c716a04b3aab");'></td><td class="info">Leash of Linguini</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Leash+of+Linguini&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Leash of Linguini effect">1</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=cast+1+Leash+of+Linguini&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Leash of Linguini"><img src="/images/relayimages/chit/upred.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/stench.gif" width=30 height=30 onClick='eff("5e788aac76c7451c42ce19d2acf6de18");'></td><td class="info">Musk of the Moose</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Musk+of+the+Moose&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Musk of the Moose effect">1</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=cast+1+Musk+of+the+Moose&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Musk of the Moose"><img src="/images/relayimages/chit/upred.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/pupils.gif" width=30 height=30 onClick='eff("c9cd2df50d6fb5a9d8d7544892c7e5b2");'></td><td class="info">Wasabi Sinuses</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Wasabi+Sinuses&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Wasabi Sinuses effect">1</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=use+1+Knob+Goblin+nasal+spray&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Wasabi Sinuses"><img src="/images/relayimages/chit/upred.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/odetobooze.gif" width=30 height=30 onClick='eff("626c8ef76cfc003c6ac2e65e9af5fd7a");' oncontextmenu='return shrug(71, "Ode to Booze");'></td><td class="info">Ode to Booze</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Ode+to+Booze&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Shrug off the Ode to Booze effect">9</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=cast+1+The+Ode+to+Booze&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Ode to Booze"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/snowflakes.gif" width=30 height=30 onClick='eff("c45d2469bf8cfd8c9bbc953e2a44f3c4");'></td><td class="info">Starry-Eyed</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Starry-Eyed&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Starry-Eyed effect">10</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=telescope+look+high&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Starry-Eyed"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/plasticball.gif" width=30 height=30 onClick='eff("b806c288732675bf60db7b948d748320");'></td><td class="info">Having a Ball!</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Having+a+Ball%21&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Having a Ball! effect">20</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=ballpit&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Having a Ball!"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/monkhead.gif" width=30 height=30 onClick='eff("d75aaa2cc6a8dcfa7cdddef658968e26");'></td><td class="info">Brother Smothers's Blessing</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Brother+Smothers%27s+Blessing&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Brother Smothers's Blessing effect">20</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=friars+booze&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Brother Smothers's Blessing"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style="font-weight:bold"><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/footprints.gif" width=30 height=30 onClick='eff("91635be2834f8a07c8ff9e3b47d2e43a");'></td><td class="info">goth giant</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+On+the+Trail&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the On the Trail effect">29</a></td><td class="powerup"> </td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/raindrop.gif" width=30 height=30 onClick='eff("df5ed605feb8ac254669bbb54b9c22f1");'></td><td class="info">Thaumodynamic</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Thaumodynamic&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Use a remedy to remove the Thaumodynamic effect">50</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=shower+lukewarm&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Thaumodynamic"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/plenty.gif" width=30 height=30 onClick='eff("c26a911b8ec2c57f7eef57f9ff5fdc24");' oncontextmenu='return shrug(63, "Polka of Plenty");'></td><td class="info">Polka of Plenty</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Polka+of+Plenty&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Shrug off the Polka of Plenty effect">12746</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=cast+1+The+Polka+of+Plenty&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Polka of Plenty"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr><tr class="effect" style=""><td class="icon"><img src="http://images.kingdomofloathing.com/itemimages/fatleons.gif" width=30 height=30 onClick='eff("63e73adb3ecfb0cbf544db435eeeaf00");' oncontextmenu='return shrug(67, "Fat Leon's Phat Loot Lyric");'></td><td class="info">Phat Loot</td><td class="shrug"><a href="/KoLmafia/sideCommand?cmd=uneffect+Fat+Leon%27s+Phat+Loot+Lyric&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Shrug off the Fat Leon's Phat Loot Lyric effect">12922</a></td><td class="powerup"><a href="/KoLmafia/sideCommand?cmd=cast+1+Fat+Leon%27s+Phat+Loot+Lyric&pwd=6385f5dd2aef25cc1eb6f124330877d3" title="Increase rounds of Fat Leon's Phat Loot Lyric"><img src="/images/relayimages/chit/up.png" border=0></a></td></tr></tbody></table></div><div id="chit_floor" class="chit_chamber"><table id="chit_toolbar"><tr><th><ul style="float:left"><li><a href="charpane.php" title="Reload"><img src="/images/relayimages/chit/refresh.png"></a></li></ul><ul style="float:right"><li><a title="Save as Mood" href="/KoLmafia/sideCommand?cmd=save+as+mood&pwd=6385f5dd2aef25cc1eb6f124330877d3"><img src="/images/relayimages/chit/moodsave.png"></a></li></ul><ul><li><a class="tool_launcher" title="Current Quests" href="#" rel="quests"><img src="/images/relayimages/chit/quests.png"></a></li><li><a class="tool_launcher" title="Modifiers" href="#" rel="modifiers"><img src="/images/relayimages/chit/modifiers.png"></a></li></ul></th></tr></table></div><div id="chit_closet"><div id="chit_toolquests" class="chit_skeleton" style="display:none"><table id="nudges" class="chit_brick nospace"><tr><th><a target="mainpane" href="questlog.php">Current Quests</a></th></tr><tr rel="qn_ec6e995648e06ab63a9efcba0f475798"><td class="small" colspan="2"><div>(This Quest Tracker is a work in progress. Check your <a class=nounder target=mainpane href=questlog.php><b>Quest Log</b></a> for quests in the meantime.)</div></td></tr></table><script type="text/javascript">hide_nudges = false;</script></div><div id="chit_toolmodifiers" class="chit_skeleton" style="display:none"><table id="chit_modifiers" class="chit_brick nospace"><thead><tr><th colspan="2">Modifiers</th></tr></thead><tbody><tr><td class="label">Meat Drop</td><td class="info">+130.0%</td></tr><tr><td class="label">Item Drop</td><td class="info">+45.0%</td></tr><tr><td class="label"> Booze Drop</td><td class="info">(+30.0%)</td></tr><tr><td class="label"> Candy Drop</td><td class="info">(+100.0%)</td></tr><tr><td class="label"> Forced Drop @</td><td class="info">69%</td></tr><tr><td class="label"> Forced Booze Drop</td><td class="info">58%</td></tr><tr><td class="label"> Forced Candy Drop</td><td class="info">41%</td></tr></tbody><tbody><tr><td class="label">Monster Level</td><td class="info">+15</td></tr><tr><td class="label">Initiative</td><td class="info">+40%</td></tr><tr><td class="label">Modified Init</td><td class="info">+40%</tr><tr><td class="label">Combat Rate</td><td class="info">+5%</td></tr></tbody><tbody><tr><td class="label">Damage Absorp</td><td class="info">66% (590)</td></tr><tr><td class="label">Damage Red</td><td class="info">14</td></tr></tbody><tbody><tr><td class="label">Spell Damage</td><td class="info">+10 / +20%</td></tr><tr><td class="label">Weapon Damage</td><td class="info">+37 </td></tr><tr><td class="label">Ranged Damage</td><td class="info">+15 </td></tr></tbody></table></div></div></div></body></html>