Skip to content

Commit

Permalink
Fixed a crashing bug with shambler. Combined Evil Curse with Cheaper …
Browse files Browse the repository at this point in the history
…Curses. Replaced the latter curse with Hellspawn Mastery, which increases its damage and gives it a secondary chain lightning attack.
  • Loading branch information
Vortex-Quake2 committed Sep 22, 2024
1 parent 1b88135 commit 1f721f4
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 23 deletions.
14 changes: 8 additions & 6 deletions src/characters/Talents.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const talentdef_t talents_vampire[] = {
};

const talentdef_t talents_necromancer[] = {
{TALENT_CHEAPER_CURSES, 5, false},
{TALENT_HELLSPAWN_MASTERY, 5, false},
{TALENT_CORPULENCE, 5, false},
{TALENT_OBLATION, 5, false},
{TALENT_DIM_VISION, 5, false},
Expand Down Expand Up @@ -548,11 +548,13 @@ int writeTalentDescription(edict_t *ent, int talentID) {
return 4;
//Necromancer talents
case TALENT_EVIL_CURSE:
menu_add_line(ent, "Increases curse duration.", MENU_WHITE_CENTERED);
return 1;
case TALENT_CHEAPER_CURSES:
menu_add_line(ent, "Reduces curse cost.", MENU_WHITE_CENTERED);
return 1;
menu_add_line(ent, "Increases curse duration", MENU_WHITE_CENTERED);
menu_add_line(ent, "and reduces cost.", MENU_WHITE_CENTERED);
return 2;
case TALENT_HELLSPAWN_MASTERY:
menu_add_line(ent, "Improves hellspawn. Adds", MENU_WHITE_CENTERED);
menu_add_line(ent, "secondary attack.", MENU_WHITE_CENTERED);
return 2;
case TALENT_CORPULENCE:
menu_add_line(ent, "Increases monster health/armor", MENU_WHITE_CENTERED);
menu_add_line(ent, "Can't combine with Life Tap.", MENU_WHITE_CENTERED);
Expand Down
2 changes: 1 addition & 1 deletion src/characters/Talents.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
#define TALENT_BOOMERANG 73
#define TALENT_BALANCESPIRIT 74
//Necromancer
#define TALENT_CHEAPER_CURSES 80
#define TALENT_HELLSPAWN_MASTERY 80
#define TALENT_CORPULENCE 81
#define TALENT_OBLATION 82
#define TALENT_DIM_VISION 83
Expand Down
4 changes: 2 additions & 2 deletions src/characters/v_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,8 @@ char *GetTalentString(int talent_ID) {
//Necromancer Talents
case TALENT_EVIL_CURSE:
return "Evil Curse";
case TALENT_CHEAPER_CURSES:
return "Cheaper Curses";
case TALENT_HELLSPAWN_MASTERY:
return "Hellspawn Mastery";
case TALENT_CORPULENCE:
return "Corpulence";
case TALENT_OBLATION:
Expand Down
4 changes: 4 additions & 0 deletions src/combat/abilities/chainlightning.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ qboolean ChainLightning_Attack (edict_t *ent, edict_t *target, int damage, int m

if (result && mode != CL_CHECK)
{
// do less damage to corpses
if (target->health < 1 && damage > 100)
damage = 100;
//gi.dprintf("CL did %d damage at %d\n", damage, level.framenum);
// deal damage
T_Damage(target, ent, ent, vec3_origin, target->s.origin, vec3_origin,
Expand All @@ -70,6 +73,7 @@ void ChainLightning (edict_t *ent, vec3_t start, vec3_t aimdir, int damage, int
edict_t *prev_ed[CLIGHTNING_MAX_HOPS]; // list of entities we've previously hit
qboolean found=false;

//gi.dprintf("ChainLightning damage: %d range: %d hop: %d\n", damage, attack_range, hop_range);
memset(prev_ed, 0, CLIGHTNING_MAX_HOPS*sizeof(prev_ed[0]));

// write a nice effect so everyone knows we've cast a spell
Expand Down
12 changes: 6 additions & 6 deletions src/combat/abilities/curses.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ void Cmd_LifeTap(edict_t* ent)
gi.dprintf("DEBUG: %s just called Cmd_LifeTap()\n", ent->client->pers.netname);

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!V_CanUseAbilities(ent, LIFE_TAP, cost, true))
Expand Down Expand Up @@ -567,7 +567,7 @@ void Cmd_AmpDamage(edict_t *ent)
gi.dprintf("DEBUG: %s just called Cmd_AmpDamage()\n", ent->client->pers.netname);

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!V_CanUseAbilities(ent, AMP_DAMAGE, cost, true))
Expand Down Expand Up @@ -623,7 +623,7 @@ void Cmd_Curse(edict_t *ent)
gi.dprintf("DEBUG: %s just called Cmd_Curse()\n", ent->client->pers.netname);

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!V_CanUseAbilities(ent, CURSE, cost, true))
Expand Down Expand Up @@ -660,7 +660,7 @@ void Cmd_Weaken(edict_t *ent)
gi.dprintf("DEBUG: %s just called Cmd_Weaken()\n", ent->client->pers.netname);

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!V_CanUseAbilities(ent, WEAKEN, cost, true))
Expand Down Expand Up @@ -702,7 +702,7 @@ void Cmd_LifeDrain(edict_t *ent)
gi.dprintf("DEBUG: %s just called Cmd_LifeDrain()\n", ent->client->pers.netname);

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!V_CanUseAbilities(ent, LIFE_DRAIN, cost, true))
Expand Down Expand Up @@ -854,7 +854,7 @@ void Cmd_Amnesia(edict_t *ent)
return;

//Talent: Cheaper Curses
if ((talentLevel = vrx_get_talent_level(ent, TALENT_CHEAPER_CURSES)) > 0)
if ((talentLevel = vrx_get_talent_level(ent, TALENT_EVIL_CURSE)) > 0)
cost *= 1.0 - 0.1 * talentLevel;

if (!G_CanUseAbilities(ent, ent->myskills.abilities[AMNESIA].current_level, cost))
Expand Down
22 changes: 22 additions & 0 deletions src/combat/abilities/flying_skull.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ void skull_movetogoal (edict_t *self, edict_t *goal)
gi.linkentity(self);
}

void ChainLightning(edict_t* ent, vec3_t start, vec3_t aimdir, int damage, int attack_range, int hop_range);

void skull_attack (edict_t *self)
{
int damage;//, knockback;
Expand Down Expand Up @@ -295,10 +297,26 @@ void skull_attack (edict_t *self)

// do the damage
damage = self->dmg;

//knockback = 2*damage;
tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT);
if (G_EntExists(tr.ent))
{
// damage to non-players is increased
//if (!tr.ent->client)
// damage *= 2;
// Talent: Hellspawn Mastery
// each talent upgrade increases the chance to proc a chainlightning attack
float chance = 0.1 * self->light_level;
if (level.framenum > self->dim_vision_delay && chance > random())
{
int cl_dmg = 10 * damage;
//gi.dprintf("hellspawn firing CL. base dmg %d modified %d CL %d\n", self->dmg, damage, cl_dmg);
ChainLightning(self, start, v, cl_dmg, SKULL_ATTACK_RANGE, CLIGHTNING_INITIAL_HR);
self->dim_vision_delay = level.framenum + (int)(1 / FRAMETIME);
return; // done attacking
}

//if (tr.ent->groundentity)
// knockback *= 2;
T_Damage(tr.ent, self, self, forward, tr.endpos, tr.plane.normal,
Expand Down Expand Up @@ -586,9 +604,13 @@ void SpawnSkull (edict_t *ent)
skull->activator = ent;
skull->takedamage = DAMAGE_YES;
skull->monsterinfo.level = ent->myskills.abilities[HELLSPAWN].current_level; // used for monster exp
skull->light_level = vrx_get_talent_level(ent, TALENT_HELLSPAWN_MASTERY); // Talent: Hellspawn Mastery
skull->monsterinfo.control_cost = 3; // used for monster exp
skull->health = SKULL_INITIAL_HEALTH + SKULL_ADDON_HEALTH*ent->myskills.abilities[HELLSPAWN].current_level;//ent->myskills.level;
skull->dmg = SKULL_INITIAL_DAMAGE + SKULL_ADDON_DAMAGE*ent->myskills.abilities[HELLSPAWN].current_level;//*ent->myskills.level;
//gi.dprintf("skull base dmg %d at creation\n", skull->dmg);
skull->dmg *= 1.0 + 0.1 * skull->light_level; // Talent: Hellspawn Mastery increases damage
//gi.dprintf("skull dmg %d with talent %d\n", skull->dmg, skull->light_level);

// az: add decino's fix from vrx-indy
// az: un-add. let's make a new talent for this.
Expand Down
3 changes: 2 additions & 1 deletion src/combat/abilities/plaguecloud.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ void InfectedCorpseTouch(edict_t* self, edict_t* other)
{
if (vrx_get_talent_level(q->ent->owner, TALENT_BLACK_DEATH)) // plague owner has upgraded black death talent
{
//gi.dprintf("touched infected corpse\n");
// flag entity with black death so that they take extra damage from plague
other->flags |= FL_BLACK_DEATH;
// kill the corpse
T_Damage(self, self, other, vec3_origin, self->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, MOD_CORPSEEXPLODE);
T_Damage(self, world, world, vec3_origin, self->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, MOD_CORPSEEXPLODE);
gi.sound(other, CHAN_ITEM, gi.soundindex("abilities/corpseexplodecast.wav"), 1, ATTN_NORM, 0);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/combat/common/damage.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,13 @@ float G_AddDamage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
damage *= 2;

// hellspawn gains extra damage against non-clients
/*
if ((attacker->mtype == M_SKULL) && (targ->mtype != M_SKULL) && !targ->client) {
if (pvm->value || invasion->value)
damage *= 4;
else
damage *= 1.5;
}
}*/

// proxy, caltrops and medic packs are 3 more effective against non-players
if (((mod == MOD_CALTROPS) || (mod == MOD_PROXY) || (mod == MOD_FMEDICPACK)) && !targ->client && targ->mtype)
Expand Down
1 change: 1 addition & 0 deletions src/entities/drone/baron_fire.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ void baron_fire_die(edict_t* self, edict_t* inflictor, edict_t* attacker, int da
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->monsterinfo.currentmove = &baron_fire_move_death;
DroneList_Remove(self);
}

void baron_fire_melee(edict_t* self)
Expand Down
3 changes: 2 additions & 1 deletion src/entities/drone/drone_decoy.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ void decoy_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage

n = randomMT() % 2;
if (n == 0) self->monsterinfo.currentmove = &actor_move_death1;
else self->monsterinfo.currentmove = &actor_move_death2;
else self->monsterinfo.currentmove = &actor_move_death2;
DroneList_Remove(self);
}

mframe_t actor_frames_attack3[] =
Expand Down
1 change: 1 addition & 0 deletions src/entities/drone/drone_makron.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ void makron_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
makron_torso (tempent);

self->monsterinfo.currentmove = &makron_move_death2;
DroneList_Remove(self);

}

Expand Down
9 changes: 5 additions & 4 deletions src/entities/drone/drone_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ edict_t *DroneList_Next(edict_t *ent)
if (ent->monsterinfo.dronelist_index + 1 < MAX_EDICTS) {
edict_t *next_drone = DroneList[ent->monsterinfo.dronelist_index + 1];
if (ent == next_drone) {
gi.dprintf("invoking horrible drone list hack because we would otherwise infinite loop");
gi.dprintf("invoking horrible drone list hack because we would otherwise infinite loop\n");
ent->monsterinfo.dronelist_index = ent->monsterinfo.dronelist_index + 1;
return DroneList_Next(ent);
}

if (next_drone != NULL && next_drone->monsterinfo.dronelist_index < ent->monsterinfo.dronelist_index) {
// wooee this is terrible
gi.dprintf("another horrible hack: next monster would have put us in an infinite loop. removing.");
gi.dprintf("another horrible hack: next monster would have put us in an infinite loop. removing.\n");
DroneList_Remove(next_drone);
return DroneList_Next(ent);
}
Expand Down Expand Up @@ -126,7 +126,7 @@ void DroneList_Remove(edict_t *ent)
}

if (duplicates > 0) {
gi.dprintf("removed monster has duplicates %d lol", duplicates);
gi.dprintf("removed monster has duplicates %d lol\n", duplicates);
}
}
#endif
Expand Down Expand Up @@ -2130,11 +2130,12 @@ char *GetMonsterKindString (int mtype)
}
}

// NOTE: M_Notify only works for player-spawn monsters--don't expect it to do anything for worldspawned monsters!
void M_Notify (edict_t *monster)
{
if (!monster || !monster->inuse)
return;
if (!monster->activator || !monster->activator->inuse || !monster->activator->client)
if (!monster->activator || !monster->activator->inuse || !monster->activator->client) // only works for player-spawned monsters
return;

// don't call this more than once
Expand Down
2 changes: 1 addition & 1 deletion src/entities/drone/drone_shambler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ void shambler_die(edict_t* self, edict_t* inflictor, edict_t* attacker, int dama
for (n = 0; n < 4; n++)
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
//self->deadflag = DEAD_DEAD;
return;

#ifdef OLD_NOLAG_STYLE
Expand Down

0 comments on commit 1f721f4

Please sign in to comment.