|
-
Critical damage formula question Gothic 2 Night of Raven
I just wanted to remake the whole damage functions in the game, so, I started to search the forum to get some informations. I found something, I can use this script to remake the whole damage system. I know that the formula for weapons is damage = (weaponDamage + strength - armor - 1)/10 if it's melee weapon, and damage = (weaponDamage + dexterity - armor - 1) if it's ranged weapon. The critical strike is applied only for melee weapons and the formula is damage = (weaponDamage + strength - armor - 1). Now there's the question, how is the condition of critical damage framed? As if (Hlp_Random(101) <= npc.hitchance) or is it any other formula? I am not sure about it and I don't want to destroy the system by applying two crits by one hit or any other trash, so I chose to ask you guys for help.
-
I think that the possibility of a critical hit depends only on your ability with that weapon. So 50% of OH ability makes you have 50% of critical hit. This is only a supposition based on my gaming experience, more over if you use lehona's script that hooks *every* damage (so also possible critical hits), you should not risk any double critical.
I wait for someone more expert than me to answer, but in the mean you could try some easy tests with the script you wrote.
-
I know how does crit work in Gothic, I just want to remake it... But the reason I can't is I don't know the formula, and I guess I'll need to make a condition like this if no one will know it:
Code:
if (dmg > myDamageVariable)
{
dmg = myDamageVariable*2;
};
-
I thought you already have all the formulas in your first post?
As far as I know, the talent values really do give you the percentage chance of critical hits. You might want to check whether npc.hitchance really contains the right value or whether you need to distinguish the weapon and look at the talent values.
I also don't know whether the engine uses the Hlp_Random(101) function to figure out whether a particular hit was critical, but at least something like it, I guess. Hlp_Random(101) is supposedly not really uniform - lower values are more likely than higher values. I never bothered to find out whether this is (a) true and (b) how large the effect is. You might find another random number generator somewhere in the forum or wiki, I vaguely remember seeing one.
-
Well, the only thing I need to is the engine function for crits. I don't need any number generators. Just a little "if" that tells us if the hit will be / is / was a crit, the "if" that engine uses. Maybe Lehona will know something about it. As far as I know, he/she found out the damage formula from Gothic engine.
-
Well, maybe I understood what you mean. Since the InitDamage function works whenever a damage is done, you could just works on that. instead of wondering whether the original damage was critical or not.
Someone corrects me if I am wrong but something like this should work fairly good, shouldn't it?
Code:
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg)
{
var C_NPC att = Hlp_GetNpc(attackerPtr);
var C_NPC vic = Hlp_GetNpc(victimPtr);
var C_ITEM wpn = Npc_GetReadiedWeapon(att);
var C_ITEM arm = Npc_GetEquippedArmor(vic);
var int str = att.attribute[4];
dmg = yourformulafunction(wpn, str, arm);
if(r_Max(101) <= att.hitchance) // dont remember the exact variable
{
dmg = dmg * 2;
}
return dmg;
}
-
I made it also as you posted, Frank-95, but I am not sure if it is the correct thing, because I spot sometimes it deals more damage than intended. Well, a bit later I'll try a if (dmg > myFormula) { dmg = myformula*2; };, maybe this will work for sure.
-
What do you actually WANT to do?
The variable dmg in the function already gives you the damage that Gothic calculated (if you don't overwrite it). If you don't want to change the damage calculated by Gothic, then simply don't overwrite dmg but return it as it is.
You could, of course, check whether dmg corresponds to the formula of a normal strike or to the formula of a critical strike. In the latter case you know that Gothic thought it was critical.
Alternatively, you just determine yourself what damage you want to deal and whether a strike is critical - after all, it does not really matter whether you or "the game" determine critical strikes.
For some reason I feel like I remember problems with Hlp_Random(x) directly in the if-condition. You might try to first assign it to a variable and then use the variable in the comparison. (I wouldn't know why the original should be problematic though.)
About incorrect damage:
- According to the formulas you posted yourself, a critical strike is NOT "normal strike * 2"
- Be aware that (weaponDamage + strength - armor - 1) may well be negative
- Gothic uses a minimum damage that is always dealt with successful strikes, defined by a constant in the normal scripts. (set to 5 in the original game)
-
I know, dude.
I just want to change the damage = (weaponDamage + strength - armor - 1)/10 to my own formula (for example damage = (weaponDamage * strength / armor)) and change the critical strike from damage = (weaponDamage + strength - armor - 1) to damage = (weaponDamage * strength / armor)*2. This is all I want to do.
Also, the damage calculations are "if (dmg < 5) { dmg = 5; };" where 5 is a variable in Constants.d (if I remember correctly) that is the minimal amount of damage that can be dealt in Gothic, so it's impossible to hit less than 5 (even if the formula is 100 + 40 - 200).
BTW, I said at start of the topic:
 Zitat von Abuyin Sharidi
I just wanted to remake the whole damage functions in the game...
-
I really don't get what the problem is. The hitchances (for melee weapons) are directly related to the chance that you will score a critical strike. In fact, that's their only use (besides changing the fighting style at 30%/60%.).
If you want a better random number generator, LeGo provides one.
-
 Zitat von Abuyin Sharidi
I just want to change the damage = (weaponDamage + strength - armor - 1)/10 to my own formula (for example damage = (weaponDamage * strength / armor)) and change the critical strike from damage = (weaponDamage + strength - armor - 1) to damage = (weaponDamage * strength / armor)*2. This is all I want to do.
That should be a relatively easy function to write then - all the necessary parts are in this thread already. If you are experiencing problems, the only way we can be of further help is when you show your actual code.
-
I am not sure about it and I don't want to destroy the system by applying two crits by one hit or any other trash, so I chose to ask you guys for help.
Maybe I understood. Do you think that the chance of a critical hit in gothic and in initdamage may add one another?
The fact is that initdamage hooks the whole damage, so it really doesn't matter if the actual hit was critical or not. So the code is the same of before. You just call two different function normalhit or criticalhit according to chance
-
 Zitat von Milky-Way
That should be a relatively easy function to write then - all the necessary parts are in this thread already. If you are experiencing problems, the only way we can be of further help is when you show your actual code.
Yea, it is easy, but if I overwrite the dmg function from engine (by initDamage function) the crit will be always the same as it was before, I mean, if my new damage formula will be damage = (weaponDamage * strength / armor), the critical strike will deal damage = (weaponDamage * strength / armor)*10 damage, does not it? The normal Gothic damage script is devided by 10 if it's not a critical hit, if it is, the damage is damage = (weaponDamage + strength - armor - 1).
Practical version:
old damage function is:
damage = (weaponDamage + strength - armor - 1)*10
if crit
damage = (weaponDamage + strength - armor - 1)
New damage function is:
damage = (weaponDamage * strength / armor)
if crit it will be damage = (weaponDamage * strength / armor)*10
and I want to be damage = (weaponDamage * strength / armor)*2.
Don't know how to explain it easier...
-
I think the dmg that you get in the function already is the final damage. Gothic does NOT multiply it afterwards in case of a critical hit but beforehand. Whatever you return is the damage dealt - hence you can just set dmg to whatever you like (using your normal formula and sometimes your critical hit formula) and then return dmg.
You can easily test it by doing something like
Code:
Print(IntToString(dmg));
right at the start of the function and then fighting to see what is printed on the screen in case of normal and critical hits. (you could also first ask whether the attacker is the player to filter the output printed on the screen, and then first try with 0% fight talent and then again 100% fight talent to see the difference in the print between normal and critical hit)
If Gothic really does change the damage after the function is called, one idea is to set the damage in your function so that the expected value ends up being the one you want (even though critical hits are still 10 times as strong as normal hits).
Geändert von Milky-Way (09.02.2015 um 21:12 Uhr)
-
And this is the problem, I don't want to have critical hits 10 times stronger, but only 2 times stronger. You said I can change the damage dealt, BUT the critical damage will be always 10 times bigger than the normal (non-critical) hit. I want to completely change the criticals.
-
 Zitat von Abuyin Sharidi
You said I can change the damage dealt, BUT the critical damage will be always 10 times bigger than the normal (non-critical) hit. I want to completely change the criticals.
Are you completely sure that this really happens?
My claim is that whatever you return from the function is the final damage dealt. No multiplication afterwards by the game. The game already calculates the critical hit beforehand and the argument dmg is correspondingly higher in case of a critical hit. But you can overwrite nevertheless, of course. Note: I did not test it, but I think what I described is the expected and intended effect of Lehona's script.
In case the script really does behave strangely (i.e. not in the way I described above), I see two options:
- ensuring that the expected value of the damage is as you want it to be. Actual damage on individual hits will be different, but overall / on average it is the same (of course there can be small differences since hitpoints are bounded). This will result in pretty much the balancing that you want to achieve. (And, after all, that is the ultimate goal, isn't it?)
- you set the talent values to either 0 or 100 and use other / own variables for display in menus, learn costs, calculations in your damage script. That way you know that the game will never / always post-multiply your value by 10.
(Personally I prefer the first option, but that is likely due to my background in statistics. It does require fewer changes in the code though.)
-
I'm pretty sure my script changes the value right before it's passed to Npc_ChangeAttribute, so whatever dmg-value you set, will be applied. At this point, there is no such thing as a critical strike - if there was one, the game has already multiplied the "normal" damage value by 10.
Of course that is something you could have tested yourself within a couple of minutes... 
Edit: Just confirmed it in IDA to make sure.
Geändert von Lehona (09.02.2015 um 21:46 Uhr)
-
So, as I understood you both, Milky-Way and Lehona, if I write in the damage script my formula, the damage will be always the same?
I mean, if I write damage = (weaponDamage * strength / armor), then the crit will be the same? There'll be no modification or multiplication by the game on its own?
-
Yes. Whatever you return from the function is the damage that will be dealt. No multiplication by the game afterwards.
-
So I can freely now deconstruct the Gothic damage. Thank you all for helping me. If I'll spot some problems I'll inform in here (but as you checked it it should have no prejudices).
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|