forked from NotAShelf/rogged
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ie2f5af13ad3c0392a5e873b15170b0226a6a6964
151 lines
4.1 KiB
Zig
151 lines
4.1 KiB
Zig
const c = @import("c.zig");
|
|
|
|
pub const EffectParams = struct {
|
|
duration: c_int,
|
|
intensity: c_int,
|
|
};
|
|
|
|
pub fn procForClass(dmg_class: c.DamageClass) c.StatusEffectType {
|
|
return switch (dmg_class) {
|
|
c.DMG_SLASH => c.EFFECT_BLEED,
|
|
c.DMG_IMPACT => c.EFFECT_STUN,
|
|
c.DMG_PIERCE => c.EFFECT_WEAKEN,
|
|
c.DMG_FIRE => c.EFFECT_BURN,
|
|
c.DMG_POISON => c.EFFECT_POISON,
|
|
else => c.EFFECT_NONE,
|
|
};
|
|
}
|
|
|
|
pub fn name(effect: c.StatusEffectType) ?[*:0]const u8 {
|
|
return switch (effect) {
|
|
c.EFFECT_POISON => "Poisoned",
|
|
c.EFFECT_BLEED => "Bleeding",
|
|
c.EFFECT_STUN => "Stunned",
|
|
c.EFFECT_BURN => "Burning",
|
|
c.EFFECT_WEAKEN => "Weakened",
|
|
else => null,
|
|
};
|
|
}
|
|
|
|
pub fn paramsFor(effect: c.StatusEffectType) EffectParams {
|
|
return switch (effect) {
|
|
c.EFFECT_BLEED => .{ .duration = 4, .intensity = c.BLEED_STACK_DAMAGE },
|
|
c.EFFECT_STUN => .{ .duration = 2, .intensity = 0 },
|
|
c.EFFECT_WEAKEN => .{ .duration = 3, .intensity = c.WEAKEN_ATTACK_REDUCTION },
|
|
c.EFFECT_BURN => .{ .duration = 2, .intensity = c.BURN_BASE_DAMAGE },
|
|
c.EFFECT_POISON => .{ .duration = 5, .intensity = c.POISON_BASE_DAMAGE },
|
|
else => .{ .duration = 0, .intensity = 0 },
|
|
};
|
|
}
|
|
|
|
pub fn clampCount(count: c_int) usize {
|
|
if (count < 0) return 0;
|
|
if (count > c.MAX_EFFECTS) return @intCast(c.MAX_EFFECTS);
|
|
return @intCast(count);
|
|
}
|
|
|
|
pub fn has(effects: [*c]const c.StatusEffect, count: c_int, effect_type: c.StatusEffectType) bool {
|
|
const safe_count = clampCount(count);
|
|
for (0..safe_count) |i| {
|
|
if (effects[i].type == effect_type and effects[i].duration > 0)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
pub fn apply(
|
|
effects: [*c]c.StatusEffect,
|
|
count: [*c]c_int,
|
|
effect_type: c.StatusEffectType,
|
|
duration: c_int,
|
|
intensity: c_int,
|
|
) void {
|
|
const safe_count = clampCount(count[0]);
|
|
|
|
for (0..safe_count) |i| {
|
|
if (effects[i].type == effect_type and effects[i].duration > 0) {
|
|
if (effect_type == c.EFFECT_BLEED) {
|
|
effects[i].intensity += intensity;
|
|
if (effects[i].duration < duration)
|
|
effects[i].duration = duration;
|
|
} else {
|
|
effects[i].duration = duration;
|
|
if (intensity > effects[i].intensity)
|
|
effects[i].intensity = intensity;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (safe_count < @as(usize, @intCast(c.MAX_EFFECTS))) {
|
|
effects[safe_count] = .{
|
|
.type = effect_type,
|
|
.duration = duration,
|
|
.intensity = intensity,
|
|
};
|
|
count[0] = @intCast(safe_count + 1);
|
|
}
|
|
}
|
|
|
|
fn compact(effects: [*c]c.StatusEffect, count: [*c]c_int) void {
|
|
var write: usize = 0;
|
|
const safe_count = clampCount(count[0]);
|
|
|
|
for (0..safe_count) |read| {
|
|
if (effects[read].duration > 0) {
|
|
if (write != read)
|
|
effects[write] = effects[read];
|
|
write += 1;
|
|
}
|
|
}
|
|
count[0] = @intCast(write);
|
|
}
|
|
|
|
fn tickOne(eff: *c.StatusEffect, hp: *c_int) c_int {
|
|
if (eff.duration <= 0) return 0;
|
|
|
|
var dmg: c_int = 0;
|
|
switch (eff.type) {
|
|
c.EFFECT_POISON, c.EFFECT_BLEED, c.EFFECT_BURN => {
|
|
dmg = eff.intensity;
|
|
hp.* -= dmg;
|
|
},
|
|
else => {},
|
|
}
|
|
eff.duration -= 1;
|
|
return dmg;
|
|
}
|
|
|
|
pub fn tickPlayer(p: [*c]c.Player) c_int {
|
|
if (p == null) return 0;
|
|
|
|
var total: c_int = 0;
|
|
const safe_count = clampCount(p[0].effect_count);
|
|
|
|
for (0..safe_count) |i| {
|
|
total += tickOne(&p[0].effects[i], &p[0].hp);
|
|
}
|
|
|
|
compact(&p[0].effects, &p[0].effect_count);
|
|
return total;
|
|
}
|
|
|
|
pub fn tickEnemy(e: [*c]c.Enemy) c_int {
|
|
if (e == null) return 0;
|
|
if (e[0].alive == 0) return 0;
|
|
|
|
var total: c_int = 0;
|
|
const safe_count = clampCount(e[0].effect_count);
|
|
|
|
for (0..safe_count) |i| {
|
|
total += tickOne(&e[0].effects[i], &e[0].hp);
|
|
}
|
|
|
|
if (e[0].hp <= 0) {
|
|
e[0].hp = 0;
|
|
e[0].alive = 0;
|
|
}
|
|
|
|
compact(&e[0].effects, &e[0].effect_count);
|
|
return total;
|
|
}
|