FG Spreadshirt Swag
  1. #1
    leozelig's Avatar
    Join Date
    Jun 2007
    Location
    Eastern USA
    Posts
    1,856
    Blog Entries
    1

    How To Create Damage Resistance PER ROUND for DCC Ruleset

    Damage resistance in DCC works a little different than D&D. If you have the 'RESIST: 5 fire' effect, your PC resists the first 5 hp of fire damage per round (not per attack), which resets at the beginning of each new round. The current code functions according to D&D rules, but I would love to get this working properly for the DCC ruleset. Does anyone know of an existing ruleset with a similar mechanic that I can use as a guide. Really any function that resets at the beginning of each new combat round would be helpful.

    Thanks!

  2. #2
    As a simpler implementation, you might be able to have the damage code set the Skip flag on the effect when the resistance is applied; but this wouldn't handle partials. It would just apply the resistance to the first damage roll with that type, then turn off the effect until the start of the PC round.

    For full support options:

    * You could add per combatant, per round tracking of resistance applied in a separate set of variables that get reset on turn advancement. The drawback to this option is that there is no way to reset the resistances used other than turn advancement (if needed at all). Also, you have to decide whether adding/removing effects has an impact as well.

    * Another option would be to embed the amount of resistance used in the resistance effect text (i.e. RESIST: 5; USEDRESIST: 3), and then remove the extra embedded usage tags on turn advancement. There is a slightly similar mechanic used for recharge in 4E/5E, but not exactly the same.

    Regards,
    JPG

  3. #3
    I did some updates to AD&D Core that allows you to track absorb of damage of a specific type and track it. The same thing could be used to track resists. You'd need to come up with a way to refresh it per round but it would work to "expire" when 5 damage is absorbed.

    If it sounds useful let me know and I'll point you at the specifics in the code.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    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.

  4. #4
    leozelig's Avatar
    Join Date
    Jun 2007
    Location
    Eastern USA
    Posts
    1,856
    Blog Entries
    1
    Thanks Moon and celestian... I am interested in looking at the specific code for that feature in the AD&D Core ruleset, celestian. Much appreciated!

  5. #5
    Quote Originally Posted by leozelig View Post
    Thanks Moon and celestian... I am interested in looking at the specific code for that feature in the AD&D Core ruleset, celestian. Much appreciated!
    The specific function that manages most of it is here:

    manager_action_damage.lua

    function getAbsorbedByType(rTarget,aSrcDmgClauseTypes,sRang eType,nDamageToAbsorb)

    This is called in getDamageAdjust(..) and eventually used in applyDamage(..).

    I commented the code pretty so it should be hopefully self explanatory if not poke me


    Code:
    function getAbsorbedByType(rTarget,aSrcDmgClauseTypes,sRangeType,nDamageToAbsorb)
     local nodeTarget = DB.findNode(rTarget.sCTNode);
     local nDMG = nDamageToAbsorb;
     if (nodeTarget) then
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","sRangeType",sRangeType);    
        for _,nodeEffect in pairs(DB.getChildren(nodeTarget, "effects")) do
          local sLabel = DB.getValue(nodeEffect,"label","");
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","sLabel",sLabel);            
          --aSrcDmgClauseTypes
          for _,sDamageType in pairs(aSrcDmgClauseTypes) do 
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","sDamageType",sDamageType);            
            -- we search for "DA: # type" but because [xDx] adds a comma 
            -- for some coreRPG or other thing we also check for "DA: #, type{,type,type}"
            -- I think it comes from rebuildParsedEffectComp(rComp) -- celelstian
            local nStart,nEnd = sLabel:find("DA:%s?%d+%s?,?.*$");
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nStart",nStart);          
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nEnd",nEnd);          
            if nStart ~= nil and nEnd ~= nil then
              local sDALabel = string.sub(sLabel,nStart,nEnd);
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","sDALabel",sDALabel);              
              local sMod,sTypes = sDALabel:match("DA:%s?(%d+)%s?,?(.*)$");
              local nMod = tonumber(sMod) or 0;
              local nRemainder = nMod;
              local aAbsorbDamageTypes = StringManager.split(sTypes, ",", true);
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","aAbsorbDamageTypes",aAbsorbDamageTypes);     
              -- flip through all damage types for this DA
              for _,sType in pairs(aAbsorbDamageTypes) do
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nDMG",nDMG);       
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nMod",nMod);              
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","sType",sType);              
                if (sType and nMod and nMod > 0) then
                  -- absorb if DA sType match incoming Damage type, or type is ALL or the incoming range type (melee|range) match DA sType
                  if (sType == sDamageType or sType == "all" or sRangeType == sType) then
                    if (nDMG > 0) then
                      if (nDMG >= nMod) then
                        nDMG = nDMG - nMod;
                        nRemainder = 0;
                      else
                        nRemainder = (nMod - nDMG);
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nRemainder1",nRemainder);                      
                        nDMG = 0;
                      end
                    end -- nDMG > 0
                     -- if sType ==
                  elseif (sType == 'none') then
                  -- with none type we do not absorb but we track the damage to the 
                  -- bubble and remove it. This allows us to have an effect like the armor
                  -- spell that takes X damage before it expires. "BAC:6;DA: 5 none"
                  -- since the entire effect is removed when DA < 0
                    nRemainder =  (nMod - nDamageToAbsorb);
                  end
                end -- if sType and nMod
              end -- aAbsorbDamageTypes for
              if (nRemainder ~= nMod) then
                if nRemainder > 0 then
                  -- adjust effect nMod to new value, replace old entry value with new
                  local sReplacedLabel = sLabel:gsub(sDALabel,"DA:".. nRemainder .. " " .. sTypes);
                  DB.setValue(nodeEffect,"label","string",sReplacedLabel);
                else
                  -- effect is used up, remove it
                  EffectManager.removeEffect(nodeTarget, sLabel);
                  --nodeEffect.delete();
                end
              end -- nRemainder > 0
            end -- nStart/nEnd ~= nil
          end -- for aSrcDmgClauseTypes
        end -- for "effects"
      end -- if nodeTarget
      
      -- get the difference in amount absorbed and the total damage.
      local nAbsorbed = 0 - (nDMG - nDamageToAbsorb);
    --Debug.console("manager_action_damage.lua","getAbsorbedByType","nAbsorbed",nAbsorbed);      
      return nAbsorbed;
     end
    The end result is you add a "DA: XXX type" effect to a npc/pc and when they take that type of damage it will reduce the damage taken up to the absorb type then into HP. When the amount of absorb hits 0 the effect is removed.

    You'd just need to tweak the logic a bit to allow the effect to hang around or find another way to reset it. Perhaps look for that type of effect each round and if <0 value set it to some predetermined value. Something like "RESIST:10 fire;MAXRESIST: 10" and just pickup the MAXRESIST value and set it. This would mean the effect would need to contain both the MAXRESIST and RESIST values.

    Mind you that's just me spit balling.
    Last edited by celestian; September 3rd, 2018 at 05:33.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    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. #6
    leozelig's Avatar
    Join Date
    Jun 2007
    Location
    Eastern USA
    Posts
    1,856
    Blog Entries
    1
    Ok, I can make sense of that - thanks, celestian!

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
  •  
STAR TREK 2d20

Log in

Log in