PDA

View Full Version : How To Create Damage Resistance PER ROUND for DCC Ruleset



leozelig
September 2nd, 2018, 23:04
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!

Moon Wizard
September 2nd, 2018, 23:52
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

celestian
September 3rd, 2018, 02:33
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.

leozelig
September 3rd, 2018, 02:55
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!

celestian
September 3rd, 2018, 05:28
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 ;)




function getAbsorbedByType(rTarget,aSrcDmgClauseTypes,sRang eType,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.

leozelig
September 3rd, 2018, 16:32
Ok, I can make sense of that - thanks, celestian!