// Brute
set g_monster_brute 1 "Enable Brutes"
set g_monster_brute_health 300 "Brute health"
-set g_monster_brute_chainsaw_damage 15 "Brute chainsaw damage (hits multiple times)"
+set g_monster_brute_attack_chainsaw_damage 15 "Brute chainsaw damage (hits multiple times)"
set g_monster_brute_drop ammo "Brute drops this item on death"
set g_monster_brute_drop_size bullets "Size of the item Brutes drop. Possible values are: small, medium, large"
set g_monster_brute_speed_walk 100 "Brute walk speed"
set g_monster_brute_attack_grenade_edgedamage 20 "Brute grenade indirect hit damage"
set g_monster_brute_attack_grenade_radius 200 "Brute grenade explosion radius"
set g_monster_brute_attack_grenade_force 15 "Brute grenade knockback"
+set g_monster_brute_attack_grenade_speed 1900
+set g_monster_brute_attack_grenade_speed_up 225
+set g_monster_brute_attack_grenade_speed_z 0
+set g_monster_brute_attack_grenade_spread 0
// Animus
set g_monster_animus 1 "Enable Animuses"
set g_monster_animus_health 150 "Animus health"
set g_monster_animus_attack_jump_damage 80 "Animus jump attack damage"
-set g_monster_animus_damage 45 "Animus melee attack damage"
+set g_monster_animus_attack_melee_damage 45 "Animus melee attack damage"
set g_monster_animus_drop health "Animus drops this item on death"
set g_monster_animus_drop_size medium "Size of the item Animuses drop. Possible values are: small, medium, large"
set g_monster_animus_speed_walk 150 "Animus walk speed"
// Shambler
set g_monster_shambler 1 "Enable Shamblers"
set g_monster_shambler_health 500 "Shambler health"
-set g_monster_shambler_damage 50 "Shambler melee attack damage"
+set g_monster_shambler_attack_smash_damage 50 "Shambler smash attack damage"
set g_monster_shambler_attack_lightning_damage 15 "Shambler lightning attack damage per frame"
set g_monster_shambler_attack_claw_damage 50 "Shambler claw attack damage"
set g_monster_shambler_drop health "Shambler drops this item on death"
set g_monster_bruiser_health 200 "Bruiser Health"
set g_monster_bruiser_drop armor "Bruiser drops this item on death"
set g_monster_bruiser_drop_size medium "Size of the item Bruisers drop. Possible values are: small, medium, large"
-set g_monster_bruiser_melee_damage 50 "Bruiser melee attack damage"
-set g_monster_bruiser_melee_side_damage 35 "Bruiser melee attack side damage"
+set g_monster_bruiser_attack_melee_damage 50 "Bruiser melee attack damage"
set g_monster_bruiser_speed_walk 40 "Bruiser walk speed"
set g_monster_bruiser_speed_run 360 "Bruiser run speed"
set g_monster_wyvern_health 95 "Wyvern health"
set g_monster_wyvern_drop ammo "Wyvern drops this item on death"
set g_monster_wyvern_drop_size cells "Size of the item Wyverns drop. Possible values are: small, medium, large"
+set g_monster_wyvern_speed_stop 300 "Wyvern stop speed"
set g_monster_wyvern_speed_walk 40 "Wyvern walk speed"
set g_monster_wyvern_speed_run 120 "Wyvern run speed"
-set g_monster_wyvern_fireball_damagetime 3 "How long the enemy will burn if it's within fireball radius"
-set g_monster_wyvern_fireball_damage 30 "Wyvern fireball projectile damage"
-set g_monster_wyvern_fireball_edgedamage 20 "Wyvern fireball indirect hit damage"
-set g_monster_wyvern_fireball_force 50 "Wyvern fireball projectile push force"
-set g_monster_wyvern_fireball_radius 120 "Wyvern fireball projectile damage radius"
-set g_monster_wyvern_fireball_speed 900 "Wyvern fireball projectile speed"
+set g_monster_wyvern_attack_fireball_damagetime 3 "How long the enemy will burn if it's within fireball radius"
+set g_monster_wyvern_attack_fireball_damage 30 "Wyvern fireball projectile damage"
+set g_monster_wyvern_attack_fireball_edgedamage 20 "Wyvern fireball indirect hit damage"
+set g_monster_wyvern_attack_fireball_force 50 "Wyvern fireball projectile push force"
+set g_monster_wyvern_attack_fireball_radius 120 "Wyvern fireball projectile damage radius"
+set g_monster_wyvern_attack_fireball_speed 900 "Wyvern fireball projectile speed"
// Cerberus
set g_monster_cerberus 1 "Enable Cerberuses"
set g_monster_cerberus_health 100 "Cerberus health"
-set g_monster_cerberus_bite_damage 30 "Cerberus bite attack damage"
+set g_monster_cerberus_attack_bite_damage 30 "Cerberus bite attack damage"
set g_monster_cerberus_attack_jump_damage 40 "Cerberus jump attack damage"
set g_monster_cerberus_drop health "Cerberus drops this item on death"
set g_monster_cerberus_drop_size small "Size of the item Cerberuss drop. Possible values are: small, medium, large"
// Slime
set g_monster_slime 1 "Enable Slime"
set g_monster_slime_health 80 "Slime health"
+set g_monster_slime_attack_explode_damage 250
set g_monster_slime_drop ammo "Slime drops this item when it explodes"
set g_monster_slime_drop_size rockets "Size of the item Slime drops. Possible values are: small, medium, large"
set g_monster_slime_speed_walk 20 "Slime walk speed"
set g_monster_knight_health 300 "Knight health"
set g_monster_knight_drop armor "Knight drops this item on death"
set g_monster_knight_drop_size medium "Size of the item Knights drop. Possible values are: small, medium, large"
-set g_monster_knight_inferno_damage 40 "Knight inferno damage"
-set g_monster_knight_inferno_chance 0.4 "Knight inferno attack chance"
-set g_monster_knight_inferno_damagetime 3 "How long the inferno should burn the player"
-set g_monster_knight_fireball_damage 30 "Knight fireball projectile damage"
-set g_monster_knight_fireball_edgedamage 10 "Knight fireball indirect hit damage"
-set g_monster_knight_fireball_force 50 "Knight fireball projectile push force"
-set g_monster_knight_fireball_radius 70 "Knight fireball projectile damage radius"
-set g_monster_knight_fireball_speed 600 "Knight fireball projectile speed"
-set g_monster_knight_fireball_spread 0 "Knight fireball projectile spread"
-set g_monster_knight_fireball_chance 0.3 "Chance for Knight to throw a fireball"
-set g_monster_knight_jump_chance 0.2 "Chance for Knight to jump at the player (always 1 if enemy is further than _dist)"
-set g_monster_knight_jump_damage 25 "Knight jump attack damage"
-set g_monster_knight_jump_dist 500 "Knight will prioritise jumping if the enemy is this far away"
-set g_monster_knight_melee_damage 20 "Knight melee attack damage"
-set g_monster_knight_spike_damage 20 "Knight spike projectile damage"
-set g_monster_knight_spike_edgedamage 10 "Knight spike projectile indirect hit damage"
-set g_monster_knight_spike_radius 20 "Knight spike projectile damage radius"
-set g_monster_knight_spike_force 5 "Knight spike projectile force"
-set g_monster_knight_spike_chance 0.5 "Knight spike attack chance"
-set g_monster_knight_speed_walk 75 "Knight walk speed"
-set g_monster_knight_speed_run 150 "Knight run speed"
+set g_monster_knight_attack_inferno_damage 40 "Knight inferno damage"
+set g_monster_knight_attack_inferno_chance 0.4 "Knight inferno attack chance"
+set g_monster_knight_attack_inferno_damagetime 3 "How long the inferno should burn the player"
+set g_monster_knight_attack_fireball_damage 30 "Knight fireball projectile damage"
+set g_monster_knight_attack_fireball_edgedamage 10 "Knight fireball indirect hit damage"
+set g_monster_knight_attack_fireball_force 50 "Knight fireball projectile push force"
+set g_monster_knight_attack_fireball_radius 70 "Knight fireball projectile damage radius"
+set g_monster_knight_attack_fireball_speed 600 "Knight fireball projectile speed"
+set g_monster_knight_attack_fireball_spread 0 "Knight fireball projectile spread"
+set g_monster_knight_attack_fireball_chance 0.3 "Chance for Knight to throw a fireball"
+set g_monster_knight_attack_fireball_damagetime 1
+set g_monster_knight_attack_jump_chance 0.2 "Chance for Knight to jump at the player (always 1 if enemy is further than _dist)"
+set g_monster_knight_attack_jump_damage 25 "Knight jump attack damage"
+set g_monster_knight_attack_jump_distance 500 "Knight will prioritise jumping if the enemy is this far away"
+set g_monster_knight_attack_melee_damage 20 "Knight melee attack damage"
+set g_monster_knight_attack_spike_damage 20 "Knight spike projectile damage"
+set g_monster_knight_attack_spike_edgedamage 10 "Knight spike projectile indirect hit damage"
+set g_monster_knight_attack_spike_radius 20 "Knight spike projectile damage radius"
+set g_monster_knight_attack_spike_force 5 "Knight spike projectile force"
+set g_monster_knight_attack_spike_chance 0.5 "Knight spike attack chance"
+set g_monster_knight_attack_speed_walk 75 "Knight walk speed"
+set g_monster_knight_attack_speed_run 150 "Knight run speed"
// Stingray
set g_monster_stingray 1 "Enable Stingray"
set g_monster_stingray_health 115 "Stingray health"
-set g_monster_stingray_damage 25 "Stingray bite attack damage"
+set g_monster_stingray_attack_bite_damage 25 "Stingray bite attack damage"
+set g_monster_stingray_attack_bite_delay 0.5
set g_monster_stingray_drop health "Stingray drops this item on death"
set g_monster_stingray_drop_size small "Size of the item Stingray drop. Possible values are: small, medium, large"
+set g_monster_stingray_speed_stop 10
set g_monster_stingray_speed_walk 40 "Stingray walk speed"
set g_monster_stingray_speed_run 200 "Stingray run speed"
// Mage
set g_monster_mage 1 "Enable Mages"
set g_monster_mage_health 200 "Mage health"
-set g_monster_mage_drop health "Mage drops this item on death"
-set g_monster_mage_drop_size medium "Size of the item Mages drop. Possible values are: small, medium, large"
-set g_monster_mage_speed 50 "Mage move speed"
set g_monster_mage_attack_spike_damage 30 "Mage homing spike explosion damage"
set g_monster_mage_attack_spike_radius 60 "Mage homing spike explosion radius"
set g_monster_mage_attack_spike_delay 2 "Delay between Mage homing spike attacks"
set g_monster_mage_attack_melee_damage 30 "Mage magic attack damage"
set g_monster_mage_attack_melee_delay 0.7 "Delay between Mage melee attacks"
set g_monster_mage_heal_self 35 "Amount of health Mage will regenerate every attack when its low on health"
-set g_monster_mage_heal_friends 15 "Amount of health Mage will regenerate nearby friends"
+set g_monster_mage_heal_allies 15 "Amount of health Mage will regenerate nearby friends"
set g_monster_mage_heal_minhealth 250 "Health limit below which Mage will try to heal itself"
set g_monster_mage_heal_range 200 "Maximum healing distance"
set g_monster_mage_heal_delay 1.5 "Delay between healing bursts"
set g_monster_mage_attack_grenade_lifetime 5 "Mage fake item grenade life time"
set g_monster_mage_attack_grenade_speed 150 "Mage fake item grenade forward speed"
set g_monster_mage_attack_grenade_speed_up 95 "Mage fake item grenade upwards speed"
-set g_monster_mage_attack_grenade_speed_z 0 "Mage fake item grenade speed angle"
-set g_monster_mage_attack_grenade_spread 0 "Mage fake item grenade spread"
set g_monster_mage_attack_grenade_force 170 "Mage fake item grenade damage knockback"
set g_monster_mage_attack_grenade_chance 30 "% chance of Mage attack being fake item grenade"
+set g_monster_mage_drop health "Mage drops this item on death"
+set g_monster_mage_drop_size medium "Size of the item Mages drop. Possible values are: small, medium, large"
+set g_monster_mage_speed_walk 50 "Mage walk speed"
+set g_monster_mage_speed_run 75 "Mage run speed"
// Zombie
set g_monster_zombie 1 "Enable Zombies"
set g_monster_zombie_attack_leap_force 55 "Force of zombie attack leap"
set g_monster_zombie_attack_leap_range 96 "Range of zombie attack leap"
set g_monster_zombie_attack_leap_speed 500 "The speed of a zombie attack leap"
-set g_monster_zombie_attack_stand_damage 40 "Damage when zombie hits from a standing position"
-set g_monster_zombie_attack_stand_delay 1.2 "Delay after a zombie hits from a standing position"
-set g_monster_zombie_attack_stand_range 48 "Range of a zombie standing position attack"
+set g_monster_zombie_attack_melee_damage 40 "Damage when zombie hits from a standing position"
+set g_monster_zombie_attack_melee_delay 1.2 "Delay after a zombie hits from a standing position"
set g_monster_zombie_health 150 "Zombie health"
set g_monster_zombie_speed_walk 150 "Zombie walk speed"
set g_monster_zombie_speed_run 400 "Zombie run speed"
-set g_monster_zombie_stopspeed 100 "Speed at which zombie stops"
+set g_monster_zombie_speed_stop 100 "Speed at which zombie stops"
set g_monster_zombie_drop health "Zombie drops this item on death"
set g_monster_zombie_drop_size large "Size of the item zombies drop. Possible values are: small, medium, large"
// Spider
set g_monster_spider 1 "Enable Spiders"
set g_monster_spider_attack_type 0 "Spider attack type (0 = ice, 1 = fire, ...)"
-set g_monster_spider_attack_leap_delay 1.5 "Delay after spider attack leap"
-set g_monster_spider_attack_stand_damage 35 "Damage when spider hits from a standing position"
-set g_monster_spider_attack_stand_delay 1.2 "Delay after a spider hits from a standing position"
-set g_monster_spider_attack_fire_time 2 "Spider fire attack burn time"
+set g_monster_spider_attack_bite_damage 35 "Damage when spider hits from a standing position"
+set g_monster_spider_attack_bite_delay 1.2 "Delay after a spider hits from a standing position"
+set g_monster_spider_attack_web_damagetime 2 "Spider fire attack burn time"
set g_monster_spider_attack_web_speed 1000 "Spider web fly speed"
set g_monster_spider_attack_web_speed_up 150 "Spider web upwards fly speed"
-set g_monster_spider_attack_web_spread 0 "Spider web spread"
-set g_monster_spider_attack_web_speed_z 0 "Spider web upwards angle"
+set g_monster_spider_attack_web_delay 1.5 "Delay after spider attack web"
set g_monster_spider_health 160 "Spider health"
-set g_monster_spider_idle_timer_min 1 "Minimum time a spider can stay idle"
set g_monster_spider_speed_walk 150 "Spider walk speed"
set g_monster_spider_speed_run 400 "Spider run speed"
-set g_monster_spider_stopspeed 100 Speed at which spider stops"
+set g_monster_spider_speed_stop 100 "Speed at which spider stops"
set g_monster_spider_drop health "Spider drops this item on death"
set g_monster_spider_drop_size large "Size of the item spiders drop. Possible values are: small, medium, large"
}
}
+void GenericCommand_dumpmonsters(float request)
+{
+ switch(request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ #ifdef SVQC
+ mon_config_file = -1;
+ mon_config_alsoprint = -1;
+ string filename = argv(1);
+
+ if(filename == "")
+ {
+ filename = "monsters_dump.cfg";
+ mon_config_alsoprint = FALSE;
+ }
+ else if(filename == "-")
+ {
+ filename = "monsters_dump.cfg";
+ mon_config_alsoprint = TRUE;
+ }
+ mon_config_file = fopen(filename, FILE_WRITE);
+
+ if(mon_config_file >= 0)
+ {
+ Dump_Monster_Settings();
+ print(sprintf("Dumping monsters... File located in ^2data/data/%s^7.\n", filename));
+ fclose(mon_config_file);
+ mon_config_file = -1;
+ mon_config_alsoprint = -1;
+ }
+ else
+ {
+ print(sprintf("^1Error: ^7Could not open file '%s'!\n", filename));
+ }
+ #else
+ print(_("Monsters dump command only works with sv_cmd.\n"));
+ #endif
+ return;
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ print(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpmonsters [filename]"));
+ print(" Where 'filename' is the file to write (default is monsters_dump.cfg),\n");
+ print(" if supplied with '-' output to console as well as default,\n");
+ print(" if left blank, it will only write to default.\n");
+ return;
+ }
+ }
+}
+
void GenericCommand_dumpnotifs(float request)
{
switch(request)
#define GENERIC_COMMANDS(request,arguments,command) \
GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
+ GENERIC_COMMAND("dumpmonsters", GenericCommand_dumpmonsters(request), "Dump all monsters into monsters_dump.cfg") \
GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \
--- /dev/null
+// ==========================
+// Monster Config Generator
+// ==========================
+
+void M_Config_Queue_Swap(float root, float child, entity pass)
+{
+ string oldroot = mon_config_queue[root];
+ mon_config_queue[root] = mon_config_queue[child];
+ mon_config_queue[child] = oldroot;
+}
+
+float M_Config_Queue_Compare(float root, float child, entity pass)
+{
+ float i, r, c;
+
+ for(i = 1; i <= 100; ++i)
+ {
+ r = str2chr(mon_config_queue[root], i);
+ c = str2chr(mon_config_queue[child], i);
+ if(r == c) { continue; }
+ else if(c > r) { return -1; }
+ else { return 1; }
+ }
+
+ return 0;
+}
+
+void Dump_Monster_Settings(void)
+{
+ float i, x, totalsettings = 0;
+ for(i = MON_FIRST; i <= MON_LAST; ++i)
+ {
+ // step 1: clear the queue
+ MON_CONFIG_COUNT = 0;
+ for(x = 0; x <= MAX_MON_CONFIG; ++x)
+ { mon_config_queue[x] = string_null; }
+
+ // step 2: build new queue
+ MON_ACTION(i, MR_CONFIG);
+
+ // step 3: sort queue
+ heapsort(MON_CONFIG_COUNT, M_Config_Queue_Swap, M_Config_Queue_Compare, world);
+
+ // step 4: write queue
+ MON_CONFIG_WRITETOFILE(sprintf("// {{{ #%d: %s\n", i, M_NAME(i)))
+ for(x = 0; x <= MON_CONFIG_COUNT; ++x)
+ { MON_CONFIG_WRITETOFILE(mon_config_queue[x]) }
+ MON_CONFIG_WRITETOFILE("// }}}\n")
+
+ // step 5: debug info
+ print(sprintf("#%d: %s: %d settings...\n", i, M_NAME(i), MON_CONFIG_COUNT));
+ totalsettings += MON_CONFIG_COUNT;
+ }
+
+ // clear queue now that we're finished
+ MON_CONFIG_COUNT = 0;
+ for(x = 0; x <= MAX_MON_CONFIG; ++x)
+ { mon_config_queue[x] = string_null; }
+
+ // extra information
+ print(sprintf("Totals: %d monsters, %d settings\n", (i - 1), totalsettings));
+}
--- /dev/null
+// ==========================
+// Monster Config Generator
+// ==========================
+
+void Dump_Monster_Settings(void);
+float mon_config_file;
+float mon_config_alsoprint;
+
+#define MAX_MON_CONFIG 256
+float MON_CONFIG_COUNT;
+string mon_config_queue[MAX_MON_CONFIG];
+
+#define MON_CONFIG_QUEUE(a) { \
+ mon_config_queue[MON_CONFIG_COUNT] = a; \
+ ++MON_CONFIG_COUNT; }
+
+#define MON_CONFIG_WRITETOFILE(a) { \
+ fputs(mon_config_file, a); \
+ if(mon_config_alsoprint) { print(a); } }
+
+#define MON_CONFIG_WRITE_CVARS(monster,name) \
+ { MON_CONFIG_QUEUE( \
+ sprintf("set g_monster_%s_%s %g\n", #monster, #name, \
+ cvar(sprintf("g_monster_%s_%s", #monster, #name)))) } \
+
+#define MON_CONFIG_SETTINGS(monsettings) \
+ #define MON_ADD_CVAR(monster,name) MON_CONFIG_WRITE_CVARS(monster,name) \
+ monsettings \
+ #undef MON_ADD_CVAR
/* fullname */ _("Animus")
);
+#define ANIMUS_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_jump_damage) \
+ MON_ADD_CVAR(monster, attack_melee_damage) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+ANIMUS_SETTINGS(animus)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_animus;
-float autocvar_g_monster_animus_health;
-float autocvar_g_monster_animus_attack_jump_damage;
-float autocvar_g_monster_animus_damage;
-float autocvar_g_monster_animus_speed_walk;
-float autocvar_g_monster_animus_speed_run;
-
const float animus_anim_stand = 0;
const float animus_anim_walk = 1;
const float animus_anim_run = 2;
{
if (vlen(self.velocity) > 300)
{
- Damage(other, self, self, autocvar_g_monster_animus_attack_jump_damage * monster_skill, DEATH_MONSTER_ANIMUS, other.origin, normalize(other.origin - self.origin));
+ Damage(other, self, self, MON_CVAR(animus, attack_jump_damage) * monster_skill, DEATH_MONSTER_ANIMUS, other.origin, normalize(other.origin - self.origin));
self.touch = MonsterTouch; // instantly turn it off to stop damage spam
}
}
{
monsters_setframe(animus_anim_attack);
self.attack_finished_single = time + 1;
- monster_melee(self.enemy, autocvar_g_monster_animus_damage, 0.3, DEATH_MONSTER_ANIMUS, TRUE);
+ monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), 0.3, DEATH_MONSTER_ANIMUS, TRUE);
return TRUE;
}
void spawnfunc_monster_animus()
{
- if not(autocvar_g_monster_animus) { remove(self); return; }
-
self.classname = "monster_animus";
self.monster_spawnfunc = spawnfunc_monster_animus;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_animus_speed_run, autocvar_g_monster_animus_speed_walk, 100, animus_anim_run, animus_anim_walk, animus_anim_stand);
+ monster_move(MON_CVAR(animus, speed_run), MON_CVAR(animus, speed_walk), 100, animus_anim_run, animus_anim_walk, animus_anim_stand);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_animus_health;
+ if not(self.health) self.health = MON_CVAR(animus, health);
self.monster_attackfunc = animus_attack;
monsters_setframe(animus_anim_stand);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(ANIMUS_SETTINGS(animus))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Bruiser")
);
+#define BRUISER_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_melee_damage) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+BRUISER_SETTINGS(bruiser)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_bruiser;
-float autocvar_g_monster_bruiser_health;
-float autocvar_g_monster_bruiser_melee_damage;
-float autocvar_g_monster_bruiser_speed_walk;
-float autocvar_g_monster_bruiser_speed_run;
-
const float bruiser_anim_stand = 0;
const float bruiser_anim_run = 1;
const float bruiser_anim_runattack = 2;
monsters_setframe((len < 50) ? bruiser_anim_attack : bruiser_anim_runattack);
self.attack_finished_single = time + 1.25;
- monster_melee(self.enemy, autocvar_g_monster_bruiser_melee_damage, 0.3, DEATH_MONSTER_BRUISER, FALSE);
+ monster_melee(self.enemy, MON_CVAR(bruiser, attack_melee_damage), 0.3, DEATH_MONSTER_BRUISER, FALSE);
return TRUE;
}
void spawnfunc_monster_bruiser()
{
- if not(autocvar_g_monster_bruiser) { remove(self); return; }
-
self.classname = "monster_bruiser";
self.monster_spawnfunc = spawnfunc_monster_bruiser;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_bruiser_speed_run, autocvar_g_monster_bruiser_speed_walk, 50, bruiser_anim_run, bruiser_anim_walk, bruiser_anim_stand);
+ monster_move(MON_CVAR(bruiser, speed_run), MON_CVAR(bruiser, speed_walk), 50, bruiser_anim_run, bruiser_anim_walk, bruiser_anim_stand);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_bruiser_health;
+ if not(self.health) self.health = MON_CVAR(bruiser, health);
self.monster_attackfunc = bruiser_attack;
monsters_setframe(bruiser_anim_stand);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(BRUISER_SETTINGS(bruiser))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Brute")
);
+#define BRUTE_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_chainsaw_damage) \
+ MON_ADD_CVAR(monster, attack_uzi_bullets) \
+ MON_ADD_CVAR(monster, attack_uzi_damage) \
+ MON_ADD_CVAR(monster, attack_uzi_force) \
+ MON_ADD_CVAR(monster, attack_uzi_chance) \
+ MON_ADD_CVAR(monster, attack_grenade_damage) \
+ MON_ADD_CVAR(monster, attack_grenade_edgedamage) \
+ MON_ADD_CVAR(monster, attack_grenade_force) \
+ MON_ADD_CVAR(monster, attack_grenade_radius) \
+ MON_ADD_CVAR(monster, attack_grenade_speed) \
+ MON_ADD_CVAR(monster, attack_grenade_speed_up) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+BRUTE_SETTINGS(brute)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_brute;
-float autocvar_g_monster_brute_health;
-float autocvar_g_monster_brute_chainsaw_damage;
-float autocvar_g_monster_brute_speed_walk;
-float autocvar_g_monster_brute_speed_run;
-float autocvar_g_monster_brute_attack_uzi_bullets;
-float autocvar_g_monster_brute_attack_uzi_damage;
-float autocvar_g_monster_brute_attack_uzi_force;
-float autocvar_g_monster_brute_attack_uzi_chance;
-float autocvar_g_monster_brute_attack_grenade_damage;
-float autocvar_g_monster_brute_attack_grenade_edgedamage;
-float autocvar_g_monster_brute_attack_grenade_force;
-float autocvar_g_monster_brute_attack_grenade_radius;
-
const float brute_anim_idle = 0;
const float brute_anim_walk = 1;
const float brute_anim_run = 2;
self.brute_cycles += 1;
self.angles_y = self.angles_y + random()* 25;
- monster_melee(self.enemy, autocvar_g_monster_brute_chainsaw_damage, 0.3, DEATH_MONSTER_BRUTE_BLADE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(brute, attack_chainsaw_damage), 0.3, DEATH_MONSTER_BRUTE_BLADE, TRUE);
if(self.brute_cycles <= 4)
defer(0.2, brute_blade);
monster_makevectors(self.enemy);
- W_SetupShot (self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, autocvar_g_monster_brute_attack_uzi_damage);
- fireBallisticBullet(w_shotorg, w_shotdir, 0.02, 18000, 5, autocvar_g_monster_brute_attack_uzi_damage, autocvar_g_monster_brute_attack_uzi_force, DEATH_MONSTER_BRUTE_UZI, 0, 1, 115);
+ W_SetupShot (self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, MON_CVAR(brute, attack_uzi_damage));
+ fireBallisticBullet(w_shotorg, w_shotdir, 0.02, 18000, 5, MON_CVAR(brute, attack_uzi_damage), MON_CVAR(brute, attack_uzi_force), DEATH_MONSTER_BRUTE_UZI, 0, 1, 115);
endFireBallisticBullet();
- if(self.brute_cycles <= autocvar_g_monster_brute_attack_uzi_bullets)
+ if(self.brute_cycles <= MON_CVAR(brute, attack_uzi_bullets))
defer(0.1, brute_uzi);
}
if(self.movetype == MOVETYPE_NONE)
self.velocity = self.oldvelocity;
- RadiusDamage (self, self.realowner, autocvar_g_monster_brute_attack_grenade_damage, autocvar_g_monster_brute_attack_grenade_edgedamage, autocvar_g_monster_brute_attack_grenade_radius, world, autocvar_g_monster_brute_attack_grenade_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, MON_CVAR(brute, attack_grenade_damage), MON_CVAR(brute, attack_grenade_edgedamage), MON_CVAR(brute, attack_grenade_radius), world, MON_CVAR(brute, attack_grenade_force), self.projectiledeathtype, other);
remove (self);
}
{
entity gren;
- W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", CH_WEAPON_A, autocvar_g_monster_brute_attack_grenade_damage);
+ W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", CH_WEAPON_A, MON_CVAR(brute, attack_grenade_damage));
w_shotdir = v_forward; // no TrueAim for grenades please
gren = spawn ();
gren.owner = gren.realowner = self;
gren.classname = "grenade";
gren.bot_dodge = TRUE;
- gren.bot_dodgerating = autocvar_g_monster_brute_attack_grenade_damage;
+ gren.bot_dodgerating = MON_CVAR(brute, attack_grenade_damage);
gren.movetype = MOVETYPE_BOUNCE;
PROJECTILE_MAKETRIGGER(gren);
gren.projectiledeathtype = DEATH_MONSTER_BRUTE_GRENADE;
gren.touch = brute_grenade_touch;
gren.takedamage = DAMAGE_YES;
- gren.health = autocvar_g_balance_grenadelauncher_primary_health;
- gren.damageforcescale = autocvar_g_balance_grenadelauncher_primary_damageforcescale;
+ gren.health = 50;
+ gren.damageforcescale = 0;
gren.event_damage = brute_grenade_damage;
gren.damagedbycontents = TRUE;
gren.missile_flags = MIF_SPLASH | MIF_ARC;
- W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
+ W_SetupProjectileVelocityEx(gren, w_shotdir, v_up, MON_CVAR(brute, attack_grenade_speed), MON_CVAR(brute, attack_grenade_speed_up), 0, 0, FALSE);
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
case MONSTER_ATTACK_RANGED:
{
self.brute_cycles = 0;
- if(random() <= autocvar_g_monster_brute_attack_uzi_chance)
+ if(random() <= MON_CVAR(brute, attack_uzi_chance))
{
monsters_setframe(brute_anim_pain);
self.attack_finished_single = time + 0.8;
void spawnfunc_monster_brute()
{
- if not(autocvar_g_monster_brute) { remove(self); return; }
-
self.classname = "monster_brute";
self.monster_spawnfunc = spawnfunc_monster_brute;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_brute_speed_run, autocvar_g_monster_brute_speed_walk, 300, brute_anim_run, brute_anim_walk, brute_anim_idle);
+ monster_move(MON_CVAR(brute, speed_run), MON_CVAR(brute, speed_walk), 300, brute_anim_run, brute_anim_walk, brute_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_brute_health;
+ if not(self.health) self.health = MON_CVAR(brute, health);
self.monster_attackfunc = brute_attack;
monsters_setframe(brute_anim_idle);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(BRUTE_SETTINGS(brute))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Cerberus")
);
+#define CERBERUS_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_bite_damage) \
+ MON_ADD_CVAR(monster, attack_jump_damage) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+CERBERUS_SETTINGS(cerberus)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_cerberus;
-float autocvar_g_monster_cerberus_health;
-float autocvar_g_monster_cerberus_bite_damage;
-float autocvar_g_monster_cerberus_attack_jump_damage;
-float autocvar_g_monster_cerberus_speed_walk;
-float autocvar_g_monster_cerberus_speed_run;
-
const float cerberus_anim_idle = 0;
const float cerberus_anim_walk = 1;
const float cerberus_anim_run = 2;
if (other.takedamage)
if (vlen(self.velocity) > 300)
{
- Damage(self.enemy, self, self, autocvar_g_monster_cerberus_attack_jump_damage * monster_skill, DEATH_MONSTER_CERBERUS_JUMP, self.enemy.origin, normalize(self.enemy.origin - self.origin));
+ Damage(self.enemy, self, self, MON_CVAR(cerberus, attack_jump_damage) * monster_skill, DEATH_MONSTER_CERBERUS_JUMP, self.enemy.origin, normalize(self.enemy.origin - self.origin));
self.touch = MonsterTouch;
}
{
monsters_setframe(cerberus_anim_attack);
self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, autocvar_g_monster_cerberus_bite_damage, 0.2, DEATH_MONSTER_CERBERUS_BITE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), 0.2, DEATH_MONSTER_CERBERUS_BITE, TRUE);
return TRUE;
}
void spawnfunc_monster_cerberus()
{
- if not(autocvar_g_monster_cerberus) { remove(self); return; }
-
self.classname = "monster_cerberus";
self.monster_spawnfunc = spawnfunc_monster_cerberus;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_cerberus_speed_run, autocvar_g_monster_cerberus_speed_walk, 50, cerberus_anim_run, cerberus_anim_walk, cerberus_anim_idle);
+ monster_move(MON_CVAR(cerberus, speed_run), MON_CVAR(cerberus, speed_walk), 50, cerberus_anim_run, cerberus_anim_walk, cerberus_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_cerberus_health;
+ if not(self.health) self.health = MON_CVAR(cerberus, health);
self.monster_attackfunc = cerberus_attack;
monsters_setframe(cerberus_anim_idle);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(CERBERUS_SETTINGS(cerberus))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Knight")
);
+#define KNIGHT_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_melee_damage) \
+ MON_ADD_CVAR(monster, attack_inferno_damage) \
+ MON_ADD_CVAR(monster, attack_inferno_damagetime) \
+ MON_ADD_CVAR(monster, attack_inferno_chance) \
+ MON_ADD_CVAR(monster, attack_fireball_damage) \
+ MON_ADD_CVAR(monster, attack_fireball_edgedamage) \
+ MON_ADD_CVAR(monster, attack_fireball_damagetime) \
+ MON_ADD_CVAR(monster, attack_fireball_force) \
+ MON_ADD_CVAR(monster, attack_fireball_radius) \
+ MON_ADD_CVAR(monster, attack_fireball_chance) \
+ MON_ADD_CVAR(monster, attack_spike_damage) \
+ MON_ADD_CVAR(monster, attack_spike_edgedamage) \
+ MON_ADD_CVAR(monster, attack_spike_force) \
+ MON_ADD_CVAR(monster, attack_spike_radius) \
+ MON_ADD_CVAR(monster, attack_spike_chance) \
+ MON_ADD_CVAR(monster, attack_jump_damage) \
+ MON_ADD_CVAR(monster, attack_jump_distance) \
+ MON_ADD_CVAR(monster, attack_jump_chance) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+KNIGHT_SETTINGS(knight)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_knight;
-float autocvar_g_monster_knight_health;
-float autocvar_g_monster_knight_melee_damage;
-float autocvar_g_monster_knight_inferno_damage;
-float autocvar_g_monster_knight_inferno_damagetime;
-float autocvar_g_monster_knight_inferno_chance;
-float autocvar_g_monster_knight_speed_walk;
-float autocvar_g_monster_knight_speed_run;
-float autocvar_g_monster_knight_fireball_damage;
-float autocvar_g_monster_knight_fireball_force;
-float autocvar_g_monster_knight_fireball_radius;
-float autocvar_g_monster_knight_fireball_chance;
-float autocvar_g_monster_knight_fireball_edgedamage;
-float autocvar_g_monster_knight_spike_chance;
-float autocvar_g_monster_knight_spike_force;
-float autocvar_g_monster_knight_spike_radius;
-float autocvar_g_monster_knight_spike_edgedamage;
-float autocvar_g_monster_knight_spike_damage;
-float autocvar_g_monster_knight_jump_chance;
-float autocvar_g_monster_knight_jump_damage;
-float autocvar_g_monster_knight_jump_dist;
-
const float knight_anim_stand = 0;
const float knight_anim_walk = 1;
const float knight_anim_run = 2;
sound(self.enemy, CHAN_AUTO, "player/lava.wav", 1, ATTN_NORM);
if(vlen(self.enemy.origin - self.origin) <= 2000)
- Fire_AddDamage(self.enemy, self, autocvar_g_monster_knight_inferno_damage * monster_skill, autocvar_g_monster_knight_inferno_damagetime, DEATH_MONSTER_KNIGHT_INFERNO);
+ Fire_AddDamage(self.enemy, self, MON_CVAR(knight, attack_inferno_damage) * monster_skill, MON_CVAR(knight, attack_inferno_damagetime), DEATH_MONSTER_KNIGHT_INFERNO);
}
void knight_fireball_explode()
{
pointparticles(particleeffectnum("fireball_explode"), self.origin, '0 0 0', 1);
- RadiusDamage(self, self.realowner, autocvar_g_monster_knight_fireball_damage, autocvar_g_monster_knight_fireball_edgedamage, autocvar_g_monster_knight_fireball_force, world, autocvar_g_monster_knight_fireball_radius, self.projectiledeathtype, world);
+ RadiusDamage(self, self.realowner, MON_CVAR(knight, attack_fireball_damage), MON_CVAR(knight, attack_fireball_edgedamage), MON_CVAR(knight, attack_fireball_force), world, MON_CVAR(knight, attack_fireball_radius), self.projectiledeathtype, world);
- for(e = world; (e = findfloat(e, takedamage, DAMAGE_AIM)); ) if(vlen(e.origin - self.origin) <= autocvar_g_monster_knight_fireball_radius)
- Fire_AddDamage(e, self, 5 * monster_skill, autocvar_g_monster_knight_inferno_damagetime, self.projectiledeathtype);
+ for(e = world; (e = findfloat(e, takedamage, DAMAGE_AIM)); ) if(vlen(e.origin - self.origin) <= MON_CVAR(knight, attack_inferno_damage))
+ Fire_AddDamage(e, self, 5 * monster_skill, MON_CVAR(knight, attack_fireball_damagetime), self.projectiledeathtype);
remove(self);
}
{
pointparticles(particleeffectnum("TE_WIZSPIKE"), self.origin, '0 0 0', 1);
- RadiusDamage (self, self.realowner, autocvar_g_monster_knight_spike_damage, autocvar_g_monster_knight_spike_edgedamage, autocvar_g_monster_knight_spike_force, world, autocvar_g_monster_knight_spike_radius, DEATH_MONSTER_KNIGHT_SPIKE, other);
+ RadiusDamage (self, self.realowner, MON_CVAR(knight, attack_spike_damage), MON_CVAR(knight, attack_spike_edgedamage), MON_CVAR(knight, attack_spike_force), world, MON_CVAR(knight, attack_spike_radius), DEATH_MONSTER_KNIGHT_SPIKE, other);
remove(self);
}
}
self.knight_cycles = 0;
RandomSelection_Init();
- RandomSelection_Add(world, 1, "", autocvar_g_monster_knight_fireball_chance, 1);
- RandomSelection_Add(world, 2, "", autocvar_g_monster_knight_inferno_chance, 1);
- RandomSelection_Add(world, 3, "", autocvar_g_monster_knight_spike_chance, 1);
- if(self.health >= 100) RandomSelection_Add(world, 4, "", ((vlen(self.enemy.origin - self.origin) > autocvar_g_monster_knight_jump_dist) ? 1 : autocvar_g_monster_knight_jump_chance), 1);
+ RandomSelection_Add(world, 1, "", MON_CVAR(knight, attack_fireball_chance), 1);
+ RandomSelection_Add(world, 2, "", MON_CVAR(knight, attack_inferno_chance), 1);
+ RandomSelection_Add(world, 3, "", MON_CVAR(knight, attack_spike_chance), 1);
+ if(self.health >= 100) RandomSelection_Add(world, 4, "", ((vlen(self.enemy.origin - self.origin) > MON_CVAR(knight, attack_jump_distance)) ? 1 : MON_CVAR(knight, attack_jump_chance)), 1);
switch(RandomSelection_chosen_float)
{
if(findtrajectorywithleading(self.origin, self.mins, self.maxs, self.enemy, 1000, 0, 10, 0, self))
{
self.velocity = findtrajectory_velocity;
- Damage(self.enemy, self, self, autocvar_g_monster_knight_jump_damage * monster_skill, DEATH_MONSTER_KNIGHT_CRUSH, self.enemy.origin, normalize(self.enemy.origin - self.origin));
+ Damage(self.enemy, self, self, MON_CVAR(knight, attack_jump_damage) * monster_skill, DEATH_MONSTER_KNIGHT_CRUSH, self.enemy.origin, normalize(self.enemy.origin - self.origin));
self.attack_finished_single = time + 2;
return TRUE;
}
monsters_setframe(anim);
self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, autocvar_g_monster_knight_melee_damage, 0.3, DEATH_MONSTER_KNIGHT_MELEE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(knight, attack_melee_damage), 0.3, DEATH_MONSTER_KNIGHT_MELEE, TRUE);
return TRUE;
}
void spawnfunc_monster_knight()
{
- if not(autocvar_g_monster_knight) { remove(self); return; }
-
self.classname = "monster_knight";
self.monster_spawnfunc = spawnfunc_monster_knight;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_knight_speed_run, autocvar_g_monster_knight_speed_walk, 100, knight_anim_run, knight_anim_walk, knight_anim_stand);
+ monster_move(MON_CVAR(knight, speed_run), MON_CVAR(knight, speed_walk), 100, knight_anim_run, knight_anim_walk, knight_anim_stand);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_knight_health;
+ if not(self.health) self.health = MON_CVAR(knight, health);
self.monster_attackfunc = knight_attack;
monsters_setframe(knight_anim_stand);
precache_sound ("player/lava.wav");
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(KNIGHT_SETTINGS(knight))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Mage")
);
+#define MAGE_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_spike_damage) \
+ MON_ADD_CVAR(monster, attack_spike_radius) \
+ MON_ADD_CVAR(monster, attack_spike_delay) \
+ MON_ADD_CVAR(monster, attack_melee_damage) \
+ MON_ADD_CVAR(monster, attack_melee_delay) \
+ MON_ADD_CVAR(monster, attack_grenade_damage) \
+ MON_ADD_CVAR(monster, attack_grenade_edgedamage) \
+ MON_ADD_CVAR(monster, attack_grenade_force) \
+ MON_ADD_CVAR(monster, attack_grenade_radius) \
+ MON_ADD_CVAR(monster, attack_grenade_lifetime) \
+ MON_ADD_CVAR(monster, attack_grenade_chance) \
+ MON_ADD_CVAR(monster, attack_grenade_speed) \
+ MON_ADD_CVAR(monster, attack_grenade_speed_up) \
+ MON_ADD_CVAR(monster, heal_self) \
+ MON_ADD_CVAR(monster, heal_allies) \
+ MON_ADD_CVAR(monster, heal_minhealth) \
+ MON_ADD_CVAR(monster, heal_range) \
+ MON_ADD_CVAR(monster, heal_delay) \
+ MON_ADD_CVAR(monster, shield_time) \
+ MON_ADD_CVAR(monster, shield_delay) \
+ MON_ADD_CVAR(monster, shield_blockpercent) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+MAGE_SETTINGS(mage)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_mage;
-float autocvar_g_monster_mage_health;
-float autocvar_g_monster_mage_speed;
-float autocvar_g_monster_mage_attack_spike_damage;
-float autocvar_g_monster_mage_attack_spike_radius;
-float autocvar_g_monster_mage_attack_spike_delay;
-float autocvar_g_monster_mage_attack_melee_damage;
-float autocvar_g_monster_mage_attack_melee_delay;
-float autocvar_g_monster_mage_heal_self;
-float autocvar_g_monster_mage_heal_friends;
-float autocvar_g_monster_mage_heal_minhealth;
-float autocvar_g_monster_mage_heal_range;
-float autocvar_g_monster_mage_heal_delay;
-float autocvar_g_monster_mage_shield_time;
-float autocvar_g_monster_mage_shield_delay;
-float autocvar_g_monster_mage_shield_blockpercent;
-float autocvar_g_monster_mage_attack_grenade_damage;
-float autocvar_g_monster_mage_attack_grenade_edgedamage;
-float autocvar_g_monster_mage_attack_grenade_radius;
-float autocvar_g_monster_mage_attack_grenade_lifetime;
-float autocvar_g_monster_mage_attack_grenade_force;
-float autocvar_g_monster_mage_attack_grenade_chance;
-
const float mage_anim_idle = 0;
const float mage_anim_walk = 1;
const float mage_anim_attack = 2;
return FALSE;
if(e.health <= 0)
return FALSE;
- if(vlen(e.origin - self.origin) > autocvar_g_monster_mage_heal_range)
+ if(vlen(e.origin - self.origin) > MON_CVAR(mage, heal_range))
return FALSE;
if(IsDifferentTeam(e, self))
return FALSE;
void mageattack_melee()
{
- monster_melee(self.enemy, autocvar_g_monster_mage_attack_melee_damage, 0.3, DEATH_MONSTER_MAGE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), 0.3, DEATH_MONSTER_MAGE, TRUE);
}
void mage_grenade_explode()
pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1);
sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
- RadiusDamage (self, self.realowner, autocvar_g_monster_mage_attack_grenade_damage, autocvar_g_monster_mage_attack_grenade_edgedamage, autocvar_g_monster_mage_attack_grenade_radius, world, autocvar_g_monster_mage_attack_grenade_force, DEATH_MONSTER_MAGE, other);
+ RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_grenade_damage), MON_CVAR(mage, attack_grenade_edgedamage), MON_CVAR(mage, attack_grenade_radius), world, MON_CVAR(mage, attack_grenade_force), DEATH_MONSTER_MAGE, other);
remove(self);
}
{
makevectors(self.angles);
- W_SetupShot_ProjectileSize (self, '-64 -64 -64', '64 64 64', FALSE, 4, "", CH_WEAPON_A, autocvar_g_monster_mage_attack_grenade_damage);
+ W_SetupShot_ProjectileSize (self, '-64 -64 -64', '64 64 64', FALSE, 4, "", CH_WEAPON_A, MON_CVAR(mage, attack_grenade_damage));
w_shotdir = v_forward; // no TrueAim for grenades please
entity gren = spawn ();
setorigin(gren, w_shotorg);
setsize(gren, '-64 -64 -64', '64 64 64');
- gren.nextthink = time + autocvar_g_monster_mage_attack_grenade_lifetime;
+ gren.nextthink = time + MON_CVAR(mage, attack_grenade_lifetime);
gren.think = mage_grenade_explode;
gren.use = mage_grenade_explode;
gren.touch = mage_grenade_touch;
gren.missile_flags = MIF_SPLASH | MIF_ARC;
- W_SETUPPROJECTILEVELOCITY_UP(gren, g_monster_mage_attack_grenade);
+ W_SetupProjectileVelocityEx(gren, w_shotdir, v_up, MON_CVAR(mage, attack_grenade_speed), MON_CVAR(mage, attack_grenade_speed_up), 0, 0, FALSE);
gren.flags = FL_PROJECTILE;
self.event_damage = func_null;
pointparticles(particleeffectnum("explosion_small"), self.origin, '0 0 0', 1);
- RadiusDamage (self, self.realowner, autocvar_g_monster_mage_attack_spike_damage, autocvar_g_monster_mage_attack_spike_damage * 0.5, autocvar_g_monster_mage_attack_spike_radius, world, 0, DEATH_MONSTER_MAGE, other);
+ RadiusDamage (self, self.realowner, MON_CVAR(mage, attack_spike_damage), MON_CVAR(mage, attack_spike_damage) * 0.5, MON_CVAR(mage, attack_spike_radius), world, 0, DEATH_MONSTER_MAGE, other);
remove (self);
}
switch(self.skin)
{
case 0:
- if(head.health < autocvar_g_balance_health_regenstable) head.health = bound(0, head.health + autocvar_g_monster_mage_heal_friends, autocvar_g_balance_health_regenstable);
+ if(head.health < autocvar_g_balance_health_regenstable) head.health = bound(0, head.health + MON_CVAR(mage, heal_allies), autocvar_g_balance_health_regenstable);
fx = "healing_fx";
break;
case 1:
case 2:
if(head.armorvalue < autocvar_g_balance_armor_regenstable)
{
- head.armorvalue = bound(0, head.armorvalue + autocvar_g_monster_mage_heal_friends, autocvar_g_balance_armor_regenstable);
+ head.armorvalue = bound(0, head.armorvalue + MON_CVAR(mage, heal_allies), autocvar_g_balance_armor_regenstable);
fx = "armorrepair_fx";
}
break;
case 3:
- head.health = bound(0, head.health - ((head == self) ? autocvar_g_monster_mage_heal_self : autocvar_g_monster_mage_heal_friends), autocvar_g_balance_health_regenstable);
+ head.health = bound(0, head.health - ((head == self) ? MON_CVAR(mage, heal_self) : MON_CVAR(mage, heal_allies)), autocvar_g_balance_health_regenstable);
fx = "rage";
break;
}
else
{
pointparticles(particleeffectnum("healing_fx"), head.origin, '0 0 0', 1);
- head.health = bound(0, head.health + autocvar_g_monster_mage_heal_friends, head.max_health);
+ head.health = bound(0, head.health + MON_CVAR(mage, heal_allies), head.max_health);
WaypointSprite_UpdateHealth(head.sprite, head.health);
}
}
if(washealed)
{
monsters_setframe(mage_anim_attack);
- self.attack_finished_single = time + autocvar_g_monster_mage_heal_delay;
+ self.attack_finished_single = time + MON_CVAR(mage, heal_delay);
}
}
shield.owner = self;
shield.team = self.team;
- shield.ltime = time + autocvar_g_monster_mage_shield_time;
+ shield.ltime = time + MON_CVAR(mage, shield_time);
shield.health = 70;
shield.classname = "shield";
shield.effects = EF_ADDITIVE;
self.weaponentity = shield;
- self.lastshielded = time + autocvar_g_monster_mage_shield_delay;
+ self.lastshielded = time + MON_CVAR(mage, shield_delay);
monsters_setframe(mage_anim_attack);
self.attack_finished_single = time + 1;
- self.armorvalue = autocvar_g_monster_mage_shield_blockpercent / 100;
+ self.armorvalue = MON_CVAR(mage, shield_blockpercent) / 100;
}
float mage_attack(float attack_type)
case MONSTER_ATTACK_MELEE:
{
monsters_setframe(mage_anim_attack);
- self.attack_finished_single = time + autocvar_g_monster_mage_attack_melee_delay;
+ self.attack_finished_single = time + MON_CVAR(mage, attack_melee_delay);
defer(0.2, mageattack_melee);
return TRUE;
}
case MONSTER_ATTACK_RANGED:
{
- if(random() < autocvar_g_monster_mage_attack_grenade_chance / 100)
+ if(random() < MON_CVAR(mage, attack_grenade_chance) / 100)
{
mage_throw_itemgrenade();
return TRUE;
}
monsters_setframe(mage_anim_attack);
- self.attack_finished_single = time + autocvar_g_monster_mage_attack_spike_delay;
+ self.attack_finished_single = time + MON_CVAR(mage, attack_spike_delay);
defer(0.2, mage_spike);
return TRUE;
void spawnfunc_monster_mage()
{
- if not(autocvar_g_monster_mage) { remove(self); return; }
-
self.classname = "monster_mage";
self.monster_spawnfunc = spawnfunc_monster_mage;
if(time >= self.weaponentity.ltime)
mage_shield_die();
- if(self.health < autocvar_g_monster_mage_heal_minhealth || need_help)
+ if(self.health < MON_CVAR(mage, heal_minhealth) || need_help)
if(time >= self.attack_finished_single)
if(random() < 0.5)
mage_heal();
if(random() < 0.5)
mage_shield();
- monster_move(autocvar_g_monster_mage_speed, autocvar_g_monster_mage_speed, 50, mage_anim_walk, mage_anim_run, mage_anim_idle);
+ monster_move(MON_CVAR(mage, speed_run), MON_CVAR(mage, speed_walk), 50, mage_anim_walk, mage_anim_run, mage_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_mage_health;
+ if not(self.health) self.health = MON_CVAR(mage, health);
self.monster_attackfunc = mage_attack;
monsters_setframe(mage_anim_walk);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(MAGE_SETTINGS(mage))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Shambler")
);
+#define SHAMBLER_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_smash_damage) \
+ MON_ADD_CVAR(monster, attack_claw_damage) \
+ MON_ADD_CVAR(monster, attack_lightning_damage) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+SHAMBLER_SETTINGS(shambler)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_shambler;
-float autocvar_g_monster_shambler_health;
-float autocvar_g_monster_shambler_damage;
-float autocvar_g_monster_shambler_attack_lightning_damage;
-float autocvar_g_monster_shambler_attack_claw_damage;
-float autocvar_g_monster_shambler_speed_walk;
-float autocvar_g_monster_shambler_speed_run;
-
const float shambler_anim_stand = 0;
const float shambler_anim_walk = 1;
const float shambler_anim_run = 2;
void shambler_smash()
{
- monster_melee(self.enemy, autocvar_g_monster_shambler_damage, 0.3, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_smash_damage), 0.3, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
}
void shambler_delayedsmash()
{
float r = (random() < 0.5);
monsters_setframe((r) ? shambler_anim_swingr : shambler_anim_swingl);
- monster_melee(self.enemy, autocvar_g_monster_shambler_attack_claw_damage, 0.3, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_claw_damage), 0.3, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
self.attack_finished_single = time + 0.8;
if(r)
defer(0.5, shambler_swing);
traceline (org, self.origin + dir * 1000, TRUE, self);
- FireRailgunBullet (org, org + dir * 1000, autocvar_g_monster_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_skill, 0, 0, 0, 0, 0, DEATH_MONSTER_SHAMBLER_ZAP);
// teamcolor / hit beam effect
//v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
void spawnfunc_monster_shambler()
{
- if not(autocvar_g_monster_shambler) { remove(self); return; }
-
self.classname = "monster_shambler";
self.monster_spawnfunc = spawnfunc_monster_shambler;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_shambler_speed_run, autocvar_g_monster_shambler_speed_walk, 300, shambler_anim_run, shambler_anim_walk, shambler_anim_stand);
+ monster_move(MON_CVAR(shambler, speed_run), MON_CVAR(shambler, speed_walk), 300, shambler_anim_run, shambler_anim_walk, shambler_anim_stand);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_shambler_health;
+ if not(self.health) self.health = MON_CVAR(shambler, health);
self.monster_attackfunc = shambler_attack;
monsters_setframe(shambler_anim_stand);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(SHAMBLER_SETTINGS(shambler))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Slime")
);
+#define SLIME_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_explode_damage) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+SLIME_SETTINGS(slime)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_slime;
-float autocvar_g_monster_slime_health;
-float autocvar_g_monster_slime_speed_walk;
-float autocvar_g_monster_slime_speed_run;
-
const float slime_anim_walk = 0;
const float slime_anim_idle = 1;
const float slime_anim_jump = 2;
if(other.takedamage)
if(vlen(self.velocity) > 200)
{
- Damage (self, world, world, self.health + self.max_health + 200, DEATH_MONSTER_SLIME, self.origin, '0 0 0');
+ Damage (self, world, world, MON_CVAR(slime, attack_explode_damage), DEATH_MONSTER_SLIME, self.origin, '0 0 0');
return;
}
void slime_explode()
{
- RadiusDamage(self, self, 250 * monster_skill, 15, 250 * (monster_skill * 0.7), world, 250, DEATH_MONSTER_SLIME, world);
+ RadiusDamage(self, self, MON_CVAR(slime, attack_explode_damage), 15, MON_CVAR(slime, attack_explode_damage) * 0.7, world, 250, DEATH_MONSTER_SLIME, world);
pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
self.health = -100; // gibbed
slime_explode();
- Monster_CheckDropCvars ("slime"); // TODO: add a special function to drop items after death
+ Monster_CheckDropCvars (self.netname); // TODO: add a special function to drop items after death
self.deadflag = DEAD_DEAD;
self.think = Monster_Fade;
void spawnfunc_monster_slime()
{
- if not(autocvar_g_monster_slime) { remove(self); return; }
-
self.classname = "monster_slime";
self.monster_spawnfunc = spawnfunc_monster_slime;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_slime_speed_run, autocvar_g_monster_slime_speed_walk, 20, slime_anim_walk, slime_anim_walk, slime_anim_idle);
+ monster_move(MON_CVAR(slime, speed_run), MON_CVAR(slime, speed_walk), 20, slime_anim_walk, slime_anim_walk, slime_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_slime_health;
+ if not(self.health) self.health = MON_CVAR(slime, health);
self.monster_attackfunc = slime_attack;
monsters_setframe(slime_anim_idle);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(SLIME_SETTINGS(slime))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Spider")
);
+#define SPIDER_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_bite_damage) \
+ MON_ADD_CVAR(monster, attack_bite_delay) \
+ MON_ADD_CVAR(monster, attack_web_damagetime) \
+ MON_ADD_CVAR(monster, attack_web_speed) \
+ MON_ADD_CVAR(monster, attack_web_speed_up) \
+ MON_ADD_CVAR(monster, attack_web_delay) \
+ MON_ADD_CVAR(monster, attack_type) \
+ MON_ADD_CVAR(monster, speed_stop) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+SPIDER_SETTINGS(spider)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_spider;
-float autocvar_g_monster_spider_stopspeed;
-float autocvar_g_monster_spider_attack_leap_delay;
-float autocvar_g_monster_spider_attack_stand_damage;
-float autocvar_g_monster_spider_attack_stand_delay;
-float autocvar_g_monster_spider_attack_fire_time;
-float autocvar_g_monster_spider_health;
-float autocvar_g_monster_spider_speed_walk;
-float autocvar_g_monster_spider_speed_run;
-float autocvar_g_monster_spider_attack_type;
-
const float spider_anim_idle = 0;
const float spider_anim_walk = 1;
const float spider_anim_attack = 2;
Freeze(e, 0.3, 2, FALSE);
break;
case SPIDER_TYPE_FIRE:
- Fire_AddDamage(e, self.realowner, 5 * monster_skill, autocvar_g_monster_spider_attack_fire_time, DEATH_MONSTER_SPIDER_FIRE);
+ Fire_AddDamage(e, self.realowner, 5 * monster_skill, MON_CVAR(spider, attack_web_damagetime), DEATH_MONSTER_SPIDER_FIRE);
break;
}
}
//proj.glow_size = 50;
//proj.glow_color = 45;
proj.movetype = MOVETYPE_BOUNCE;
- W_SETUPPROJECTILEVELOCITY_UP(proj, g_monster_spider_attack_web);
+ W_SetupProjectileVelocityEx(proj, w_shotdir, v_up, MON_CVAR(spider, attack_web_speed), MON_CVAR(spider, attack_web_speed_up), 0, 0, FALSE);
proj.touch = spider_web_touch;
setsize(proj, fmins, fmaxs);
proj.takedamage = DAMAGE_NO;
{
case MONSTER_ATTACK_MELEE:
{
- monster_melee(self.enemy, autocvar_g_monster_spider_attack_stand_damage, 0.3, DEATH_MONSTER_SPIDER, TRUE);
+ monster_melee(self.enemy, MON_CVAR(spider, attack_bite_damage), 0.3, DEATH_MONSTER_SPIDER, TRUE);
monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
- self.attack_finished_single = time + autocvar_g_monster_spider_attack_stand_delay;
+ self.attack_finished_single = time + MON_CVAR(spider, attack_bite_delay);
return TRUE;
}
return FALSE;
monsters_setframe(spider_anim_attack2);
- self.attack_finished_single = time + autocvar_g_monster_spider_attack_leap_delay;
+ self.attack_finished_single = time + MON_CVAR(spider, attack_web_delay);
monster_makevectors(self.enemy);
spider_shootweb(self.spider_type);
void spawnfunc_monster_spider()
{
- if not(autocvar_g_monster_spider) { remove(self); return; }
-
self.classname = "monster_spider";
self.monster_spawnfunc = spawnfunc_monster_spider;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_spider_speed_run, autocvar_g_monster_spider_speed_walk, autocvar_g_monster_spider_stopspeed, spider_anim_walk, spider_anim_walk, spider_anim_idle);
+ monster_move(MON_CVAR(spider, speed_run), MON_CVAR(spider, speed_walk), MON_CVAR(spider, speed_stop), spider_anim_walk, spider_anim_walk, spider_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_spider_health;
- if not(self.spider_type) self.spider_type = autocvar_g_monster_spider_attack_type;
+ if not(self.health) self.health = MON_CVAR(spider, health);
+ if not(self.spider_type) self.spider_type = MON_CVAR(spider, attack_type);
self.monster_attackfunc = spider_attack;
monsters_setframe(spider_anim_idle);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(SPIDER_SETTINGS(spider))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Stingray")
);
+#define STINGRAY_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_bite_damage) \
+ MON_ADD_CVAR(monster, attack_bite_delay) \
+ MON_ADD_CVAR(monster, speed_stop) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+STINGRAY_SETTINGS(stingray)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_stingray;
-float autocvar_g_monster_stingray_health;
-float autocvar_g_monster_stingray_damage;
-float autocvar_g_monster_stingray_speed_walk;
-float autocvar_g_monster_stingray_speed_run;
-
const float stingray_anim_attack = 0;
const float stingray_anim_death = 1;
const float stingray_anim_swim = 2;
case MONSTER_ATTACK_MELEE:
{
monsters_setframe(stingray_anim_attack);
- self.attack_finished_single = time + 0.5;
- monster_melee(self.enemy, autocvar_g_monster_stingray_damage, 0.1, DEATH_MONSTER_STINGRAY, FALSE);
+ self.attack_finished_single = time + MON_CVAR(stingray, attack_bite_delay);
+ monster_melee(self.enemy, MON_CVAR(stingray, attack_bite_damage), 0.1, DEATH_MONSTER_STINGRAY, FALSE);
return TRUE;
}
void spawnfunc_monster_stingray()
{
- if not(autocvar_g_monster_stingray) { remove(self); return; }
-
self.classname = "monster_stingray";
self.monster_spawnfunc = spawnfunc_monster_stingray;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_stingray_speed_run, autocvar_g_monster_stingray_speed_walk, 10, stingray_anim_swim, stingray_anim_swim, stingray_anim_swim);
+ monster_move(MON_CVAR(stingray, speed_run), MON_CVAR(stingray, speed_walk), MON_CVAR(stingray, speed_stop), stingray_anim_swim, stingray_anim_swim, stingray_anim_swim);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_stingray_health;
+ if not(self.health) self.health = MON_CVAR(stingray, health);
self.monster_attackfunc = stingray_attack;
monsters_setframe(stingray_anim_swim);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(STINGRAY_SETTINGS(stingray))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Wyvern")
);
+#define WYVERN_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_fireball_damage) \
+ MON_ADD_CVAR(monster, attack_fireball_edgedamage) \
+ MON_ADD_CVAR(monster, attack_fireball_damagetime) \
+ MON_ADD_CVAR(monster, attack_fireball_force) \
+ MON_ADD_CVAR(monster, attack_fireball_radius) \
+ MON_ADD_CVAR(monster, attack_fireball_speed) \
+ MON_ADD_CVAR(monster, speed_stop) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+WYVERN_SETTINGS(wyvern)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_wyvern;
-float autocvar_g_monster_wyvern_health;
-float autocvar_g_monster_wyvern_speed_walk;
-float autocvar_g_monster_wyvern_speed_run;
-float autocvar_g_monster_wyvern_fireball_damage;
-float autocvar_g_monster_wyvern_fireball_force;
-float autocvar_g_monster_wyvern_fireball_radius;
-float autocvar_g_monster_wyvern_fireball_edgedamage;
-float autocvar_g_monster_wyvern_fireball_damagetime;
-float autocvar_g_monster_wyvern_fireball_speed;
-
const float wyvern_anim_hover = 0;
const float wyvern_anim_fly = 1;
const float wyvern_anim_magic = 2;
{
pointparticles(particleeffectnum("fireball_explode"), self.origin, '0 0 0', 1);
- RadiusDamage(self, self.realowner, autocvar_g_monster_wyvern_fireball_damage, autocvar_g_monster_wyvern_fireball_edgedamage, autocvar_g_monster_wyvern_fireball_force, world, autocvar_g_monster_wyvern_fireball_radius, self.projectiledeathtype, world);
+ 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) <= autocvar_g_monster_wyvern_fireball_radius)
- Fire_AddDamage(e, self, 5 * monster_skill, autocvar_g_monster_wyvern_fireball_damagetime, self.projectiledeathtype);
+ 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);
remove(self);
}
setsize(missile, '-6 -6 -6', '6 6 6');
setorigin(missile, self.origin + self.view_ofs + v_forward * 14);
missile.flags = FL_PROJECTILE;
- missile.velocity = dir * autocvar_g_monster_wyvern_fireball_speed;
+ missile.velocity = dir * MON_CVAR(wyvern, attack_fireball_speed);
missile.avelocity = '300 300 300';
missile.nextthink = time + 5;
missile.think = wyvern_fireball_explode;
void spawnfunc_monster_wyvern()
{
- if not(autocvar_g_monster_wyvern) { remove(self); return; }
-
self.classname = "monster_wyvern";
self.monster_spawnfunc = spawnfunc_monster_wyvern;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_wyvern_speed_run, autocvar_g_monster_wyvern_speed_walk, 300, wyvern_anim_fly, wyvern_anim_hover, wyvern_anim_hover);
+ monster_move(MON_CVAR(wyvern, speed_run), MON_CVAR(wyvern, speed_walk), MON_CVAR(wyvern, speed_stop), wyvern_anim_fly, wyvern_anim_hover, wyvern_anim_hover);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_wyvern_health;
+ if not(self.health) self.health = MON_CVAR(wyvern, health);
self.monster_attackfunc = wyvern_attack;
monsters_setframe(wyvern_anim_hover);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(WYVERN_SETTINGS(wyvern))
+ return TRUE;
+ }
}
return TRUE;
/* fullname */ _("Zombie")
);
+#define ZOMBIE_SETTINGS(monster) \
+ MON_ADD_CVAR(monster, health) \
+ MON_ADD_CVAR(monster, attack_melee_damage) \
+ MON_ADD_CVAR(monster, attack_melee_delay) \
+ MON_ADD_CVAR(monster, attack_leap_damage) \
+ MON_ADD_CVAR(monster, attack_leap_force) \
+ MON_ADD_CVAR(monster, attack_leap_speed) \
+ MON_ADD_CVAR(monster, attack_leap_delay) \
+ MON_ADD_CVAR(monster, speed_stop) \
+ MON_ADD_CVAR(monster, speed_run) \
+ MON_ADD_CVAR(monster, speed_walk)
+
+#ifdef SVQC
+ZOMBIE_SETTINGS(zombie)
+#endif // SVQC
#else
#ifdef SVQC
-float autocvar_g_monster_zombie;
-float autocvar_g_monster_zombie_stopspeed;
-float autocvar_g_monster_zombie_attack_leap_damage;
-float autocvar_g_monster_zombie_attack_leap_delay;
-float autocvar_g_monster_zombie_attack_leap_force;
-float autocvar_g_monster_zombie_attack_leap_speed;
-float autocvar_g_monster_zombie_attack_stand_damage;
-float autocvar_g_monster_zombie_attack_stand_delay;
-float autocvar_g_monster_zombie_health;
-float autocvar_g_monster_zombie_speed_walk;
-float autocvar_g_monster_zombie_speed_run;
-
const float zombie_anim_attackleap = 0;
const float zombie_anim_attackrun1 = 1;
const float zombie_anim_attackrun2 = 2;
if(other.takedamage)
{
angles_face = vectoangles(self.moveto - self.origin);
- angles_face = normalize(angles_face) * autocvar_g_monster_zombie_attack_leap_force;
- Damage(other, self, self, autocvar_g_monster_zombie_attack_leap_damage * monster_skill, DEATH_MONSTER_ZOMBIE_JUMP, other.origin, angles_face);
+ 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);
self.touch = MonsterTouch; // instantly turn it off to stop damage spam
}
monsters_setframe(chosen_anim);
- self.attack_finished_single = time + autocvar_g_monster_zombie_attack_stand_delay;
+ self.attack_finished_single = time + MON_CVAR(zombie, attack_melee_delay);
- monster_melee(self.enemy, autocvar_g_monster_zombie_attack_stand_damage, 0.3, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), 0.3, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
return TRUE;
}
case MONSTER_ATTACK_RANGED:
{
makevectors(self.angles);
- if(monster_leap(zombie_anim_attackleap, zombie_attack_leap_touch, v_forward * autocvar_g_monster_zombie_attack_leap_speed + '0 0 200', autocvar_g_monster_zombie_attack_leap_delay))
+ if(monster_leap(zombie_anim_attackleap, zombie_attack_leap_touch, v_forward * MON_CVAR(zombie, attack_leap_speed) + '0 0 200', MON_CVAR(zombie, attack_leap_delay)))
return TRUE;
}
}
void spawnfunc_monster_zombie()
{
- if not(autocvar_g_monster_zombie) { remove(self); return; }
-
self.classname = "monster_zombie";
self.monster_spawnfunc = spawnfunc_monster_zombie;
{
case MR_THINK:
{
- monster_move(autocvar_g_monster_zombie_speed_run, autocvar_g_monster_zombie_speed_walk, autocvar_g_monster_zombie_stopspeed, zombie_anim_runforward, zombie_anim_runforward, zombie_anim_idle);
+ monster_move(MON_CVAR(zombie, speed_run), MON_CVAR(zombie, speed_walk), MON_CVAR(zombie, speed_stop), zombie_anim_runforward, zombie_anim_runforward, zombie_anim_idle);
return TRUE;
}
case MR_DEATH:
}
case MR_SETUP:
{
- if not(self.health) self.health = autocvar_g_monster_zombie_health;
+ if not(self.health) self.health = MON_CVAR(zombie, health);
self.monster_attackfunc = zombie_attack;
monsters_setframe(zombie_anim_spawn);
// nothing
return TRUE;
}
+ case MR_CONFIG:
+ {
+ MON_CONFIG_SETTINGS(ZOMBIE_SETTINGS(zombie))
+ return TRUE;
+ }
}
return TRUE;
#define MON_ADD_CVAR(monster,name) \
MON_DUPECHECK(MON_CVAR_##monster##_##name, autocvar_g_monster_##monster##_##name)
-#define MON_CVAR(monster,name) autocvar_g_balance_##monster##_##name
-
-#define MON_ADD_PROP(monster,prop,name) \
- .float ##prop; \
- MON_DUPECHECK(MON_CVAR_##monster##_##name, autocvar_g_monster_##monster##_##name)
-
-#define MON_SET_PROP(wepid,monster,prop,name) get_monsterinfo(##wepid).##prop = autocvar_g_monster_##monster##_##name;
-
-#define MON_SET_PROPS(monsettings,wepid) \
- #define MON_ADD_CVAR(monster,mode,name) \
- #define MON_ADD_PROP(monster,prop,name) MON_SET_PROP(wepid,monster,prop,name) \
- monsettings \
- #undef MON_ADD_CVAR \
- #undef MON_ADD_PROP
+#define MON_CVAR(monster,name) autocvar_g_monster_##monster##_##name
#include "all.qh"
#undef MON_ADD_CVAR
-#undef MON_ADD_PROP
#undef REGISTER_MONSTER
ACCUMULATE_FUNCTION(RegisterMonsters, register_monsters_done)
../common/command/shared_defs.qh
../common/net_notice.qh
../common/animdecide.qh
+
+../common/monsters/config.qh
../common/monsters/monsters.qh
+
autocvars.qh
constants.qh
defs.qh // Should rename this, it has fields and globals
../common/explosion_equation.qc
+../common/monsters/config.qc
../common/monsters/monsters.qc
mutators/base.qc