Too Many Tabs!! Adding your Library Tabs to the "Features" tabs so they can be toggled on/off

If you're like me, you're using many of Pixie's Libraries, and you've created some of your own. I'm just starting to work on integrating these additional libraries better with the Core.

What started the project for me was having too many tabs from the added libraries. I've discovered how to make them able to be toggled on/off, just like the containers tab. I've even found out how to add liquids from Pixie's LiquidLib to the Containers tab.

If you want a checkbox on a Feature Tab that will toggle the library Tab on/off, you need to update either CoreEditorGame.aslx , CoreEditorObjectFeatures.aslx, or both.

You'll also need to at least one extra line of code to the Library Tab.

Here's an example of what I've personally added to CoreEditorGame.aslx it's on the tab with the caption [EditorGameFeatures]

      <control>
        <controltype>checkbox</controltype>
        <caption>NpcLib (using NpcLib)</caption>
        <attribute>feature_npc</attribute>
      </control>	  

      <control>
        <controltype>checkbox</controltype>
        <caption>Posturing allowed (Sit, stand, recline)</caption>
        <attribute>feature_PostureLib</attribute>
        <onlydisplayif>game.feature_npc</onlydisplayif> 
      </control>	

      <control>
        <controltype>checkbox</controltype>
        <caption>WeatherLib</caption>
        <attribute>feature_WeatherLib</attribute>
      </control>	

      <control>
        <controltype>checkbox</controltype>
        <caption>LiquidLib</caption>
        <attribute>feature_LiquidLib</attribute>
      </control>

      <control>
        <controltype>checkbox</controltype>
        <caption>Ip Worlds(allows for typing of rooms and objects according to Ip style)</caption>
        <attribute>feature_IpWorlds</attribute>
      </control>

      <control>
        <controltype>checkbox</controltype>
        <caption>Expanded Descriptions (Senses, Darkfeel, Ip, CombatLib)</caption>
        <attribute>feature_DescriptionsTab</attribute>
      </control>	  
	  
      <control>
        <controltype>checkbox</controltype>
        <caption>LiftLib</caption>
        <attribute>LiftLib</attribute>
      </control>

With that added, there are now attributes which can be used with <onlydisplayif>on your Library Tab

Also I've updated my CoreEditorObjectFeatures.aslx as follows:

    <control>
      <controltype>checkbox</controltype>
      <caption>NPC (using NpcLib)</caption>
      <attribute>feature_npc</attribute>
      <onlydisplayif>game.feature_npc</onlydisplayif> 
    </control>	

    <control>
      <controltype>checkbox</controltype>
      <caption>Furniture or NPC Postures</caption>
      <attribute>postureable</attribute>
      <onlydisplayif>game.feature_PostureLib</onlydisplayif> 
    </control>	

	
    <control>
      <controltype>checkbox</controltype>
      <caption>ConvLib</caption>
      <attribute>feature_ConvLib</attribute>
    </control>	
	
    <control>
      <controltype>checkbox</controltype>
      <caption>StackLib (for stack related objects)</caption>
      <attribute>feature_stackobject</attribute>
    </control>	

    <control>
      <controltype>checkbox</controltype>
      <caption>Combat Object</caption>
      <attribute>feature_combat</attribute>
    </control>	

    <control>
      <controltype>checkbox</controltype>
      <caption>Holy (works with BornagainLib)</caption>
      <attribute>feature_holy</attribute>
    </control>	

These might reference a CoreEditorGame update, so they wouldn't show unless the checkbox is on the Game object first.
Then with these two set up the way you like. You add the "onlydisplayif" with the "attribute" you picked for toggling your tab.
Here's an example of my updated Stacklib Tab:

  <tab>
    <parent>_ObjectEditor</parent>
    <caption>Stackable</caption>
    <mustnotinherit>editor_room; editor_player</mustnotinherit>
    <onlydisplayif>this.feature_stackobject</onlydisplayif>

It works great to clean up the interface. In the case of adding LiquidLib to the containers Tab, I added Pixie's Liquid Types to the CoreTypes.aslx first.

Then I was able to update CoreEditorObjectContainer.aslx with the following control:

    <control>
      <controltype>dropdowntypes</controltype>
      <caption>liquid?</caption>
      <types>*=[TypeContainerNot]; liquidcontainer=Liquid Container</types>
      <width>150</width>
    </control>

To add Liquid Container to the containers

and at the bottom these parts from Pixie's original tab have been moved over:

    <!-- LiquidLib -->	

    <control>
      <controltype>number</controltype>
      <caption>[EditorObjectContainerLqdMaximumCapacity]</caption>
      <attribute>capacity</attribute>
      <width>100</width>
      <mustinherit>liquidcontainer</mustinherit>
      <minimum>0</minimum>
    </control>
    
    <control>
      <controltype>number</controltype>
      <caption>[EditorObjectContainerLqdStartingVolume]</caption>
      <attribute>full</attribute>
      <width>100</width>
      <mustinherit>liquidcontainer</mustinherit>
      <minimum>0</minimum>
    </control>
    
    <control>
      <controltype>textbox</controltype>
      <caption>[EditorObjectContainerNameStartingLiquid]</caption>
      <attribute>liquidtype</attribute>
      <mustinherit>liquidcontainer</mustinherit>
    </control>

