Starfinder Playlist
  1. #1

    Adding different types of NPC sheets

    Is it possible to have diferent types of NPC sheets?

    I ask because I want to have a different NPC sheet depending on the type of NPC in the game. The Ruleset I am modifing is a Star Wars Saga version. Types I am looking to break out, Droid, Creature, Vehicle, and Starship. I would like to have specific sheets for eah one to make GMing a bit easier. Any thoughts?

  2. #2
    Foen's Avatar
    Join Date
    Jan 2007
    Location
    Suffolk, England
    Posts
    2,007
    You could build an NPC sheet which has fields for all NPC types, but just show/hide the ones you need depending on which type is selected by the GM.

    I use a custom template control which allows you to cycle through a text list by clicking on it, and then show/hide fields based on the current value of the control. It works like a checkbox, but has more than two states and displays text rather than an icon.

    Stuart

  3. #3
    Quote Originally Posted by Foen
    You could build an NPC sheet which has fields for all NPC types, but just show/hide the ones you need depending on which type is selected by the GM.

    I use a custom template control which allows you to cycle through a text list by clicking on it, and then show/hide fields based on the current value of the control. It works like a checkbox, but has more than two states and displays text rather than an icon.

    Stuart
    Could you post an example text or file?

    Just to make sure I understand, I have all the fields that I would want on any of the NPC sheets. Then I show/hide depending on what type of sheet I have selected. IE: Only the fields for Droid show when I am opening a droid NPC sheet.

    How would that look on the sheet? Would it condense the spaces? Or would it look like a bunch of dead space here and there?

  4. #4
    A perfect example would be the NPC sheets in the C&C ruleset, which do exactly what Foen describes.

    Notice the monster tick is unchecked. This is an NPC sheet.



    When you check it it changes the fields to those used for a monster entry.

    Alea Iacta Est
    The Die is Cast!

  5. #5
    Foen's Avatar
    Join Date
    Jan 2007
    Location
    Suffolk, England
    Posts
    2,007
    Sorry for the delay in responding on this one. I'll try to dig out some sample code as soon as I get a spare few minutes.

    Stuart

  6. #6
    Cool, I appreciate the help. After seeing the example I bought the C&C ruleset. Granted any direct code you can show me would be awesome.

    Chris

  7. #7
    Foen's Avatar
    Join Date
    Jan 2007
    Location
    Suffolk, England
    Posts
    2,007
    Here is the definition for a template control, which allows you to cycle through a list of pre-defined values:

    Code:
      <template name="multitext">
        <stringcontrolX>
          <statelabels mergerule="resetandadd">
            <state>On</state>
            <state>Off</state>
          </statelabels>
          <static />
          <script>
            local sourcelessvalue = 1;
            local enabled = true;
    
            function setState(state)
              if self.beforeStateChanged then
                state = self.beforeStateChanged(state);
              end
              if state == nil or state == false then
                state = 1;
              end
              if source then
                source.setValue(state);
              else
                sourcelessvalue = state;
                update();
              end
            end
    
            function update()
              if source then
                setValue(statelabels[1].state[source.getValue()]);
              else
                setValue(statelabels[1].state[sourcelessvalue]);
              end
              if self.onStateChanged then
                self.onStateChanged();
              end
            end
    
            function getState()
              if source then
                return source.getValue();
              else
                return sourcelessvalue;
              end
            end
    
            function onClickDown(button, x, y)
              if enabled then
                local newstate = getState() + 1;
                if newstate &gt; table.getn(statelabels[1].state) then
                  newstate = 1;
                end
                setState(newstate);
              end
            end
    
            function onInit()
                if super 
                and super.onInit then
                  super.onInit();
                end
              setValue(statelabels[1].state[1]);
    
              if not sourceless and window.getDatabaseNode() then
                if sourcename then
                  source = window.getDatabaseNode().createChild(sourcename[1], "number");
                else
                  source = window.getDatabaseNode().createChild(getName(), "number");
                end
                if source then
                  source.onUpdate = update;
                  update();
                end
                if window.getDatabaseNode().isStatic() then
                  enabled = false;
                end
              else
                if state then
                  sourcelessvalue = state[1];
                  update();
                end
              end
              if readonly then
                enabled = false;
              end
            end
    
            function setEnabled(state)
              if not sourceless and window.getDatabaseNode() then
                if window.getDatabaseNode().isStatic() then
                  state = false;
                end
              end
              enabled = state;
            end
          </script>
        </stringcontrolX>
      </template>
    The following shows how this might be used in an NPC sheet:

    Code:
      <multitext name="npctype">
        <anchored>
          ... some anchoring ...
        </anchored>
        <font>sheettextsmall</font>
        <script>
          function onInit()
            if super and super.onInit then
              super.onInit();
            end
            if getState() &lt; 1 then
              setState(1);
            elseif getState() &gt; 3 then
              setState(3);
            end
          end
    
          function onStateChanged()
            ... change the layout of the sheet ...
          end
        </script>
        <statelabels>
          <state>Normal NPC</state>
          <state>Evil Monster</state>
          <state>Special NPC</state>
        </statelabels>
      </multitext>
    There are three things to take account of, when creating sheets with dynamic layout:

    1. Showing/hiding the right controls;
    2. Ensuring that the flow of layout doesn't create gaps; and
    3. Tab order.

    Assuming you use the multitext control (although if you only have two types of NPC you can use a checkbox, like C&C) the first of these is dealt with in the onStateChanged event handler. By examing the getState() result (which returns a number between 1 and n, where n is the number of different text labels), you can selectively show or hide the controls and labels on the NPC sheet.

    Flow layout can be handled in two ways. If life is kind to you, the different NPC fields will just replace each other (maybe a normal NPC has a HP field, but a Monster has a Hit Dice field) in which case you set their anchoring/bounds to the same place and show either one or the other.

    If life is less kind, you can use relative anchoring, which works a bit like HTML flow, putting a control on the windowclass at the 'next position' relative to some starting point. Having other controls above or below it just causes the layout to change automatically. A great example of this can be found in the Combat Tracker code, where dynamic windows for attacks, defences and effects flow one after the other.

    The final item (tab order) is more of a pain. The short answer is that tab order cannot be set dynamically, so removing and adding fields causes the windowclass to behave oddly (you still tab to a field, even though it isn't shown).

    The longer answer involves using stringcontrols, which have an onTab event that can be wired to redirect the focus to the next field. Unfortunately there is no such event for numbercontrols, and you have to fudge it by placing hidden stringcontrols before and after the numbercontrols, to bounce the focus on or back. Unless this is really essential, I suggest you leave it to a later release.

    Hope this is some help!

    Stuart

  8. #8

    closer still

    So I have been examining the code from C&C. WOW. They use a few lua files to help sort out the mess. I have figured out how to get the other check boxes up. The part I am working on now is the actuall showing of the fileds depending on the check. I currently have 4 options (actually 5 for all unchecked) droid, beast, vehicle, and starship. I believe I have all the fields to put in but I will know for sure once my players help me finish a spreadsheet of all npc in the books released thus far. This has helped me identify all the fields I want to include.

    Now to the question:

    Foen, you showed code for a drop down option. Could I add a field that has the type listed and have it select the check box for me. Thus altering the view based on the field. The reason I ask this, I plan on taking my spread sheet and turning it into mods so that I have all th npc available in FG. I dont want to have to think what someting is when I pull it up.

    Second, could it be as simple as using a nested if then statement to show what is on the tabs on the npc sheet?

    If npctype = npc
    display field 1
    display field 2

    else If npctype = droid
    display field 1
    display field 3

    else if npctype = vehicle
    display field 1
    display field 4

    By doing this I can set the tab order. I also should not need an lua to sort things out. Granted I plan on this showing different info on all three tabs.

    Any thoughts?

  9. #9
    Foen's Avatar
    Join Date
    Jan 2007
    Location
    Suffolk, England
    Posts
    2,007
    The code to cycle a text field between a number of values is shown above, and it also has a hook (onStateChanged) which you can use to switch field visibility on or off. The if..elseif..else..end block is good for that, but another way is to set a boolean local variable for each bunch of similar fields:

    local showstats = false;

    if npctype==droid or npctype==npc then
    showstats = true;
    end

    ...

    hp.setVisible(showstats);
    str.setVisible(showstats);
    xp.setVisible(showstats);

    etc.

    Which method you choose depends on whether the fields are grouped into similar types which are shared between npctypes, or whether every npctype has its own unique fields.

    A lua script file is very similar to inline scripting, so don't be too worried about putting your script in a file: it can make it easier to read and maintain than trying to put it all in the xml files.

    Stuart

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Dungeons & Dragons 2024 Core Rulebooks Pre-Order

Log in

Log in