#ifdef REGISTER_WEAPON
REGISTER_WEAPON(
-/* WEP_##id */ DEVASTATOR,
-/* function */ W_Devastator,
-/* ammotype */ IT_ROCKETS,
-/* impulse */ 9,
-/* flags */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
-/* rating */ BOT_PICKUP_RATING_HIGH,
-/* model */ "rl",
-/* netname */ "devastator",
-/* fullname */ _("Devastator")
+/* WEP_##id */ DEVASTATOR,
+/* function */ W_Devastator,
+/* ammotype */ ammo_rockets,
+/* impulse */ 9,
+/* flags */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
+/* rating */ BOT_PICKUP_RATING_HIGH,
+/* color */ '1 1 0',
+/* model */ "rl",
+/* crosshair */ "gfx/crosshairrocketlauncher 0.5875",
+/* refname */ "devastator",
+/* wepname */ _("Devastator")
);
-#define DEVASTATOR_SETTINGS(weapon) \
- WEP_ADD_CVAR(weapon, MO_NONE, ammo) \
- WEP_ADD_CVAR(weapon, MO_NONE, animtime) \
- WEP_ADD_CVAR(weapon, MO_NONE, damage) \
- WEP_ADD_CVAR(weapon, MO_NONE, damageforcescale) \
- WEP_ADD_CVAR(weapon, MO_NONE, detonatedelay) \
- WEP_ADD_CVAR(weapon, MO_NONE, edgedamage) \
- WEP_ADD_CVAR(weapon, MO_NONE, force) \
- WEP_ADD_CVAR(weapon, MO_NONE, guidedelay) \
- WEP_ADD_CVAR(weapon, MO_NONE, guidegoal) \
- WEP_ADD_CVAR(weapon, MO_NONE, guiderate) \
- WEP_ADD_CVAR(weapon, MO_NONE, guideratedelay) \
- WEP_ADD_CVAR(weapon, MO_NONE, guidestop) \
- WEP_ADD_CVAR(weapon, MO_NONE, health) \
- WEP_ADD_CVAR(weapon, MO_NONE, lifetime) \
- WEP_ADD_CVAR(weapon, MO_NONE, radius) \
- WEP_ADD_CVAR(weapon, MO_NONE, refire) \
- WEP_ADD_CVAR(weapon, MO_NONE, remote_damage) \
- WEP_ADD_CVAR(weapon, MO_NONE, remote_edgedamage) \
- WEP_ADD_CVAR(weapon, MO_NONE, remote_force) \
- WEP_ADD_CVAR(weapon, MO_NONE, remote_radius) \
- WEP_ADD_CVAR(weapon, MO_NONE, speed) \
- WEP_ADD_CVAR(weapon, MO_NONE, speedaccel) \
- WEP_ADD_CVAR(weapon, MO_NONE, speedstart) \
- WEP_ADD_PROP(weapon, reloading_ammo, reload_ammo) \
- WEP_ADD_PROP(weapon, reloading_time, reload_time) \
- WEP_ADD_PROP(weapon, switchdelay_raise, switchdelay_raise) \
- WEP_ADD_PROP(weapon, switchdelay_drop, switchdelay_drop)
+#define DEVASTATOR_SETTINGS(w_cvar,w_prop) DEVASTATOR_SETTINGS_LIST(w_cvar, w_prop, DEVASTATOR, devastator)
+#define DEVASTATOR_SETTINGS_LIST(w_cvar,w_prop,id,sn) \
+ w_cvar(id, sn, NONE, ammo) \
+ w_cvar(id, sn, NONE, animtime) \
+ w_cvar(id, sn, NONE, damage) \
+ w_cvar(id, sn, NONE, damageforcescale) \
+ w_cvar(id, sn, NONE, detonatedelay) \
+ w_cvar(id, sn, NONE, edgedamage) \
+ w_cvar(id, sn, NONE, force) \
+ w_cvar(id, sn, NONE, guidedelay) \
+ w_cvar(id, sn, NONE, guidegoal) \
+ w_cvar(id, sn, NONE, guiderate) \
+ w_cvar(id, sn, NONE, guideratedelay) \
+ w_cvar(id, sn, NONE, guidestop) \
+ w_cvar(id, sn, NONE, health) \
+ w_cvar(id, sn, NONE, lifetime) \
+ w_cvar(id, sn, NONE, radius) \
+ w_cvar(id, sn, NONE, refire) \
+ w_cvar(id, sn, NONE, remote_damage) \
+ w_cvar(id, sn, NONE, remote_edgedamage) \
+ w_cvar(id, sn, NONE, remote_force) \
+ w_cvar(id, sn, NONE, remote_radius) \
+ w_cvar(id, sn, NONE, speed) \
+ w_cvar(id, sn, NONE, speedaccel) \
+ w_cvar(id, sn, NONE, speedstart) \
+ w_prop(id, sn, float, reloading_ammo, reload_ammo) \
+ w_prop(id, sn, float, reloading_time, reload_time) \
+ w_prop(id, sn, float, switchdelay_raise, switchdelay_raise) \
+ w_prop(id, sn, float, switchdelay_drop, switchdelay_drop) \
+ w_prop(id, sn, string, weaponreplace, weaponreplace) \
+ w_prop(id, sn, float, weaponstart, weaponstart) \
+ w_prop(id, sn, float, weaponstartoverride, weaponstartoverride)
#ifdef SVQC
-DEVASTATOR_SETTINGS(devastator)
+DEVASTATOR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP)
.float rl_release;
.float rl_detonate_later;
#endif
if(other.takedamage == DAMAGE_AIM)
if(IS_PLAYER(other))
- if(IsDifferentTeam(self.realowner, other))
+ if(DIFF_TEAM(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
if (self.realowner.weapon == WEP_DEVASTATOR)
{
- if(self.realowner.ammo_rockets < WEP_CVAR(devastator, ammo))
+ if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
{
self.realowner.cnt = WEP_DEVASTATOR;
ATTACK_FINISHED(self.realowner) = time;
if (self.realowner.weapon == WEP_DEVASTATOR)
{
- if(self.realowner.ammo_rockets < WEP_CVAR(devastator, ammo))
+ if(self.realowner.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
{
self.realowner.cnt = WEP_DEVASTATOR;
ATTACK_FINISHED(self.realowner) = time;
if (self.realowner.weapon == WEP_DEVASTATOR)
{
if(self == self.realowner.lastrocket)
- if not(self.realowner.rl_release)
- if not(self.BUTTON_ATCK2)
+ if(!self.realowner.rl_release)
+ if(!self.BUTTON_ATCK2)
if(WEP_CVAR(devastator, guiderate))
if(time > self.pushltime)
if(self.realowner.deadflag == DEAD_NO)
entity missile;
entity flash;
- W_DecreaseAmmo(ammo_rockets, WEP_CVAR(devastator, ammo), WEP_CVAR(devastator, reload_ammo));
+ W_DecreaseAmmo(WEP_CVAR(devastator, ammo));
W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", CH_WEAPON_A, WEP_CVAR(devastator, damage));
pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
setorigin (missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
- W_SetupProjectileVelocity(missile, WEP_CVAR(devastator, speedstart), 0);
+ W_SetupProjVelocity_Basic(missile, WEP_CVAR(devastator, speedstart), 0);
missile.angles = vectoangles (missile.velocity);
missile.touch = W_Devastator_Touch;
{
// decide whether to detonate rockets
entity missile, targetlist, targ;
- float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
- float selfdamage, teamdamage, enemydamage;
- edgedamage = WEP_CVAR(devastator, edgedamage);
- coredamage = WEP_CVAR(devastator, damage);
- edgeradius = WEP_CVAR(devastator, radius);
- recipricoledgeradius = 1 / edgeradius;
- selfdamage = 0;
- teamdamage = 0;
- enemydamage = 0;
targetlist = findchainfloat(bot_attack, TRUE);
- missile = find(world, classname, "rocket");
- while (missile)
+ for(missile = world; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == self)
{
- if (missile.realowner != self)
- {
- missile = find(missile, classname, "rocket");
- continue;
- }
targ = targetlist;
- while (targ)
- {
- d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - missile.origin);
- d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
- // count potential damage according to type of target
- if (targ == self)
- selfdamage = selfdamage + d;
- else if (targ.team == self.team && teamplay)
- teamdamage = teamdamage + d;
- else if (bot_shouldattack(targ))
- enemydamage = enemydamage + d;
- targ = targ.chain;
- }
- missile = find(missile, classname, "rocket");
- }
- float desirabledamage;
- desirabledamage = enemydamage;
- if (time > self.invincible_finished && time > self.spawnshieldtime)
- desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
- if (teamplay && self.team)
- desirabledamage = desirabledamage - teamdamage;
-
- missile = find(world, classname, "rocket");
- while (missile)
- {
- if (missile.realowner != self)
+ while(targ)
{
- missile = find(missile, classname, "rocket");
- continue;
- }
- makevectors(missile.v_angle);
- targ = targetlist;
- if (skill > 9) // normal players only do this for the target they are tracking
- {
- targ = targetlist;
- while (targ)
+ if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
{
- if (
- (v_forward * normalize(missile.origin - targ.origin)< 0.1)
- && desirabledamage > 0.1*coredamage
- )self.BUTTON_ATCK2 = TRUE;
- targ = targ.chain;
+ self.BUTTON_ATCK2 = TRUE;
+ break;
}
- }else{
- float distance; distance= bound(300,vlen(self.origin-self.enemy.origin),30000);
- //As the distance gets larger, a correct detonation gets near imposible
- //Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
- if(v_forward * normalize(missile.origin - self.enemy.origin)< 0.1)
- if(IS_PLAYER(self.enemy))
- if(desirabledamage >= 0.1*coredamage)
- if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
- self.BUTTON_ATCK2 = TRUE;
- // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
+ targ = targ.chain;
}
-
- missile = find(missile, classname, "rocket");
}
- // if we would be doing at X percent of the core damage, detonate it
- // but don't fire a new shot at the same time!
- if (desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
- self.BUTTON_ATCK2 = TRUE;
- if ((skill > 6.5) && (selfdamage > self.health))
- self.BUTTON_ATCK2 = FALSE;
- //if(self.BUTTON_ATCK2 == TRUE)
- // dprint(ftos(desirabledamage),"\n");
- if (self.BUTTON_ATCK2 == TRUE) self.BUTTON_ATCK = FALSE;
+
+ if(self.BUTTON_ATCK2) self.BUTTON_ATCK = FALSE;
}
return TRUE;
WEP_ACTION(self.weapon, WR_RELOAD);
else
{
- if (self.BUTTON_ATCK)
+ if(self.BUTTON_ATCK)
{
if(self.rl_release || WEP_CVAR(devastator, guidestop))
if(weapon_prepareattack(0, WEP_CVAR(devastator, refire)))
else
self.rl_release = 1;
- if (self.BUTTON_ATCK2)
+ if(self.BUTTON_ATCK2)
{
rockfound = 0;
for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == self)
precache_sound("weapons/rocket_fire.wav");
precache_sound("weapons/rocket_mode.wav");
}
-
- #define WEP_ADD_CVAR(weapon,mode,name) /*nothing*/
- #define WEP_ADD_PROP(weapon,prop,name) WEP_SET_PROP(WEP_DEVASTATOR,weapon,prop,name)
- ARC_SETTINGS(devastator)
- #undef WEP_ADD_CVAR
- #undef WEP_ADD_PROP
-
- return TRUE;
- }
- case WR_CONFIG:
- {
- #define WEP_ADD_CVAR(weapon,mode,name) WEP_CONFIG_WRITE_CVARS(weapon,mode,name)
- #define WEP_ADD_PROP(weapon,prop,name) WEP_CONFIG_WRITE_PROPS(weapon,prop,name)
- DEVASTATOR_SETTINGS(devastator)
- #undef WEP_ADD_CVAR
- #undef WEP_ADD_PROP
+ DEVASTATOR_SETTINGS(WEP_SKIPCVAR, WEP_SET_PROP)
return TRUE;
}
case WR_SETUP:
{
- weapon_setup(WEP_DEVASTATOR);
- self.current_ammo = ammo_rockets;
self.rl_release = 1;
return TRUE;
}
ammo_amount = FALSE;
if(WEP_CVAR(devastator, reload_ammo))
{
- if(self.ammo_rockets < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR]) < WEP_CVAR(devastator, ammo))
+ if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo) && self.(weapon_load[WEP_DEVASTATOR]) < WEP_CVAR(devastator, ammo))
ammo_amount = TRUE;
}
- else if(self.ammo_rockets < WEP_CVAR(devastator, ammo))
+ else if(self.WEP_AMMO(DEVASTATOR) < WEP_CVAR(devastator, ammo))
ammo_amount = TRUE;
return !ammo_amount;
}
{
return FALSE;
}
+ case WR_CONFIG:
+ {
+ DEVASTATOR_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS)
+ return TRUE;
+ }
case WR_RESETPLAYER:
{
self.rl_release = 0;
}
case WR_RELOAD:
{
- W_Reload(WEP_CVAR(devastator, ammo), WEP_CVAR(devastator, reload_ammo), WEP_CVAR(devastator, reload_time), "weapons/reload.wav");
+ W_Reload(WEP_CVAR(devastator, ammo), "weapons/reload.wav");
return TRUE;
}
case WR_SUICIDEMESSAGE:
precache_sound("weapons/rocket_impact.wav");
return TRUE;
}
+ case WR_ZOOMRETICLE:
+ {
+ // no weapon specific image for this weapon
+ return FALSE;
+ }
}
return TRUE;
}