Dungeons & Dragons 2024 Core Rulebooks Pre-Order
  1. #1

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286

    Initiative tools

    A complicated ruleset modification, but very useful (I think): The characterlist (above the chat box) displays the character's initiative and a flag indicates the player who's turn it is in the GM's combat tracker. The initiative can be changed by the GM by either dragging the result of a die roll onto the appropriate field in the combat tracker, by dragging the result of a die roll with description "Initiative" onto the character's portrait, or by directly modifying the initiative field in the combat tracker by scrolling the mouse.

    I'll post complete listings of any functions I have changed, one file in each of the next posts. Any changes/additions I made are in bold italics

    characterlist.lua
    Code:
    function controlSortCmp(t1, t2)
      return t1.init < t2.init;
    end
    
    function layoutControls()
      local identitylist = {};
    	
      for key, val in pairs(User.getAllActiveIdentities()) do
        iInit = DB.findNode("charsheet." .. val .. ".init.value").getValue();
        table.insert(identitylist, { name = val, control = findControlForIdentity(val), init = iInit });
      end
    	
      table.sort(identitylist, controlSortCmp);
    
      local n = 0;
      for key, val in pairs(identitylist) do
        val.control.sendToBack();
      end
    	
      anchor.sendToBack();
    end
    
    function onIdentityActivation(identity, username, activated)
      if activated then
       do
          DB.createNode("charsheet." .. identity .. ".init.value", "number");
          DB.createNode("charsheet." .. identity .. ".init.turn", "number");
          tPCs = DB.findNode("charsheet").getChildren();
          for name, oPC in pairs(tPCs) do
            if User.isHost() then
              DB.findNode("charsheet." .. identity .. ".init").addHolder(oPC.getOwner(), false);
              if oPC.getChild("init") then
                oPC.getChild("init").addHolder(username, false);
              end
            end
          end
          DB.findNode("charsheet." .. identity .. ".init.value").onUpdate = initUpdate;
          DB.findNode("charsheet." .. identity .. ".init.turn").onUpdate = turnUpdate;
          if not findControlForIdentity(identity) then
            createControl("characterlist_entry", "ctrl_" .. identity);
            
            userctrl = findControlForIdentity(identity);
            userctrl.createWidgets(identity);
            
            layoutControls();
          end
          initUpdate(DB.findNode("charsheet." .. identity .. ".init.value"));
        end
      else
        findControlForIdentity(identity).destroy();
        layoutControls();
      end
    end
    
    function initUpdate(node)
      sName = node.getParent().getParent().getName();
      userctrl = findControlForIdentity(sName);
      userctrl.initwidget.setText(node.getValue());
      layoutControls();
    end
    
    function turnUpdate(node)
      sName = node.getParent().getParent().getName();
      userctrl = findControlForIdentity(sName);
      if node.getValue() == 1 then
        userctrl.turnwidget.setVisible(true);
      else
        userctrl.turnwidget.setVisible(false);
      end
    end
    Last edited by Hamish; November 16th, 2007 at 20:03.

  2. #2

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    characterlist_entry.lua
    Code:
    function createWidgets(name)
      identityname = name;
    
      portraitwidget = addBitmapWidget("portrait_" .. name .. "_charlist");
    
      namewidget = addTextWidget("sheetlabelsmall", "- Unnamed -");
      namewidget.setPosition("center", 0, 27);
      namewidget.setFrame("mini_name", 5, 2, 5, 2);
      namewidget.setMaxWidth(75);
    	
      initwidget = addTextWidget("sheetlabelsmall", "0");
      initwidget.setPosition("center", 30, -20);
      initwidget.setFrame("mini_name", 5, 2, 5, 2);
    
      turnwidget = addBitmapWidget("indicator_flag");
      turnwidget.setPosition("center", 30, -20);
      turnwidget.setVisible(false);
    	
      typingwidget = addBitmapWidget("indicator_typing");
      typingwidget.setPosition("center", -23, -23);
      typingwidget.setVisible(false);
    
      idlingwidget = addBitmapWidget("indicator_idling");
      idlingwidget.setPosition("center", -23, -23);
      idlingwidget.setVisible(false);
    	
      colorwidget = addBitmapWidget("indicator_pointer");
      colorwidget.setPosition("center", 31, 16);
      colorwidget.setVisible(false);
    
      resetMenuItems();
      if User.isHost() then
        registerMenuItem("Ring Bell", "bell", 5);
      else
        if User.isOwnedIdentity(name) then
          registerMenuItem("Activate", "turn", 5);
          registerMenuItem("Release", "erase", 4);
        end
      end
    end
    
    function onDrop(x, y, draginfo)
      if User.isHost() then
        -- Portrait icon and number drop
        if draginfo.isType("number") then
          if string.lower(draginfo.getDescription()) == "initiative" then
            DB.findNode("charsheet." .. identityname .. ".init.value").setValue(draginfo.getNumberData());
          else
            local msg = {};
            msg.text = draginfo.getDescription();
            msg.font = "systemfont";
            msg.icon = "portrait_" .. identityname .. "_targetportrait";
            msg.dice = {};
            msg.diemodifier = draginfo.getNumberData();
            msg.dicesecret = false;
      			
            ChatManager.deliverMessage(msg);
      			
            return true;
          end
        end
    
        -- Send dropped string as whisper
        if draginfo.isType("string") then
          local msg = {};
          msg.text = draginfo.getStringData();
          msg.font = "msgfont";
    
          msg.sender = "<whisper>";
          ChatManager.deliverMessage(msg, User.getIdentityOwner(identityname));
    
          msg.sender = "-> " .. User.getIdentityLabel(identityname);
          ChatManager.addMessage(msg);
    
          return true;
        end
    		
        -- Shortcut shared to single client
        if draginfo.isType("shortcut") then
          local win = Interface.openWindow(draginfo.getShortcutData());
          if win then
            win.share(User.getIdentityOwner(identityname));
          end
    		
          return true;
        end
      end
    
    
      -- Portrait selection
      if draginfo.isType("portraitselection") then
        User.setPortrait(identityname, draginfo.getStringData());
        return true;
      end
    end
    Last edited by Hamish; November 16th, 2007 at 14:44.

  3. #3

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    combattracker.lua
    Code:
    function addPc(source, token)
      local newentry = createWindow();
    	
      newentry.setType("pc");
    	
      -- Shortcut
      newentry.name.setReadOnly(true);
      newentry.name.setFrame(nil);
    	
      newentry.link.setValue("charsheet", source.getNodeName());
      newentry.link.setVisible(true);
    	
      -- Token
      if token then
        newentry.token.setPrototype(token);
      end
    	
      -- FoF
      newentry.friendfoe.setState("friend");
    	
      -- Linked fields
      newentry.name.setLink(source.getChild("name"));
      newentry.initresult.setLink(source.getChild("init.value"));
      newentry.hp.setLink(source.getChild("hp.total"));
      newentry.wounds.setLink(source.getChild("hp.wounds"));
    	
      newentry.ac.setLink(source.getChild("ac.totals.general"), source.getChild("ac.totals.touch"), source.getChild("ac.totals.flatfooted"));
    
      newentry.fortitudesave.setLink(source.getChild("saves.fortitude.total"));
      newentry.reflexsave.setLink(source.getChild("saves.reflex.total"));
      newentry.willsave.setLink(source.getChild("saves.will.total"));
    	
      return newentry;
    end

  4. #4

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    combattracker_entry.lua
    Code:
    function setActive(state)
      active.setState(state);
    	
      if state and charactertype == "pc" then
        -- Turn notification
        local msg = {};
        msg.text = name.getValue();
        msg.font = "narratorfont";
        msg.icon = "indicator_flag";
    		
        ChatManager.deliverMessage(msg);
    		
        local usernode = link.getTargetDatabaseNode()
        if usernode then
          User.ringBell(usernode.getName());
          usernode.getChild("init.turn").setValue(1);
        end
      end
      if state == false and charactertype == "pc" then
        local usernode = link.getTargetDatabaseNode()
        if usernode then
          usernode.getChild("init.turn").setValue(0);
        end
      end
    end

  5. #5

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    utility_combattracker.xml
    Change the script block for the numbercontrol named "initresult" to:
    Code:
    <script>
      function onDrop(x, y, draginfo)
        if draginfo.getType() == "number" then
          if linknode then
            linknode.setValue(draginfo.getNumberData());
          else
            setValue(draginfo.getNumberData());
          end
        end
    						
        return true;
      end
    
      function onLinkUpdated(source)
        setValue(source.getValue());
        window.windowlist.applySort();
      end
    					
      function onValueChanged()
        if linknode then
          linknode.setValue(getValue());
        end
        window.windowlist.applySort();
      end
    				
      function setLink(dbnode)
        if dbnode then
          linknode = dbnode;
          linknode.onUpdate = onLinkUpdated;
          onLinkUpdated(linknode);
    							
          addBitmapWidget("indicator_linked").setPosition("bottomright", -5, -5);
        end
      end
    </script>
    Last edited by Hamish; November 17th, 2007 at 17:01.

  6. #6
    Quote Originally Posted by Hamish
    A complicated ruleset modification, but very useful (I think): The characterlist (above the chat box) displays the character's initiative and a flag indicates the player who's turn it is in the GM's combat tracker. The initiative can be changed by the GM by either dragging the result of a die roll onto the appropriate field in the combat tracker, by dragging the result of a die roll with description "Initiative" onto the character's portrait, or by directly modifying the initiative field in the combat tracker by scrolling the mouse.
    Hamish, does this mean the players will all be able to see this as well? And therefore know where they are in initiative order?

  7. #7

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    Yes, that was the whole point, to make it more obvious for the players when their turn would be. The characterlist will order the portraits, the character with the highest initiative is on the left, the one with the lowest on the right. This will show on the host as well as on the client.

  8. #8

    Join Date
    Jun 2007
    Location
    Zeist, Netherlands
    Posts
    286
    16-11-2007 21:04CET
    I just noticed a problem when using this ruleset modification in an existing campaign, for campaigns where no characters have been created yet, this should not be a problem. I'm working on it!
    Fixed characterlist.lua so it will work for existing characters.

    17-11-2007 18:17CET
    There was also a problem with dragging a die roll result to the initiative field in the combat tracker, it would add the number to the existing value instead of replacing it.
    Fixed utility_combattracker.xml to replace the initiative value when dropping a die roll result on it.
    Last edited by Hamish; November 17th, 2007 at 17:20.

  9. #9
    Quote Originally Posted by Hamish
    Yes, that was the whole point, to make it more obvious for the players when their turn would be. The characterlist will order the portraits, the character with the highest initiative is on the left, the one with the lowest on the right. This will show on the host as well as on the client.
    Great. I'll try it out and let you know how I go.

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
  •  
5E Product Walkthrough Playlist

Log in

Log in