12static float mix(
float x,
float y,
float a) {
19 ret = rangeDamage(src,other,*b,bMsk);
22 ret = rangeDamage(src,other,splDmg,bMsk);
25 ret = swordDamage(src,other);
34 auto gl = npc.
guild();
35 auto& g = npc.
world().script().guildVal();
38 float fallTime = speed/gravity;
39 float height = 0.5f*std::abs(gravity)*fallTime*fallTime;
40 float h0 = float(g.falldown_height[gl]);
41 float dmgPerMeter = float(g.falldown_damage[gl]);
46 ret.
value = int32_t(dmgPerMeter*(height-h0)/100.f -
float(prot));
58 bool invincible = !checkDamageMask(nsrc,nother,&b);
62 auto& script = nsrc.
world().script();
63 float hitChance = float(script.rand(100))/100.f;
71 hitCh =
mix(1.f, chance, (dist / refRange));
72 else if(dist<maxRange)
73 hitCh =
mix(chance, 0.f, (dist-refRange) / (maxRange-refRange));
77 noHit = (dist>float(
MaxBowRange) || hitCh<=hitChance);
79 if(!g2 && !noHit && !invincible) {
80 const int32_t mul = script.criticalDamageMultiplyer();
81 const int critChance = int(script.rand(100));
82 if(std::lround(100.f * b.
critChance())>critChance)
88 return Val(0,
false,invincible);
91 return Val(0,
true,
true);
94 return Val(0,
true,
true);
96 return rangeDamage(nsrc,nother,dmg,bMsk);
100 auto& other = nother.
handle();
108 bool invincible =
true;
109 for(
unsigned int i=0; i<zenkit::DamageType::NUM; ++i) {
110 if(dmg[
size_t(i)]==0)
112 int vd = std::max(dmg[
size_t(i)] - other.protection[i],0);
113 if(other.protection[i]>=0) {
119 return Val(value,
true,invincible);
123 if(!checkDamageMask(nsrc,nother,
nullptr))
124 return Val(0,
true,
true);
126 auto& script = nsrc.
world().script();
127 auto& src = nsrc.
handle();
128 auto& other = nother.
handle();
134 int critChance = int(script.rand(100));
138 if(
auto w = nsrc.
inventory().activeWeapon()) {
150 bool invincible =
true;
151 for(
unsigned int i=0; i<zenkit::DamageType::NUM; ++i) {
152 if((dtype & (1<<i))==0)
154 int vd = std::max(str + src.damage[i] - other.protection[i],0);
155 if(src.hitchance[tal]<=critChance)
157 if(other.protection[i]>=0) {
163 return Val(value,
true,invincible);
165 bool invincible =
true;
166 const int32_t mul = script.criticalDamageMultiplyer();
167 for(
unsigned int i=0; i<zenkit::DamageType::NUM; ++i) {
168 if((dtype & (1<<i))==0)
172 vd = std::max(str + src.damage[i] - other.protection[i],0);
else
173 vd = std::max(str + mul*src.damage[i] - other.protection[i],0);
174 if(other.protection[i]>=0) {
180 return Val(value,
true,invincible);
185 if(
auto w = npc.
inventory().activeWeapon())
186 return w->handle().damage_type;
187 return npc.
handle().damage_type;
190bool DamageCalculator::checkDamageMask(
Npc& nsrc,
Npc& nother,
const Bullet* b) {
191 auto& other = nother.
handle();
195 for(
unsigned int i=0;i<zenkit::DamageType::NUM;++i) {
196 if(dmg[
size_t(i)]>0 && other.protection[i]>=0)
201 for(
unsigned int i=0;i<zenkit::DamageType::NUM;++i){
202 if((dtype & (1<<i))==0)
215 for(
unsigned int i=0;i<zenkit::DamageType::NUM;++i){
216 if((dtype & (1<<i))==0)
218 ret[size_t(i)] = d + src.
handle().damage[i];
auto damage() const -> const DamageCalculator::Damage &
static auto rangeDamageValue(Npc &src) -> Damage
static Val damageValue(Npc &src, Npc &other, const Bullet *b, bool isSpell, const DamageCalculator::Damage &splDmg, const CollideMask bMsk)
static Val damageFall(Npc &src, float speed)
static int32_t damageTypeMask(Npc &npc)
static constexpr float gravity
auto version() const -> const VersionInfo &
int32_t protection(Protection p) const
int32_t talentValue(Talent t) const
int32_t attribute(Attribute a) const
auto inventory() const -> const Inventory &
static float mix(float x, float y, float a)