Quest Object Links within HTML Table? [Super Solved]

Is this doable? I made an HTML table by piecing together several strings and printing it in javascript like so:

$("#marketPane").html(t)

...where (t) contains a long string of HTML. However, in the HTML table, there are objects that are printed that I want to make Quest object links instead, so the player can just click on them and see the list of displayverbs.

Among other things, I tried using the text processor {object:whatever}, putting that into the string of HTML but couldn't get that to work:

"<td>{object:whatever}</td>"  // this is just printed out literally
"<td>{eval:{object:whatever}}</td>"  // same
"<td>" + {object:whatever} + "</td>"  // error message

I also tried fiddling with the GetDisplayVerbs built-in function, calling it with an object's string name as an argument, but I either got errors or nothing at all:

<a onclick=\"ASLEvent('GetDisplayVerbs', 'object.name');\"></a>

Is this even doable?


You want to use Quest's ProcessText() function to turn the text processor directives into HTML before you pass them to the javascript.

For example t = ProcessText("{object:whatever}") will set the variable t to a string like: <a id="verblink1234" style="font-face: FogLihtenNo04, Scrambled Tofu; color: puce" class="cmdlink elementmenu" data-elementid="whatever">Whatever Object</a>.

If you're using Quest to assemble the string t and then pass it to Javascript, just call ProcessText on the string first.

If you're using javascript code to generate the link, then you'll need to set it up like the example I gave there. The minimum working link will be <a class="cmdlink elementmenu" data-elementid="objectname">link text</a>. The elementmenu class causes the link to display a verbs menu when it is clicked.

One possible problem with that: At the end of every turn, Quest runs the function UpdateObjectLinks, which sends to javascript a list of all objects currently visible, and their displayverbs. This then calls the javascript function UpdateObjectLinks which goes through all visible links and either creates the verb menu ready for when they're clicked on, or disables them if you can no longer see that object. So if you create an object link in javascript, it won't work until Quest's "end of turn" cleanup runs. If your javascript was started from within Quest, this is still fine. If not, you will probably want to run ASLEvent('UpdateObjectLinks') to force it to fill in the menmu data for your new link.


Partial success! I'm assembling the string t in Quest and then passing it to JS. So ProcessText("{object:whatever}") works to print the alias of the object, but it still doesn't display as a clickable object link. I'm going to try ASLEvent('UpdateObjectLinks') next...


You don't need to call UpdateObjectLinks manually if you're sending the string from Quest; it's done automatically after running turnscripts every turn.

If the link isn't clickable, it probably means the object isn't visible. Like when the player leaves a room, all the objects in that room become non-clickable.

There's two ways around this, if you really want a verb menu to be displayed for objects that aren't visible. One is to modify the UpdateObjectLinks function so that it includes all the objects you want when it's compiling its list of which objects should have links. The other is to override the javascript (I can show you the code for that when I get back, if you need it).


K.V.

This post may contain sensitive material.

