Add better damage conversion (bad code inside)

All new ideas for the upcoming releases of ToME 4.x.x should be discussed here

Moderator: Moderator

Post Reply
Message
Author
Umbrall
Thalore
Posts: 153
Joined: Sat Feb 23, 2013 7:53 pm

Add better damage conversion (bad code inside)

#1 Post by Umbrall »

In short, add a list that can convert any elements to any other elements:
like {DT.FIRE = {DT.ACID = 0.75}} EDIT: I don't know how arrays work, I thought that these constants were numbers but something like this, perhaps by name as I had done it elsewhere. A second array stores damage types not to convert to
This is useful for addon developers to be able to properly convert damage without superloading (which is bad) and generalizes the fire damage convert of the alchemist (also allowing it to stack to a degree). And it can make cool artifacts or skills that convert damage types.

Not guarenteed to compile or be correct, this does not perfectly handle conversion sums over 100%, which could be done by normalizing the sum. This does it by ignoring damage over the base in an undefined order.
This code is definitely incorrect probably.

Code: Select all

if src.convert_damage[typ] then
	local dam_base = dam
	local add_dam = 0
	for new_type, frac in pairs(src.convert_damage[typ]) do
		if not src.no_convert[new_type] then
			dam = math.max(dam - frac * dam_base, 0)
			old_no_convert = src.no_convert[new_type] = true
			src.no_convert[new_type] = true
			add_dam = add_dam + DamageType:get(new_type).projector(src, x, y, new_type, math.max(dam_base * frac, dam), tmp, no_martyr)
			src.no_convert = old_no_convert
		end
	end
	if (dam <= 0) then return add_dam end
end

nate
Wyrmic
Posts: 261
Joined: Fri Jan 18, 2013 8:35 am

Re: Add better damage conversion (bad code inside)

#2 Post by nate »

Damage type conversion is a cool idea, but with the game's current structure, it's really got to be a case by case basis. Damage types are really open format, and they rely on various elements being passed to them in a damage table. Rather than being generated in one way, this damage table is generated at each instance by the calling instance. As an example, consider upgrading LIGHTNING damage to LIGHTNING_DAZE damage-- LIGHTNING_DAZE requires a field in its damage table called "daze", whereas LIGHTNING won't even work if it's sent a table. Conversion between simple types (that don't receive a damage table) is possible, but I think as you've seen, it can be added individually by addons-- replace the convertible damage types with a damage type that does a check for replacement, and send your data to the appropriate projector. If you're in full control of the types of damage that you want converted, you can instead just send those damage types to a proxy damage type.

If I were going to build damage type conversion in to the ToME engine, I'd want to go whole hog-- generate consistent damage tables that had EVERYTHING ever needed, in an easily hooked or superloaded function, and send them to EVERY damage type, to allow full conversion. A task like that would be possible, but it would be a lot of tedious work; it would probably work by sending a source, weapon, and talent (maybe some other stuff) with every damage type, and modifying every existing damage type to work from these values instead of what it's sent in its damage table, along with dealing with outside cases when it couldn't find what it needed in any of the parameter tables (like if a projectile was shot by a launcher that has been destroyed in the time between the projectile's launch and the projectile's hit-- it's hard to predict exactly how many weird cases like this might exist).

As an alternative, data/damage_types.lua could definitely stand to be made more friendly to add-ons. The damage types can be overloaded, but not easily superloaded, which isn't as big of a deal as the fact that the default damage projector is one huge monolithic function returned by a local function-- really hard to modify without replacing it and the entire list of damage projectors, which breaks compatibility between add-ons: only one add-on at a time can get away with doing that. Moving this function to its own module would be an easy start; the best solution would involve breaking it up into many individual component functions (which would likely improve readability at the same time). Similarly, making projector calls accessible (importantly, replaceable, superloadable) from outside of the calls to newDamageType would allow superloading of these, allowing, say, two different damage-conversion add-ons to play nicely with each other.

At least, that's how I see it-- there may be ways to do this that haven't occurred to me.

edit: and if i was going to do all that, i'd be tempted to go whole hog and revise the wording of calls to the damageprojector: "subject:damage(object, dam, 'physical', {pA, pB, pC})" would sure be a nice way to be able to call these.
Proud father of Fx4fx and Chronometer add-ons; proud mother of Fated add-on

Umbrall
Thalore
Posts: 153
Joined: Sat Feb 23, 2013 7:53 pm

Re: Add better damage conversion (bad code inside)

#3 Post by Umbrall »

Actually, can we just get the damage funciton to stop when the hook returns 0 damage, and to pass no_martyr and temp. Because it's really annoying to convert all of something and have it show up as zero, and more annoying to have to guess whether it should have thorn stuff or not.

Post Reply