So that the Tab for Liquids appears on rooms, but the containers portion appears on the containers tab.

I'm going to work on cleaning up the very complicated descriptions tab I have for my big project next...

but I intend to look into more fully integrating the libraries into the core, and blending together Pixie's NPC/Postures work possibly into the core or into one combined library.

My eventual goal would be something like a large update of Quest (at least for my own use if folks don't want a version where Pixie's libraries can all be toggled on/off as part of the core).

Here's hoping that this information is interesting or useful to someone!


Update:

Having fun with this project. The amounts of tabs are also lessening as different parts of each tab can be added to core editors like the example from LiquidLib above.

The Object Setup tab can be used as a good place to have dropdowns for different selections of types. Types then can be used to determine how the extant tabs look, which controls are added.

The Game Start Script can be modified in the core to include "if" statements which check whether you wish to "Activate" a set of library features, like CombatLib. If someone selects the checkbox that chooses to activate CombatLib on the features tab, as an example. The game start script can read "if HasAttribute(game, "whateverthatcheckboxadds")" then "CombatInitialise".

When I first discovered Quest, I was merely excited that I'd be able to create my own Text Adventure games. I've been very excited and happy to discover that through the documentation and help of users like Pixie and MrAngel, I've learned not to be scared of code. I'm loving learning how to fully use the system.

Thanks for all who make this possible!


So expanding upon the above. The attribute for the feature which in the first core update I mentioned merely toggled a library tab on/off, can be used as a checking reference to initiate the library according to the documentation instructions.

In the case of CombatLib, it was initially just an attribute naming the feature which would be the "Only display if" requirement for the Tab. Building on that, you use that feature in other places like the UI and the Game Start places of the core.

If the game has that feature then CombatInitialise, but also in the Interface, it can activate the "Spells" pane or "2nd Inventory" library, which with only one small update to the "learn" script will populate with known spells.

Here's an example of the two functions I've updated in Core so far as I've been working on more fully integrating the libraries:

  <function name="InitUserInterface">
    if (HasAttribute(game, "feature_DescriptionsTab")) {
      InitInv2 ("Spells")
      SetInv2 (spells_known)
    }
    if (HasAttribute(game, "feature_holy")) {
      InitInv3 ("Bible")
      SetInv3 (verses_known)
    }
  </function>
  
  <function name="StartGame">
    <![CDATA[
    StartTurnOutputSection
    if (game.showtitle) {
      JS.StartOutputSection ("title")
      PrintCentered ("<span style=\"font-size:260%\">" + game.gamename + "</span>")
      if (game.subtitle <> null) {
        if (LengthOf(game.subtitle) > 0) {
          PrintCentered ("<span style=\"font-size:130%\">" + game.subtitle + "</span>")
        }
      }
      if (game.author <> null) {
        if (LengthOf(game.author) > 0) {
          PrintCentered ("<br/><span style=\"font-size:140%\">[By] " + game.author + "</span>")
        }
      }
      msg ("<div style=\"margin-top:20px\"></div>")
      JS.EndOutputSection ("title")
    }
    if (game.pov = null) {
      playerObject = GetObject("player")
      if (playerObject = null) {
        if (ListCount(AllObjects()) > 0) {
          firstRoom = ObjectListItem(AllObjects(), 0)
        }
        else {
          create ("room")
          firstRoom = room
        }
        create ("player")
        player.parent = firstRoom
      }
      game.pov = player
    }
    else {
      InitPOV (null, game.pov)
    }
    InitStatusAttributes
    UpdateStatusAttributes
    InitVerbsList
    if ((HasAttribute(game, "feature_DescriptionsTab") and (HasAttribute(game, "feature_holy")))) {
      CombatInitialise
      game.scopebackdrop => {
        foreach (o, GetDirectChildren(spells_known)) {
          list add (items, o)
        }
        foreach (o, GetDirectChildren(verses_known)) {
          list add (items, o)
        }
      }
    }
    else if (HasAttribute(game, "feature_DescriptionsTab")) {
      CombatInitialise
      game.scopebackdrop => {
        foreach (o, GetDirectChildren(spells_known)) {
          list add (items, o)
        }
      }
    }
    else if (HasAttribute(game, "feature_holy")) {
      game.scopebackdrop => {
        foreach (o, GetDirectChildren(verses_known)) {
          list add (items, o)
        }
      }
    }
    if (HasAttribute(game, "feature_IpWorlds")) {
      game.gamestorage = NewObjectList()
      game.pervtype = NewObjectList()
      foreach (obj, FilterByType (allobjects(), "pervtype")) {
        list add (game.pervtype, obj)
      }
      foreach (obj, FilterByType (AllRooms(), "gamestorage")) {
        list add (game.gamestorage, obj)
      }
    }
    if (HasAttribute(game, "feature_ShopLib")) {
      set (game, "moneyformat", £!1.2!)
    }
    if (HasAttribute(game, "showreactions")) {
      player.contacts = NewObjectList()
      foreach (obj, AllObjects()) {
        if (HasAttribute(obj, "playercontact")) {
          list add (player.contacts, obj)
        }
      }
    }
    if (HasScript(game, "start")) do (game, "start")
    foreach (obj, AllObjects()) {
      if (HasScript(obj, "_initialise_")) do (obj, "_initialise_")
    }
    UpdateStatusAttributes
    UpdateObjectLinks
    on ready {
      if (game.gridmap) {
        Grid_DrawPlayerInRoom (game.pov.parent)
      }
      if (game.displayroomdescriptiononstart) {
        OnEnterRoom (null)
      }
      UpdateStatusAttributes
      UpdateObjectLinks
    }
    // Added by KV to use the old JS clearScreen if the transcript is disabled
    if (GetBoolean(game, "notranscript")){
      JS.eval("transcriptEnabled = false;")
    }
    game.runturnscripts = false
    FinishTurn
    ]]>
  </function>

