Joshua Stream Pre
Page 6 of 8 First ... 45678 Last
  1. #51
    Decal modules will need to be made manually for now. All they require is a definition.xml file and the decals in the folder and format as noted in the Developer Thread.

    Regards,
    JPG

  2. #52
    Do decals need to be in their own module, or can they be part of a larger module?

  3. #53
    LordEntrails's Avatar
    Join Date
    May 2015
    Location
    -7 UTC
    Posts
    14,879
    Blog Entries
    9
    They can be part of a larger module.

  4. #54
    Zacchaeus's Avatar
    Join Date
    Dec 2014
    Location
    Scotland
    Posts
    17,868
    Quote Originally Posted by darrenan View Post
    Do decals need to be in their own module, or can they be part of a larger module?
    If the product is going to be sold via the store then the decals need to be in their own module. Otherwise you can include decals in the the module itself.
    If you need to contact customer support or if there is something that you would like to see in Fantasy Grounds that isn't currently part of the software or if there is something you think would improve a ruleset then add your idea here http://fgapp.idea.informer.com/

  5. #55
    How hard would it be to add the ability to use a "Random" encounter entry in a Table that outputs encounters? I thought it would work and noticed it doesn't.

    Thanks!

    So I decided to get you at least a working example. This works in my local tests.

    All I did was update addLinkToBattle to support 'battlerandom' items.

    Code:
    ...
    NPCManager.addLinkToBattle = addLinkToBattle;
    ...
    
    --[[
        
      Generate Encounter from Random Encounter and return the node
    
    ]]
    function generateEncounterFromRandom(nodeSource)
    	if not nodeSource then
    		return;
    	end
    	
    	local sDisplayClass = LibraryData.getRecordDisplayClass("battle");
    	local sRootMapping = LibraryData.getRootMapping("battle");
    	if ((sRootMapping or "") == "") then
    		return;
    	end
    	
    	local nodeTarget = DB.createChild(sRootMapping);
    	DB.copyNode(nodeSource, nodeTarget);
    	
    	local aDelete = {};
    	local sTargetNPCList = LibraryData.getCustomData("battle", "npclist") or "npclist";
    	for _,nodeNPC in pairs(DB.getChildren(nodeTarget, sTargetNPCList)) do
    		local sExpr = DB.getValue(nodeNPC, "expr", "");
    		DB.deleteChild(nodeNPC, "expr");
    		
    		sExpr = sExpr:gsub("$PC", tostring(PartyManager.getPartyCount()));
    		
    		local nCount = StringManager.evalDiceMathExpression(sExpr);
    		DB.setValue(nodeNPC, "count", "number", nCount);
    		if nCount <= 0 then
    			table.insert(aDelete, nodeNPC);
    		end
    	end
    	for _,nodeDelete in ipairs(aDelete) do
    		nodeDelete.delete();
    	end
    	DB.setValue(nodeTarget, "locked", "number", 1);
    
    	if CampaignDataManager2 and CampaignDataManager2.onEncounterGenerated then
    		CampaignDataManager2.onEncounterGenerated(nodeTarget);
    	end
    	
      return nodeTarget;
    end
    
    function addLinkToBattle(nodeBattle, sLinkClass, sLinkRecord, nCount)
    	local sTargetNPCList = LibraryData.getCustomData("battle", "npclist") or "npclist";
    
    	if sLinkClass == "battle" then
    		local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
    		for _,nodeSrcNPC in pairs(DB.getChildren(DB.getPath(sLinkRecord, sTargetNPCList))) do
    			local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
    			DB.copyNode(nodeSrcNPC, nodeTargetNPC);
    			if nCount then
    				DB.setValue(nodeTargetNPC, "count", "number", DB.getValue(nodeTargetNPC, "count", 1) * nCount);
    			end
    		end
    
    -- new bit here
      elseif sLinkClass == "battlerandom" then
        local nodeRandomEncounter = DB.findNode(sLinkRecord);
        local nodeGeneratedEncounter = generateEncounterFromRandom(nodeRandomEncounter);
    
        -- normal battle entry stuff... copied from above
        local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
        for _,nodeSrcNPC in pairs(DB.getChildren(DB.getPath(nodeGeneratedEncounter.getPath(), sTargetNPCList))) do
          local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
          DB.copyNode(nodeSrcNPC, nodeTargetNPC);
          if nCount then
            DB.setValue(nodeTargetNPC, "count", "number", DB.getValue(nodeTargetNPC, "count", 1) * nCount);
          end
        end
    -- new bit ends here
    
      else
        local bHandle = false;
    		local sLinkSourceType = NPCManager.getNPCSourceType(sLinkRecord);
    		if sLinkSourceType == "npc" then
    			bHandle = true;
    		else
    			local aCombatClasses = LibraryData.getCustomData("battle", "acceptdrop") or { "npc" };
    			if StringManager.contains(aCombatClasses, sLinkSourceType) then
    				bHandle = true;
    			elseif StringManager.contains(aCombatClasses, sLinkClass) then
    				ChatManager.SystemMessage(Interface.getString("battle_message_wrong_source"));
    				return false;
    			end
    		end
    
    		if bHandle then
    			local sName = DB.getValue(DB.getPath(sLinkRecord, "name"), "");
    
    			local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
    			local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
    			DB.setValue(nodeTargetNPC, "count", "number", nCount or 1);
    			DB.setValue(nodeTargetNPC, "name", "string", sName);
    			DB.setValue(nodeTargetNPC, "link", "windowreference", sLinkClass, sLinkRecord);
    			
    			local nodeID = DB.getChild(sLinkRecord, "isidentified");
    			if nodeID then
    				DB.setValue(nodeTargetNPC, "isidentified", "number", nodeID.getValue());
    			end
    			
    			local sToken = DB.getValue(DB.getPath(sLinkRecord, "token"), "");
    			if sToken == "" or not Interface.isToken(sToken) then
    				local sLetter = StringManager.trim(sName):match("^([a-zA-Z])");
    				if sLetter then
    					sToken = "tokens/Medium/" .. sLetter:lower() .. "[email protected] Tokens";
    				else
    					sToken = "tokens/Medium/[email protected] Tokens";
    				end
    			end
    			DB.setValue(nodeTargetNPC, "token", "token", sToken);
    		else
    			return false;
    		end
    	end
    	
    	return true;
    end
    Last edited by celestian; November 28th, 2021 at 08:47.
    ---
    Fantasy Grounds AD&D Content Bundle (All The AD&D Content)
    Documentation for AD&D 2E ruleset.
    My Twitch Channel for AD&D and FG related streams (See schedule for live days)
    My YouTube for FG related Tutorials and AD&D Actual Plays
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  6. #56
    That sounds reasonable. But, why create the intermediate encounter at all? Why not just add the random counts directly to the encounter you are dropping on?

    JPG

  7. #57
    Quote Originally Posted by Moon Wizard View Post
    That sounds reasonable. But, why create the intermediate encounter at all? Why not just add the random counts directly to the encounter you are dropping on?

    JPG
    Good point It was a quick and dirty 10-20 minutes test to see if the basic model would work.
    ---
    Fantasy Grounds AD&D Content Bundle (All The AD&D Content)
    Documentation for AD&D 2E ruleset.
    My Twitch Channel for AD&D and FG related streams (See schedule for live days)
    My YouTube for FG related Tutorials and AD&D Actual Plays
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  8. #58

    ActionSkill.getUnlistedRoll double NPC modifier

    In the 5E ruleset, ActionSkill.getUnlistedRoll doubles the modifier for skill rolls. This does not typically show up because this function is only called from the party sheet roll code. A PC that is calling this will inherently have a modifier of 0 because all the built in rolls are required on the sheet. However, if you pass an NPC to this function because it did not have a specific roll for the skill, it will grab the stat needed for the skill roll and then add it in two different places.

    Only dealing with nMod once fixes this issue. (As a note, this happens in the current version and test version.)

    Code:
    function getUnlistedRoll(rActor, sSkill)
    	local rRoll = {};
    	rRoll.sType = "skill";
    	rRoll.aDice = { "d20" };
    	
    	local nMod = 0;
    	local bADV = false;
    	local bDIS = false;
    	local sAddText = "";
    	
    	local sAbility = nil;
    	if DataCommon.skilldata[sSkill] then
    		sAbility = DataCommon.skilldata[sSkill].stat;
    	end
    	if sAbility then
    		nMod, bADV, bDIS, sAddText = ActorManager5E.getCheck(rActor, sAbility, sSkill);
    	end
    --nMod added here
    	rRoll.nMod = nMod;
    	
    	rRoll.sDesc = "[SKILL] " .. sSkill;
    	if sAddText and sAddText ~= "" then
    		rRoll.sDesc = rRoll.sDesc .. " " .. sAddText;
    	end
    	if nMod and nMod ~= 0 then
    		rRoll.sDesc = rRoll.sDesc .. string.format(" [%+d]", nMod);
    --nMod added here again
    		rRoll.nMod = rRoll.nMod + nMod;
    	end
    	if bADV then
    		rRoll.sDesc = rRoll.sDesc .. " [ADV]";
    	end
    	if bDIS then
    		rRoll.sDesc = rRoll.sDesc .. " [DIS]";
    	end
    
    	return rRoll;
    end

  9. #59
    Quote Originally Posted by Moon Wizard View Post
    That sounds reasonable. But, why create the intermediate encounter at all? Why not just add the random counts directly to the encounter you are dropping on?

    JPG
    This seems to work, generates random encounters directly, without the encounter middle man.

    Code:
    --[[
      Replacement function to add support for battlerandom in tables
    ]]
    function addLinkToBattle(nodeBattle, sLinkClass, sLinkRecord, nCount)
    	local sTargetNPCList = LibraryData.getCustomData("battle", "npclist") or "npclist";
    
    	if sLinkClass == "battle" then
    		local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
    		for _,nodeSrcNPC in pairs(DB.getChildren(DB.getPath(sLinkRecord, sTargetNPCList))) do
    			local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
    			DB.copyNode(nodeSrcNPC, nodeTargetNPC);
    			if nCount then
    				DB.setValue(nodeTargetNPC, "count", "number", DB.getValue(nodeTargetNPC, "count", 1) * nCount);
    			end
    		end
      --- added this to support random encounter in tables
      elseif sLinkClass == "battlerandom" then
        -- get the random encounter node
        local nodeRandomEncounter = DB.findNode(sLinkRecord);
        local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
        local aDelete = {};
        -- flip through npcs in the random encounter and make copy
        for _,nodeNPC in pairs(DB.getChildren(nodeRandomEncounter, sTargetNPCList)) do
          local sExpr = DB.getValue(nodeNPC, "expr", "");
          local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
          DB.copyNode(nodeNPC, nodeTargetNPC);
          DB.deleteChild(nodeTargetNPC, "expr");
          sExpr = sExpr:gsub("$PC", tostring(PartyManager.getPartyCount()));
          
          --figure out count of npcs
          local nCount = StringManager.evalDiceMathExpression(sExpr);
          DB.setValue(nodeTargetNPC, "count", "number", nCount);
          if nCount <= 0 then
            table.insert(aDelete, nodeTargetNPC);
          end
        end
        -- if any of the npc count ended up being 0 or less we delete them
        for _,nodeDelete in ipairs(aDelete) do
          nodeDelete.delete();
        end
        -- end of random encounter table support
      else
        local bHandle = false;
    		local sLinkSourceType = NPCManager.getNPCSourceType(sLinkRecord);
    		if sLinkSourceType == "npc" then
    			bHandle = true;
    		else
    			local aCombatClasses = LibraryData.getCustomData("battle", "acceptdrop") or { "npc" };
    			if StringManager.contains(aCombatClasses, sLinkSourceType) then
    				bHandle = true;
    			elseif StringManager.contains(aCombatClasses, sLinkClass) then
    				ChatManager.SystemMessage(Interface.getString("battle_message_wrong_source"));
    				return false;
    			end
    		end
    
    		if bHandle then
    			local sName = DB.getValue(DB.getPath(sLinkRecord, "name"), "");
    
    			local nodeTargetNPCList = DB.createChild(nodeBattle, sTargetNPCList);
    			local nodeTargetNPC = DB.createChild(nodeTargetNPCList);
    			DB.setValue(nodeTargetNPC, "count", "number", nCount or 1);
    			DB.setValue(nodeTargetNPC, "name", "string", sName);
    			DB.setValue(nodeTargetNPC, "link", "windowreference", sLinkClass, sLinkRecord);
    			
    			local nodeID = DB.getChild(sLinkRecord, "isidentified");
    			if nodeID then
    				DB.setValue(nodeTargetNPC, "isidentified", "number", nodeID.getValue());
    			end
    			
    			local sToken = DB.getValue(DB.getPath(sLinkRecord, "token"), "");
    			if sToken == "" or not Interface.isToken(sToken) then
    				local sLetter = StringManager.trim(sName):match("^([a-zA-Z])");
    				if sLetter then
    					sToken = "tokens/Medium/" .. sLetter:lower() .. "[email protected] Tokens";
    				else
    					sToken = "tokens/Medium/[email protected] Tokens";
    				end
    			end
    			DB.setValue(nodeTargetNPC, "token", "token", sToken);
    		else
    			return false;
    		end
    	end
    	
    	return true;
    end
    ---
    Fantasy Grounds AD&D Content Bundle (All The AD&D Content)
    Documentation for AD&D 2E ruleset.
    My Twitch Channel for AD&D and FG related streams (See schedule for live days)
    My YouTube for FG related Tutorials and AD&D Actual Plays
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  10. #60
    @srmccarty,
    I pushed update to fix that in beta version of 5E ruleset.

    @celestian,
    I added the random encounter link drop to encounter support in the latest beta version of CoreRPG.

    Regards,
    JPG

Thread Information

Users Browsing this Thread

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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
PF2E Playlist

Log in

Log in