traceline (org, self.origin + dir * 1000, TRUE, self);
- FireRailgunBullet (org, org + dir * 1000, MON_CVAR(shambler, attack_lightning_damage) * monster_skill, 0, 0, 0, 0, 0, DEATH_MONSTER_SHAMBLER_ZAP);
+ FireRailgunBullet (org, org + dir * 1000, MON_CVAR(shambler, attack_lightning_damage) * Monster_SkillModifier(), 0, 0, 0, 0, 0, DEATH_MONSTER_SHAMBLER_ZAP);
// teamcolor / hit beam effect
//v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
Freeze(e, 0.3, 2, FALSE);
break;
case SPIDER_TYPE_FIRE:
- Fire_AddDamage(e, self.realowner, 5 * monster_skill, MON_CVAR(spider, attack_web_damagetime), DEATH_MONSTER_SPIDER_FIRE);
+ Fire_AddDamage(e, self.realowner, 5 * Monster_SkillModifier(), MON_CVAR(spider, attack_web_damagetime), DEATH_MONSTER_SPIDER_FIRE);
break;
}
}
RadiusDamage(self, self.realowner, MON_CVAR(wyvern, attack_fireball_damage), MON_CVAR(wyvern, attack_fireball_edgedamage), MON_CVAR(wyvern, attack_fireball_force), world, MON_CVAR(wyvern, attack_fireball_radius), self.projectiledeathtype, world);
for(e = world; (e = findfloat(e, takedamage, DAMAGE_AIM)); ) if(vlen(e.origin - self.origin) <= MON_CVAR(wyvern, attack_fireball_radius))
- Fire_AddDamage(e, self, 5 * monster_skill, MON_CVAR(wyvern, attack_fireball_damagetime), self.projectiledeathtype);
+ Fire_AddDamage(e, self, 5 * Monster_SkillModifier(), MON_CVAR(wyvern, attack_fireball_damagetime), self.projectiledeathtype);
remove(self);
}
{
angles_face = vectoangles(self.moveto - self.origin);
angles_face = normalize(angles_face) * MON_CVAR(zombie, attack_leap_force);
- Damage(other, self, self, MON_CVAR(zombie, attack_leap_damage) * monster_skill, DEATH_MONSTER_ZOMBIE_JUMP, other.origin, angles_face);
+ Damage(other, self, self, MON_CVAR(zombie, attack_leap_damage) * Monster_SkillModifier(), DEATH_MONSTER_ZOMBIE_JUMP, other.origin, angles_face);
self.touch = MonsterTouch; // instantly turn it off to stop damage spam
}
if(moveflag)
e.monster_moveflags = moveflag;
-
- if(e.team || !IS_PLAYER(spawnedby))
- e.colormap = 1024;
- else
- e.colormap = spawnedby.colormap;
if(IS_PLAYER(spawnedby))
{
}
}
+float Monster_SkillModifier()
+{
+ float t = 1;
+
+ t *= (self.monster_skill * 0.5);
+
+ return t;
+}
+
float monster_isvalidtarget (entity targ, entity ent)
{
if(!targ || !ent)
float monster_melee(entity targ, float damg, float anim, float er, float anim_finished, float deathtype, float dostop)
{
- float rdmg = damg * random();
-
if (self.health <= 0)
return FALSE; // attacking while dead?!
traceline(self.origin + self.view_ofs, self.origin + v_forward * er, 0, self);
if(trace_ent.takedamage)
- Damage(trace_ent, self, self, rdmg * monster_skill, deathtype, trace_ent.origin, normalize(trace_ent.origin - self.origin));
+ Damage(trace_ent, self, self, damg * Monster_SkillModifier(), deathtype, trace_ent.origin, normalize(trace_ent.origin - self.origin));
return TRUE;
}
self.nextthink = time + self.ticrate;
MUTATOR_CALLHOOK(MonsterSpawn);
+
+ // TODO: fix this mess
+ if(IS_PLAYER(self.monster_owner))
+ self.colormap = self.monster_owner.colormap;
+ else if(teamplay && self.team)
+ self.colormap = 1024 + self.team * 17;
+ else
+ {
+ if(self.monster_skill <= MONSTER_SKILL_EASY)
+ self.colormap = 1027;
+ else if(self.monster_skill <= MONSTER_SKILL_MEDIUM)
+ self.colormap = 1038;
+ else if(self.monster_skill <= MONSTER_SKILL_HARD)
+ self.colormap = 1028;
+ else
+ self.colormap = 1024;
+ }
}
float monster_initialize(float mon_id, float nodrop)
return FALSE;
entity mon = get_monsterinfo(mon_id);
+
+ if not(self.monster_skill)
+ self.monster_skill = cvar("g_monsters_skill");
// support for quake style removing monsters based on skill
- if(monster_skill <= 1) if(self.spawnflags & MONSTERSKILL_NOTEASY) { return FALSE; }
- if(monster_skill == 2) if(self.spawnflags & MONSTERSKILL_NOTMEDIUM) { return FALSE; }
- if(monster_skill >= 3) if(self.spawnflags & MONSTERSKILL_NOTHARD) { return FALSE; }
+ if(self.monster_skill == MONSTER_SKILL_EASY) if(self.spawnflags & MONSTERSKILL_NOTEASY) { return FALSE; }
+ if(self.monster_skill == MONSTER_SKILL_MEDIUM) if(self.spawnflags & MONSTERSKILL_NOTMEDIUM) { return FALSE; }
+ if(self.monster_skill == MONSTER_SKILL_HARD) if(self.spawnflags & MONSTERSKILL_NOTHARD) { return FALSE; }
if(self.team && !teamplay)
self.team = 0;
.string spawnmob;
.float monster_attack;
-float monster_skill;
-
.entity monster_owner; // new monster owner entity, fixes non-solid monsters
.float monstercount; // per player monster count
void monster_remove(entity mon); // removes a monster
.float(float attack_type) monster_attackfunc;
-const float MONSTER_ATTACK_MELEE = 1;
-const float MONSTER_ATTACK_RANGED = 2;
+const float MONSTER_ATTACK_MELEE = 1;
+const float MONSTER_ATTACK_RANGED = 2;
+
+.float monster_skill;
+const float MONSTER_SKILL_EASY = 1;
+const float MONSTER_SKILL_MEDIUM = 3;
+const float MONSTER_SKILL_HARD = 5;
+const float MONSTER_SKILL_INSANE = 7;
+const float MONSTER_SKILL_NIGHTMARE = 10;
.float fish_wasdrowning; // used to reset a drowning fish's angles if it reaches water again
MSG_CENTER_NOTIF(1, CENTER_ROUND_PLAYER_WIN, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF, 0, 0, "", NO_CPID, "0 0", _("^K1You froze yourself"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE, 0, 0, "", NO_CPID, "0 0", _("^K1Round already started, you spawn as frozen"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_INVASION_SUPERMONSTER, 1, 0, "s1", NO_CPID, "0 0", _("^K1A %s has arrived!"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DONTHAVE, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DROP, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_GOT, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") \
g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
g_bugrigs_steer = cvar("g_bugrigs_steer");
- monster_skill = cvar("g_monsters_skill");
-
g_minstagib = cvar("g_minstagib");
sv_clones = cvar("sv_clones");
roundcnt += 1;
+ invasion_monsterskill = roundcnt + max(1, numplayers * 0.3);
+
maxcurrent = 0;
numspawned = 0;
numkilled = 0;
maxspawned = rint(autocvar_g_invasion_monster_count * (roundcnt * 0.5));
else
maxspawned = autocvar_g_invasion_monster_count;
-
- monster_skill += 0.1 * numplayers;
}
MUTATOR_HOOKFUNCTION(invasion_MonsterDies)
maxcurrent += 1;
}
+ self.monster_skill = invasion_monsterskill;
+
+ if((get_monsterinfo(self.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, M_NAME(self.monsterid));
+
self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
return FALSE;
sprint(self, strcat("roundcnt = ", ftos(roundcnt), "\n"));
sprint(self, strcat("monsters_total = ", ftos(monsters_total), "\n"));
sprint(self, strcat("monsters_killed = ", ftos(monsters_killed), "\n"));
- sprint(self, strcat("monster_skill = ", ftos(monster_skill), "\n"));
+ sprint(self, strcat("invasion_monsterskill = ", ftos(invasion_monsterskill), "\n"));
return TRUE;
}
allowed_to_spawn = TRUE;
- monster_skill = 0.5;
-
roundcnt = 0;
}
float numkilled;
float last_check;
float maxcurrent;
+
+float invasion_monsterskill;