NOTE: Core.aslx is the one file that you cannot rename, and then have the other parts of the core call the new version. (Example CoreEditor3.aslx)

So I Highly recommend keeping your Core variants in different folders for different versions before choosing which one to drop in your ProgramFiles-->Quest 5--> core folder. That way you can "switch" which core games you're using without fear of losing the original quest core, or any of your versions.

I can easily revert back to the naked quest 5.8 engine, by copying "core" from my "original" folder to the "Core" folder. Or switch to the version where only tabs toggle on/off by copying the "core" from "Core2" into the "Core" folder. All other updates can sit next to eachother as long as each version = a file-name and "includeref" update for version number.

Here's hoping this makes sense and is helpful for someone. It's all been part of my learning process for coding and Quest. I'm forever grateful to the quest creator, whomever that is, and also to my heroes Pixie, MrAngel, and other forum participants who educate us newbies into hobbyists.


Help!

I hadn't made a multi-attack monster using Pixie's CombatLib yet, but as I'm testing my core integrations, I'm getting an error with the Shaman from the tutorial. I made him a ritual knife as an additional object. The Frost Blast executes fine, but when he attacks with the ritual knife, I get errors that are like this one.

Error running script: Error compiling expression 'Replace(this.attackdesc, "%", CapFirst(GetDisplayAlias (owner))) + " and misses."': FunctionCallElement: Could find not function 'Replace(Object, String, String)'

At first I wondered if the function in question was put in the wrong place when I integrated combat stuff into the core, but it turns out this function isn't part of CombatLib it's just frequently used by it.

Does anyone know what's causing the error? Was this discussed in forums years ago when CombatLib was polished and first published?

Please and thanks for any info/direction.


While tossing this little snafu with the multi-attack monsters on the back burner, i'm having a blast plugging away here at the integrations with CombatLib specifically.

Places where Pixie offers/recommends creating attributes, functions, scripts and/or overriding are getting added to the tabs and appear or not based on types and functions. The editor_player type now has two attributes changedintelligence and changedmana_bonus which have an "if" script to check whether game.feature_mana is being used and runn SetMana if it's there. So his Vanician magic option is now an option on the game features tab which becomes available if using CombatLib.

There are now a set of controls on that Combat tab which appear for editor_player type as well and "onlydisplayif" scenarios.

Added a string dictionary control to Game player tab for checking/adding attributes as I/people decide to create my/their own.

I don't know why I have so much fun learning the quest code by studying my heroes this way, but I do. And these integrations will make it even easier to create and customise my games without having to always go to the Attributes tab and remember everything or look it up.


Was inspired with the answer to the multi-attack monster issue reading in the other forum. Mrangel answered someone elses' question and it helped me see what I need to do here. Really, the only issue is that the attackdescription is a required field so the attribute has to exist when the multi-attack monster scripts are running. Below is the post when I figured out the answer in https://textadventures.co.uk/forum/quest/topic/br2wcmnfue_ar142pugg4a/2-status-attributes-on-same-line

Mrangel, this looks very similar to an error I'm working on in Pixie's combatlib. He's got something called a multi-attack monster. You drop several objects inside the monster, and his library scripts are meant to randomly pick one of the objects and then run the attack script using those attributes.

The error that comes back when the second attack comes in is like this:

Error running script: Error compiling expression 'Replace(this.attackdesc, "%", CapFirst(GetDisplayAlias (owner))) + " and misses."': FunctionCallElement: Could find not function 'Replace(Object, String, String)'

Which looks very like what Jennifer Wren's error is saying.... but reading this combined with your discussion here gives me an idea!

What if it's missing a required attribute? "attackdesc" isn't filled out on that second attack.... let me check...

Yes! That was it! You solved one of my problems while solving Ms. Jennifer's! all the library wants is an addition to the editor here "Required for multi-attack types" and probably also to be also on the appropriate combat tabs in the editor instead of only the "description" tab. That way when it is a monster attack, it's right with all the other fields that define it.

Thanks Mr. Angel. You're a hero in this forum! And also thanks Jennifer for your part in the inspiration and encouragement. It's encouraging to also see other folks learning as they try to build games!


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

Support

Forums