This works for me in Quest 5.7.2 (which is what's installed on this old Windows 7 machine I am currently using).

At first, it didn't work, then I realized I'd changed the defaults in Quest on this machine, and the hyperlinks were disabled by default. Once I enabled the hyperlinks, it miraculously worked for me!

<!--Saved by Quest 5.7.6729.435-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Table with Object Link">
    <gameid>b6723229-eb97-4ab6-84d6-4da010311753</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <enablehyperlinks />
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <description><![CDATA[<table><tr><th>OBJECT:</th></tr><tr><td>{object:dildo}</td></tr></table>]]></description>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="dildo">
      <inherit name="editor_object" />
      <look><![CDATA[It has an inscription which reads:<br/><br/>PROPERTY OF XM]]></look>
    </object>
  </object>
</asl>

image


To add a little JS to the mix, I gave my <td> an id of table-object1 and added a test command to change the text:

<!--Saved by Quest 5.7.6729.435-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Table with Object Link">
    <gameid>b6723229-eb97-4ab6-84d6-4da010311753</gameid>
    <version>2.0</version>
    <firstpublished>2018</firstpublished>
    <enablehyperlinks />
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <description><![CDATA[<table><tr><th>OBJECT:</th></tr><tr><td id="table-object1">{object:dildo}</td></tr></table>]]></description>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="dildo">
      <inherit name="editor_object" />
      <look><![CDATA[It has an inscription which reads:<br/><br/>PROPERTY OF XM]]></look>
    </object>
  </object>
  <command name="test">
    <pattern>test</pattern>
    <script>
      t = ProcessText("{object:dildo:sex toy}")
      JS.eval ("$('#table-object1').html('" + t + "');")
    </script>
  </command>
</asl>

image


EDIT

I'm bad about not refreshing my page before posting things. MrAngel is probably onto something, but I didn't see his post about how maybe the object wasn't in scope until I'd already posted this.


Just because it's buzzing around in my head now, here's some javascript that will make the verbs menu display for an object that isn't visible:

$(function () {
  var forcedVerbs = {};
  var original_updateObjectLinks = updateObjectLinks;
  updateObjectLinks = function(data) {
    original_updateObjectLinks($.extend(data, forcedVerbs));
  };
  forceLinkVerbs = function (object, verbs) {
    if (verbs) {
      forcedVerbs[object] = verbs;
    } else {
      delete (forcedVerbs[object]);
    }
  };
});

or if you're on the web version:

JS.eval("$(function() {var fv={};var uol=updateObjectLinks;updateObjectLinks=function(d) {uol($.extend(d,fv));};forceLinkVerbs=function(i,vb) {if(vb) {fv[i]=vb;} else {delete (fv[i]);}};});")

Then you can do something like JS.forceLinkVerbs("jenny", "call/think about/look for") in Quest, immediately after printing out {object:jenny}, to make your verbs appear. The verbs passed to this function will be displayed instead of the object's displayverbs or inventoryverbs, and will stop the object link being disabled when it goes out of scope.

(Note: If the object is visible, its regular displayverbs or inventoryverbs will still be used in the sidebar. This only modified object links)

(Note2: Most built-in commands will generate a message like "You can't see that" if the object isn't reachable)

(Note3: JS.forceLinkVerbs("objectname", "") will restore the object's links to their default behaviour)

(Note4: I'm typing this off the top of my head, so sorry if it has errors)


@mrangel
Thank you for your excellent info. To make my objects visible, what if I just put them as scenery objects in the room? Although I am learning what I can from your code, I'm trying to stick to simpler solutions wherever possible, so that I can edit them myself.

@KV
In your second code post, you have a line:

JS.eval ("$('#table-object1').html('" + t + "');")

I've been trying to do that as:

JS.eval ("$('#table-object1').html(t);")

...which of course didn't work. So I've learned yet another thing! (This syntax is so confusing and seemingly arbitrary.) So I don't even need to send my t variable from Quest to a JS function to print it out; I can just do it all in Quest.

On a side note, you need a use verb on that toy. I'm getting to know XanMag better too : )


To make my objects visible, what if I just put them as scenery objects in the room?

So to answer my own question, designating objects as scenery disables their displayverbs list from showing up, even when their object links are displayed. So that is not a solution. I'm going to try modifying the UpdateObjectLinks function now...


Issue #1 - So here is the section of UpdateObjectLinks that, well, updates the object links:

data = NewStringDictionary()
foreach (object, ScopeVisible()) {
  dictionary add (data, object.name, Join(GetDisplayVerbs(object), "/"))
}
----------------------------- I added this part (below) ----------------------------------------
if (game.pov.parent = Market) {
  foreach (item, game.data) {
    dictionary add (data, item, Join(GetDisplayVerbs(object), "/"))
  }
}
---------------------------- I added this part (above) ------------------------------------------
JS.updateObjectLinks (data)

So Quest puts all visible objects into a string dictionary called data. I just added my non-visible items (whose display verbs list I want shown/clickable) from my stringlist game.data into data. Then JS.updateObjectLinks (data) is run. My non-visible items will show their object links, but clicking on the links still shows nothing, no displayverbs list.

Issue #2 - I want to display my non-visible objects in that long HTML string t. So if I do:

<td>{object:SpecificItemName}</td>

...that displays correctly. But what if I want to use a variable instead of a specific object? These don't work; they display literally:

<td>{object:variable}</td>
<td>{object:variable.name}</td>
<td>{object:{=variable}}</td>
<td>{object:{=variable.name}}</td>

Any additional adult toy examples would be appreciated...


Ok, again answering one of my own questions...

For Issue #2, I should use game.text_processor_variables, which is explained under http://docs.textadventures.co.uk/quest/text_processor.html (under "Local variables")

UPDATE: Issue #2 is back in play. I couldn't get this to work right (sigh).

UPDATE2: In the text processor, I tried to use attributes instead of variables to display object links -- Quest doesn't seem to allow this as you can't nest the attribute within the {object:XXX} directive, as per my other post.


I tested the forced verb lists javascript above, and can confirm that it works.

(I actually entered it in the javascript console on some random game, rather than creating one to test it. But it seems to work, and not to break the verb menu for other objects)

For Issue #2, I should use game.text_processor_variables,

Which version of Quest are you using?
text_processor_variables is new in 5.8

UPDATE2: In the text processor, I tried to use attributes instead of variables to display object links

That's a pretty sensible way to do it. Unfortunately, yes, this is a weakness of the text processor.
If you're writing Quest code, you could always take an object name before running the text processor. For example t = "{object:" + obj.name + "}" (leaves your variable t containing the string {object:pencil} which you can then pass to the text processor normally).

If you have a message which wants to get an object name from an attribute somewhere, you could also preprocess it.
I think you might be able to do, for example, someobject.someattribute = "{object:pencil}", and then later you can pass "{someobject.someattribute}" to the text processor.


Sorry it's taken me so long to respond; I have been busy all week long. Just for the record, I am using Quest 5.8 on the desktop.

This is what I've got so far -- for the object links in my built-up t variable, I'm using "{object:" + obj.name + "}", as mrangel suggested (this is genius!). Quest accepts this, but, by itself, this isn't enough to make the links appear as those objects aren't visible (though the font changes for some reason). To make them full-fledged links, I added:

if (game.pov.parent = Market) {
  foreach (item, game.data) {
    dictionary add (data, item, Join(GetDisplayVerbs(object), "/"))
  }
}

to UpdateObjectLinks (as mentioned previously) in order to add my objects to Quest's data dictionary, making them "visible". Now the links display but the displayverbs still don't show up when you click the link. So I added mrangel's js code (above) to my .js script:

$(function enableObjectLinks() {
  var forcedVerbs = {};
  var original_updateObjectLinks = updateObjectLinks;
  updateObjectLinks = function(data) {
    original_updateObjectLinks($.extend(data, forcedVerbs));
  };
  forceLinkVerbs = function (object, verbs) {
    if (verbs) {
      forcedVerbs[object] = verbs;
    } else {
      delete (forcedVerbs[object]);
    }
  };
});

I named the function enableObjectLinks and am calling it from my UserInitInterface tab. I'm also supposed to call JS.forceLinkVerbs("myobject", "buy/sell") immediately after my object links are printed. This is my (relevant) code I'm using to print those in HTML:

$('#marketPane').html(t);
setCss (".MPListing", "color:DarkCyan;");

#marketPane is the element that contains t (bear in mind that there are multiple object links in t), and .MPListing is just the class id for any lines of HTML containing those object links.

Issue #1 Placing JS.forceLinkVerbs("myobject", "buy/sell") on the next line of js code doesn't seem to do anything. Do I have to call that js function inside the t variable?

Issue #2 I hate to bug you with this, but when the object links are printed, the color and font is changed. Is there any way to change them to the right color/font?

Thanks again for all your help.


I named the function enableObjectLinks and am calling it

Don't. The function should be unnamed, just like it was in the code I gave you, and the $( immediately before the function () means it will call itself as soon as all the other JS files have been loaded.

Placing JS.forceLinkVerbs("myobject", "buy/sell") on the next line of js code doesn't seem to do anything.

That's Quest code. If you're calling it from the javascript side, you just want:
forceLinkVerbs("myobject", "buy/sell")


Ok, I got rid of the new name and am not calling it in the UI Init tab.

I placed forceLinkVerbs("cloth", "buy/sell") directly after $('#marketPane').html(t); ("cloth" is one of the objects). The displayverbs still don't show up when you click on the link. Also, since there are multiple objects, I need to replace "cloth" with something that represents those multiple objects -- what is the syntax for that?

UPDATE: I undid my modifications to UpdateObjectLinks since your JS already includes that. You know, my mod and your JS each had the same result in the sense that each enabled the object links, but clicking on the links still did nothing.

UPDATE2: As for calling forceLinkVerbs on multiple objects, can I use JS "Loop Fors"? (I'm studying w3schools.com)

UPDATE3: Added semi-colon after forceLinkVerbs("cloth", "buy/sell") but that made no difference.


The code works for me; I can't work out what you're doing different.
Can you share what you've got so far so I can take a look at it?


Ok, so my UI Init tab runs this setup JS function:

function setupMarketPane() {
    var t = "<table id=\"marketPane\"></table>";
    $("body").append(t, $("#marketPane"));    
    $("#marketPane").insertAfter($("#gridPanel")).width('39.5%').css({'position':'fixed','z-index':'5','height':'0px','margin-top':'44px','margin-left':'18px','background-color':'FloralWhite','transition':'height 0.3s'});    
};

This creates the t variable (HTML built-up string) and marketPane element (holds the HTML table) and appends them to the body so that they will not be cleared on ClearScreen.

Then after the player enters the Market room, this Quest function is called:

t = "<table id=\"marketPane\"><th class=\"MPTitle\" colspan=\"4\">THE AGORA</th><tr><th class=\"MPProps\" width=\"50%\">ITEM</th><th class=\"MPProps\" width=\"25%\">LOAD</th><th class=\"MPProps\" width=\"10%\">QUANTITY</th><th class=\"MPProps\" width=\"15%\">PRICE</th></tr>"
// ITEMS RANDOMIZER -
t = t + "<th class=\"MPCategory\" colspan=\"4\">Commodities</th>"
game.AgoraCommCopy = game.AgoraComm
CommNum = GetRandomInt(1,3)
for (CommLoop, 1, CommNum, 1) {
  c = PickOneString (game.AgoraCommCopy)
  list remove (game.AgoraCommCopy, c)
  c = GetObject(c)
  qty = GetRandomInt(c.QtyMin,c.QtyMax)
  price = GetRandomInt(c.PriceMin,c.PriceMax)
  t = t + "<tr><td class=\"MPListing\" width=\"50%\">" + ProcessText("{object:" + c.name + "}") + "</td><td class=\"MPListing\" width=\"25%\">" + c.load + "</td><td class=\"MPListing\" width=\"10%\">" + qty + "</td><td class=\"MPListing\" width=\"15%\">" + price + "</td></tr>"
}
// Directly below - Extra unmodified row needed at end of table to enable proper vertical spacing.
t = t + "<tr></tr></table>"
game.t = t
JS.openMarketPane (t)

So the above function builds up the t variable (title, subtitle, category subtitle, and randomized listings of items (where the object links are). Where it says " + ProcessText("{object:" + c.name + "}") + " is where the object links are printed. At the end of all of this, JS.openMarketPane (t) is called:

function openMarketPane(t) {
    $('#marketPane').height('580px').html(t).css({'border':'2px solid DarkCyan'});
    forceLinkVerbs("wines", "Look at/Take");
    forceLinkVerbs("olive oil", "Buy/Sell");
    forceLinkVerbs("cloth", "look at/use")
    setCss (".MPTitle", "height:20px;padding-top:20px;padding-bottom:5px;font-size:20px;text-align:center;color:DarkCyan;");
    setCss (".MPProps", "height:20px;padding:3px 20px 15px;text-align:left;font-style:italic;color:DarkTurquoise;");
    setCss (".MPCategory", "height:20px;padding:3px;color:DarkCyan;");
    setCss (".MPListing", "height:20px;padding:3px 20px;text-align:left;color:DarkCyan;");
};

Then there is your JS code:

$(function () {
  var forcedVerbs = {};
  var original_updateObjectLinks = updateObjectLinks;
  updateObjectLinks = function(data) {
    original_updateObjectLinks($.extend(data, forcedVerbs));
  };
  forceLinkVerbs = function (object, verbs) {
    if (verbs) {
      forcedVerbs[object] = verbs;
    } else {
      delete (forcedVerbs[object]);
    }
  };
});

Please ask if there are any questions about this (questionable?) code...


Ok, I just figured out why the displayverbs weren't working for me. It's because I set the z-index of marketPane to 5. When I set it to 0, then the displayverbs show up. Yay!


I just can't see the problem there :S

Though I would point out that having two tables inside each other with the same ID is a little odd. It's not valid HTML; though I suspect the browser will just ignore it. I would suggest that the t passed to openMarketPane shouldn't include <table id=\"marketPane\"> or </table>, as this HTML string is being placed inside the existing <table> tag.

Also, your setupMarketPane function seems to be a little inefficient. You're appending the new element at the end of the body, and then calling insertAfter to remove it from there and place it elsewhere in the document. It may be slightly more efficient to write:

function setupMarketPane() {
    $('<table>',  {id: 'marketPane'}).css({position:'fixed', 'z-index':5, width:'39.5%', height:0, marginTop:44, marginLeft:18, backgroundColor:'FloralWhite', transition:'height 0.3s'}).insertAfter('#gridPanel');
};

Again, this is a little neater, maybe a little more efficient, but I don't think it could be causing your problem.


One last thought, which I'm sure you've double-checked a dozen times, but:

    forceLinkVerbs("wines", "Look at/Take");
    forceLinkVerbs("olive oil", "Buy/Sell");
    forceLinkVerbs("cloth", "look at/use")

Have you double checked that those object names are correct? Not capitalised, or anything like that? That's the only think I can think of at this point.

Oh, also, the third forceLinkVerbs line is missing its semicolon.


Ok, I just figured out why the displayverbs weren't working for me. It's because I set the z-index of marketPane to 5. When I set it to 0, then the displayverbs show up. Yay!

Ah ... the outer marketPane table was appearing in front of the inner one, and catching all the clicks?


Yeah, my marketPane was appearing over the displayverbs!

What do you mean "outer" and "inner" marketPane? I thought that there was only one!?

UPDATE: I see, marketPane is a table, and t is also a table within marketPane. So I should get rid of the table tags from t.


Yeah; your generated HTML was starting with <table id="marketPane"><table id="marketPane"><tr> and ending with </tr></table></table>.


Unfortunately, when I replaced my setupMarketPane code with yours, the HTML table would not even display anymore after the player enters the market room. Any idea why that might be?

UPDATE:
"I would suggest that the t passed to openMarketPane shouldn't include <table id="marketPane"> or , as this HTML string is being placed inside the existing tag."

When I delete the inner table tags from the t variable, then the table displays but is completely blank!


Another thing -- here is an abridged version of the JS function openMarketPane (above) where the t table is printed out:

function openMarketPane(t) {
    $('#marketPane').height('580px').html(t).css({'border':'2px solid DarkCyan'});
    forceLinkVerbs("wines", "Buy/Sell");
    forceLinkVerbs("olive oil", "Buy/Sell");
    forceLinkVerbs("cloth", "Buy/Sell");
};

Since I'm going to have dozens of possible randomized objects printed out in this table in the future, I don't want to have to call forceLinkVerbs(); for every object. So what I'm doing is this -- in that big Quest function where objects are randomly selected and the t variable is built up (above), I made a string (acc) composed of all the objects that are currently being printed out, with a single space between each object, e.g., cloth wines olive_oil. This string acc is sent along with t to this new version of the JS function openMarketPane:

function openMarketPane(t, acc) {
    $("#marketPane").height('580px').html(t).css({'border':'2px solid DarkCyan'});
    acc.split(" ");
    var idx;    
    for (idx = 0; idx < acc.length; idx++) {
        forceLinkVerbs(acc[idx].trim(), "Buy/Sell");
    }
    window.alert(acc)
};

So acc should be converted into an array with spaces as separators. The for loop should run forceLinkVerbs for each string (object) in the array, trimming away the blank spaces for each.

But this new openMarketPane function doesn't work -- the table is printed out but the objects don't have their links enabled. window.alert(acc) confirms that acc is, in fact, a string list of all the objects that should be printed out, separated by single spaces. If I can't get this to work, then I'll have to go back to a long list of forceLinkVerbs calls...


acc.split(" ") returns an array, just like Split(acc, " ") in Quest. It doesn't modify acc itself..

Also, there's no reason not to use $.each here:

function openMarketPane(t, acc) {
    $("#marketPane").height('580px').html(t).css({'border':'2px solid DarkCyan'});
    $.each(acc.split(" "), function (idx, val) {
        forceLinkVerbs(val, "Buy/Sell");
    });
};

($.each takes two parameters. The first is an array, the second is a function which will be run on every member of the array. That function is passed two parameters: the index into the array, and the item from the array. The syntax looks a bit weird until you get used to it, but it can make your code a lot smaller)


Also, why stick them together into a string? You can just pass a stringlist from Quest. (Note: valid data types for paramaters using the JS. command are: string, object, int, double, boolean, stringlist, stringdictionary. If I remember correctly. You can pass a stringlist, but not a plain list even if its members are strings).

Or even keep the loop in Quest; you could put: JS.forceLinkVerbs (c.name, "Buy/Sell") inside your object randomizer loop, eliminating the need to assemble a list and then loop over it again.


Actually... I'm wondering why setupMarketPane is necessary.
If your string t includes the <table> tag, then you could omit setupMarketPane, and have

function openMarketPane(t, acc) {
    $(t).insertAfter('#gridPanel');
    // add .css(), .height(), etc if necessary; or include the style="" within t
    $.each(acc.split(" "), function (idx) {
        forceLinkVerbs(acc[idx], "Buy/Sell");
    });
};

Sorry, my brain's jumping all over the place today.


Unfortunately, when I replaced my setupMarketPane code with yours, the HTML table would not even display anymore after the player enters the market room. Any idea why that might be?

I just tested it with all your CSS, and it looks like it's appearing off the bottom of the screen. You're setting position: fixed but not specifying where it should be fixed, which is usually discouraged. If you add the CSS property top: 0 or bottom: 0 it appears fine.

I'm a little puzzled, because when I test it, it does exactly the same with your initial code. (When I was playing with this before, I just assumed your CSS was fine and didn't look at it, so I didn't notice this issue earlier)


When I delete the inner table tags from the t variable, then the table displays but is completely blank!

I can't replicate this. I tried everything I can think of, but I can't get that to happen.


(another side-note: your string t looks long and unwieldy, which makes it a little harder to track what is going on. It might be possible to streamline it by setting class="MPListing on the row instead of every cell (so it only appears once per line), and doing:
setCss (".MPListing td", "height:20px;padding:3px 20px;text-align:left;color:DarkCyan;");


Haha! I laughed while reading this because you are repeatedly asking why I did things in such an inefficient way! Simple, because I don't know what I'm doing! (the perfect example of a little knowledge being dangerous...)


FINAL CODE(?)

function setupMarketPane() {
    $('<table>',  {id: "marketPane"}).insertAfter($("#gridPanel")).width('39.5%').css({'position':'fixed','z-index':'0','height':'0px','margin-top':'44px','margin-left':'18px','background-color':'FloralWhite','transition':'height 0.3s'});    
};

I chose to keep setupMarketPane as this script only needs to be run once per gaming session. Yes, a table is being placed within another table, both with the same ID -- it is strange but it works! I have to put the inner table within something (another table, a row, etc.), or else only a blank table prints out. I might give each table a different ID if I run into a problem there. Appending the t variable to the body was unnecessary.

This is the Quest function MarketItemsGenerator:

t = "<table id=\"marketPane\"><th class=\"MPTitle\" colspan=\"4\">THE AGORA</th><tr class=\"MPProps\"><th width=\"50%\">ITEM</th><th width=\"25%\">LOAD</th><th width=\"10%\">QUANTITY</th><th width=\"15%\">PRICE</th></tr>"
// ITEMS RANDOMIZER -
t = t + "<th class=\"MPCategory\" colspan=\"4\">Commodities</th>"
game.AgoraCommCopy = game.AgoraComm
CommNum = GetRandomInt(1,3)
for (CommLoop, 1, CommNum, 1) {
  c = PickOneString (game.AgoraCommCopy)
  list remove (game.AgoraCommCopy, c)
  c = GetObject(c)
  qty = GetRandomInt(c.QtyMin,c.QtyMax)
  price = GetRandomInt(c.PriceMin,c.PriceMax)
  t = t + "<tr class=\"MPListing\"><td width=\"50%\">" + ProcessText("{object:" + c.name + "}") + "</td><td width=\"25%\">" + c.load + "</td><td width=\"10%\">" + qty + "</td><td width=\"15%\">" + price + "</td></tr>"
  JS.forceLinkVerbs (c.name, "BUY/SELL")
}
t = t + "<tr></tr></table>"
game.t = t
JS.openMarketPane (t)

So I cleaned up my t string as you suggested. I'm also calling JS.forceLinkVerbs (c.name, "Buy/Sell") in here as that is the most elegant solution. I actually wanted to do something like that before, but didn't think it would work -- I thought that you had to print the object links first and then mess around with the display verbs, but obviously that isn't so.

Then your JS code is unchanged:

$(function () {
  var forcedVerbs = {};
  var original_updateObjectLinks = updateObjectLinks;
  updateObjectLinks = function(data) {
    original_updateObjectLinks($.extend(data, forcedVerbs));
  };
  forceLinkVerbs = function (object, verbs) {
    if (verbs) {
      forcedVerbs[object] = verbs;
    } else {
      delete (forcedVerbs[object]);
    }
  };
});

Followed finally by openMarketPane printing everything out:

function openMarketPane(t) {
    $("#marketPane").height('580px').html(t).css({'border':'2px solid DarkCyan'});
    setCss (".MPTitle", "height:20px;padding-top:20px;padding-bottom:5px;font-size:20px;text-align:center;color:DarkCyan;");
    setCss (".MPProps th", "height:20px;padding:3px 20px 15px;text-align:left;font-style:italic;color:DarkTurquoise;");
    setCss (".MPCategory", "height:20px;padding:3px;color:DarkCyan;");
    setCss (".MPListing td", "height:20px;padding:3px 20px;text-align:left;color:DarkCyan;");
};

There was one more issue -- the current font I'm using is "Courgette". When printing the HTML table, Quest uses some other font that is NOT Courgette. This is not a problem, except that when the object links are created with " + ProcessText("{object:" + c.name + "}") + " under MarketItemsGenerator, then the font of those object links changes to Courgette (so the HTML table is showing two different fonts). This must occur when Quest runs one of its built-in turnscripts (it happens AFTER UpdateObjectLinks).

Is there a relatively simple way to change the object link font to, say, the same font as the HTML table? If this is too complicated to fix, I will let this one go...

Thanks again.


{object: forces the link to use the fonts specified in the game's settings.

If you want to force it to use the same font as the table, you probably want to run:
$('#marketPane a').css('font-face', 'inherit');

Or, to stop it messing about with the link formatting at all, you could skip using ProcessText entirely and just use: "<a class=\"cmdlink elementmenu\" data-elementid=\"" + c.name + "\">" + GetDisplayAlias(c) + "</a>".

I recommended ProcessText rather than generating your own HTML because it formats the link the same as other links, which I assumed you would want.

(Sorry for any errors, I'm on my phone so can't double-check right now)


$('#marketPane a').css('font-family', 'inherit'); seems to do the trick.

Thank you very much, MrAngel!


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums