I understand most of what you've said (not all, especially the syntax of that code unless it's meant to be definined by making special structures as operators for the class
If that was to me (sorry, been offline a couple of days, just catching up) then it's not
actual code, in that example, it's just something that's reasonably human-readable/writable (for ease of maintenance by yourself, mainly) that can be machine-read to enact. You make it any way you wanted, and it'd work like the Raws-parsing bit within DF that "builds an entity" from its body-plan and abilities and other qualities. (You may be hard-coding the weapon qualities and special abilities within the code, or importing from a file, but either way you'd be working with that textually.)
So, "Dam==Cold:Armour-5" is just text. Your code goes "There's something to parse..." splits between cause ("Dam==Cold") and effect ("Armour-5") through simple regexp or similar manipulation and then checks to see what the cause consists of. How you implement it is up to you, but the keyword "Dam"(age) gets interpreted for its various qualities, in each combat round that the weapon (or armour or whatever it is that has this quality) is being used. I haven't tried to check to see if the rest of your published code might give clues to this, but let's just say that in any given round the "Dam" information includes how much, who from, with what weapon/spell/trap/whatever, and (for the purposes of the above example) any elemental alignment that it has.
The parser you write (I'm leaving a
lot of this up to you) will decide that as it is an equality check with the word "Cold", then it checks the true/false condition on Damage.Element="Cold", or whatever might work in your situation. If it had been "Dam==Orc" then it's receptive towards the Damage.GivenBy (or equivalent) having a value equating with (or including, among other information) an Orc character. "Dam<50" might interrogate the quantity of damage given, and the parser activates the effect condition only when the damage received is less than (in this case) a value of 50.
If the parser's processing reveals it to be a match, then the effect side is looked at. In the above example, the effective armour value (for this round only, i.e. due to this particular strike against it) is reduced by five. As a concept, this represents a weapon that, when attacked by cold-based offensiveness (everything from an icy blast from a wand to being stabbed with an icicle?) acts as a conduit to that kind of attack and thus makes your armour less effective than it is against mundane attacks, or heat-based ones, or water-based ones, etc, etc... For whatever reason. Or so I (think) I envisaged that quality.
It could as easily be parsed (should you set it up as such) as a
permanent armour adjustment, indicating damage
to the armour (spread over the items involved, or applied to one/some of the relevant items?), to the value of five. Or you might prefer that to be represented as "Armour--5" or "Armour=-5", as what text should be parsed to do that. It's totally up to you. (Also consider "Armour.Temp-5" against "Armour-5" so that the "-5" adjustment gets applied to a temporary (during this round's calculations only) armour variable, in the former, while the latter adjusts the situation globally, as appropriate...
But it's a made-up example. And whatever it looks like "inside the code" (could be more easily readable, or less so), it could be reconstructed in that form from a
completely separate RAWs-like or XML-like external configuration file, with yet another format, and yet another parser validating (very importantly!) and then re-encoding the desired effects in the internally-handled method. Which could be to create a reference to a function. I could show you several ways of doing this in Perl, but I'm not sure that they'd translate so easily to whatever C-variant you're using (whatever that is, again, I forget).
Oh, go on then... Without any trying of this out, just writing it out on-spec, the test-function creator might look like:
sub CreateDamageCheck { # Called whenever a cause of "Dam==something", or other relational variant, is detected
my ($rel,$qual) = @_; my $test;
if ($qual=~m/^\d+$/) { # If the quality matches a pure number
return sub { my ($refDamage) = @_; # $refDamage is for an elsewhere-defined reference to a hash about Damage
$val = ${$refDamage}{"Amount"}; # I sometimes get the {}s wrong in hashreferences, this may be such an occasion!
if ($rel eq "==") {return $val==$qual}
if ($rel eq "!=") {return $val!=$qual} # this sort of thing, for other relationships... could be neater...
} # END return sub (for damage comparison)
} # END if $qual is numeric
if (exists($elemental{$qual})) { # member of (more-)globally defined hash of defined elemental types!
return sub { my ($refDamage) = @_; # $refDamage is for an elsewhere-defined reference to a hash about Damage
$val = ${$refDamage}{"Element"}; # I sometimes get the {}s wrong in hashreferences, this may be such an occasion!
if ($rel eq "==") {return $val eq $qual}
if ($rel eq "!=") {return $val ne $qual} # Blah-de-blah
} # END return sub (for elemental comparison)
} # END if $qual is elemental
# ...Ditto for checks of $qual against other criteria (although already I can see repeated code that can surely be streamlined!)
} # END sub CreateDamageCheck
So, on getting a "Dam==Cold" match, you'd extract the "==" and "Cold" (may need to do something about case) and effectively set something that was:
my $check = CreateDamageCheck("==","Cold")
This would(/should, subject to me getting it right!) give a $check that was a reference to an otherwise anonymous function that you could call as:
&$check(\%RoundDamage)
at every point that the item with this $check stored within it[1] is called. If it returns a true value, then the &$result() that you created in a similar manner would be called, either acting on combat variables globally within the current scope (bad idea?) or being passed its own \%Whatever full of data (and references of data) to the current combat situation.
But, as I said, this is an untested and on-spec answer, based upon a vague original suggestion, being demonstrated within a language that is
not your particular variant of the C-family, and being written without reference to
any of your other data structures... And, like I said, I'm procedurally/functionally/data-orientated, by various degrees, whereas I know your stuff is object-orientated... So there's an additional sticking point of translation.
(Hmm, not sure if this is a helpful reply at all, then... Probably not.)
[1] Probably you'd take the [$check,$result] two-element array ($result having come from a similar function-creating process to parse the effect string) and stack this cause-and-affect pairing (as well as all others) in the array that is referenced under "special effects". Whether you process the special-effects queue until you get a valid effect, or process it all (stacking
all of them) or even engineer a "case/break" possibility, somehow, is up-to-you... Actually, it's up to me, as I realise that I'm explaining what
I'd do, again, and it probably isn't how you (or any other sane person) would do it.