19 newmine.owner = this.
owner;
24 setorigin(newmine, this.
origin);
25 setmodel(newmine, MDL_MINELAYER_MINE);
26 setsize(newmine,
'-4 -4 -4',
'4 4 4');
34 newmine.event_damage = this.event_damage;
36 newmine.damagedbycontents =
true;
46 newmine.nextthink =
time;
47 newmine.cnt = this.
cnt;
48 newmine.flags = this.
flags;
70 WEP_CVAR(WEP_MINE_LAYER, edgedamage),
81 Weapon thiswep = WEP_MINE_LAYER;
82 if (this.
realowner.(weaponentity).m_weapon == thiswep)
88 own.cnt = thiswep.
m_id;
111 WEP_CVAR(WEP_MINE_LAYER, remote_damage),
112 WEP_CVAR(WEP_MINE_LAYER, remote_edgedamage),
113 WEP_CVAR(WEP_MINE_LAYER, remote_radius),
116 WEP_CVAR(WEP_MINE_LAYER, remote_force),
123 Weapon thiswep = WEP_MINE_LAYER;
124 if (this.
realowner.(weaponentity).m_weapon == thiswep)
130 own.cnt = thiswep.
m_id;
160 for (; head; head = head.chain)
174 for (; head; head = head.chain)
185 IL_EACH(
g_mines, it.realowner == e && it.weaponentity_fld == weaponentity, ++minecount);
208 if (
WEP_CVAR(WEP_MINE_LAYER, lifetime_countdown) > 0)
223 float time_core =
WEP_CVAR(WEP_MINE_LAYER, proximity_time_core);
224 float time_edge =
WEP_CVAR(WEP_MINE_LAYER, proximity_time_edge);
225 float proxrad =
WEP_CVAR(WEP_MINE_LAYER, proximity_radius);
229 for (; head; head = head.chain)
234 new_mine_time =
time + time_core;
235 if (time_edge != time_core)
236 new_mine_time += (time_edge - time_core) *
vlen(head.WarpZone_findradius_dist) / proxrad;
250 if (this.
realowner.(weaponentity).m_weapon == WEP_MINE_LAYER
292 float is_from_enemy = (inflictor.realowner != this.
realowner);
317 W_SetupShot_ProjectileSize(actor, weaponentity,
'-4 -4 -4',
'4 4 4',
false, 5, SND_MINE_FIRE,
CH_WEAPON_A,
WEP_CVAR(WEP_MINE_LAYER, damage), thiswep.
m_id);
322 mine.weaponentity_fld = weaponentity;
324 mine.owner = mine.realowner = actor;
325 if (
WEP_CVAR(WEP_MINE_LAYER, detonatedelay) >= 0)
326 mine.spawnshieldtime =
time +
WEP_CVAR(WEP_MINE_LAYER, detonatedelay);
328 mine.spawnshieldtime = -1;
329 mine.bot_dodge =
true;
330 mine.bot_dodgerating =
WEP_CVAR(WEP_MINE_LAYER, damage) * 2;
336 mine.damagedbycontents =
true;
341 mine.projectiledeathtype = thiswep.
m_id;
342 mine.weaponentity_fld = weaponentity;
343 setsize(mine,
'-4 -4 -4',
'4 4 4');
351 mine.nextthink =
time;
370 bool minfound =
false;
371 IL_EACH(
g_mines, it.realowner ==
this && it.weaponentity_fld == weaponentity,
375 if (!it.minelayer_detonate)
377 it.minelayer_detonate = true;
398 float edgedamage, coredamage, edgeradius, recipricoledgeradius;
399 float selfdamage, teamdamage, enemydamage;
400 edgedamage =
WEP_CVAR(WEP_MINE_LAYER, edgedamage);
401 coredamage =
WEP_CVAR(WEP_MINE_LAYER, damage);
403 recipricoledgeradius = 1 / edgeradius;
411 IL_EACH(g_bot_targets, it.bot_attack,
413 float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
414 d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
418 else if (SAME_TEAM(it, actor))
420 else if (bot_shouldattack(actor, it))
425 float desirabledamage = enemydamage;
429 desirabledamage -= teamdamage;
437 IL_EACH(g_bot_targets, it.bot_attack,
439 if (v_forward * normalize(mine.origin - it.origin) < 0.1
440 && desirabledamage >= 0.1 * coredamage)
441 PHYS_INPUT_BUTTON_ATCK2(actor) = true;
448 if (v_forward * normalize(it.origin - actor.enemy.origin) < 0.1
449 && IS_PLAYER(actor.enemy)
450 && desirabledamage >= 0.1 * coredamage)
452 float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
453 if (random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
454 PHYS_INPUT_BUTTON_ATCK2(actor) = true;
461 if (desirabledamage >= 0.75 * coredamage)
476 if (autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load <
WEP_CVAR(WEP_MINE_LAYER,
ammo))
481 thiswep.wr_reload(thiswep, actor, weaponentity);
531 return WEAPON_MINELAYER_SUICIDE;
536 return WEAPON_MINELAYER_MURDER;
561 PAR(_(
"The %s places mines on the ground when fired, which detonate and damage enemies if stepped on. "
562 "Only a couple mines can be placed at any time, and after some time they will self-detonate."),
COLORED_NAME(
this));
563 PAR(_(
"Uniquely, the mines explode sooner the closer an enemy comes to them. "
564 "The secondary fire can be used to detonate all mines placed by the primary fire."));
565 PAR(_(
"It consumes %s ammo for each mine laid."),
COLORED_NAME(ITEM_Rockets));
566 PAR(_(
"The mines are not launched very far before they hit the ground, so the %s isn't very effective at medium to long ranges. "
567 "It is often used to protect important areas of the map such as the flag in %s, control points in %s, or checkpoints in %s."),
COLORED_NAME(
this),
COLORED_NAME(MAPINFO_TYPE_CTF),
COLORED_NAME(MAPINFO_TYPE_ONSLAUGHT),
COLORED_NAME(MAPINFO_TYPE_ASSAULT));
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity, bool shot_accurate)
IntrusiveList g_bot_dodge
#define MUTATOR_CALLHOOK(id,...)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
virtual void wr_checkammo1()
(SERVER) checks ammo for weapon primary
#define colormapPaletteColor(c, isPants)
#define COLORED_NAME(this)
const int IT_UNLIMITED_AMMO
#define setmodel(this, m)
bool IsFlying(entity this)
#define PHYS_INPUT_BUTTON_ATCK(s)
#define PHYS_INPUT_BUTTON_ATCK2(s)
void SetMovetypeFollow(entity ent, entity e)
void UnsetMovetypeFollow(entity ent)
int LostMovetypeFollow(entity ent)
vector trace_plane_normal
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
IntrusiveList g_damagedbycontents
float autocvar_g_balance_selfdamagepercent
const int HITTYPE_BOUNCE
set manually after projectile has bounced
#define pointparticles(effect, org, vel, howmany)
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
entity WarpZone_SearchInRadius(vector org, float rad, float nomonsters, WarpZone_FindRadius_cond_callback_t cb)
Modified findradius aware of warpzones, that only includes entities that meet the "cb" criteria.
void WarpZone_RefSys_Copy(entity me, entity from)
Copies the warpzone reference of from onto me.
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
void W_MineLayer_ProximityExplode(entity this)
void W_MineLayer_Explode_think(entity this)
void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
int W_MineLayer_Count(entity e,.entity weaponentity)
void W_MineLayer_Explode(entity this, entity directhitentity)
void W_MineLayer_Stick(entity this, entity to)
void W_MineLayer_Think(entity this)
bool W_MineLayer_Think_cond(entity e)
bool W_MineLayer_PlacedMines(entity this,.entity weaponentity, bool detonate)
void W_MineLayer_Attack(Weapon thiswep, entity actor,.entity weaponentity)
void W_MineLayer_Touch(entity this, entity toucher)
bool W_MineLayer_CheckSameTeam_cond(entity e)
void W_MineLayer_DoRemoteExplode(entity this)
void W_MineLayer_RemoteExplode(entity this)
void set_movetype(entity this, int mt)
const int MOVETYPE_FOLLOW
#define UNSET_ONGROUND(s)
const int MOVETYPE_BOUNCE
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
entity Notification
always last
#define METHOD(cname, name, prototype)
const int PROJECTILE_MINE
float health
Legacy fields for the resources. To be removed.
#define w_getbestweapon(ent, wepent)
#define IS_INDEPENDENT_PLAYER(e)
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode)
#define PROJECTILE_TOUCH(e, t)
IntrusiveList g_projectiles
#define PROJECTILE_MAKETRIGGER(e)
#define sound(e, c, s, v, a)
void play2(entity e, string filename)
float spamsound(entity e, int chan, Sound samp, float vol, float _atten)
use this one if you might be causing spam (e.g.
bool StatusEffects_active(StatusEffect this, entity actor)
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
#define W_SetupShot_ProjectileSize(ent, wepent, mi, ma, antilag, recoil, snd, chan, maxdamage, deathtype)
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
string W_Guide_Keybinds(Weapon wep)
void W_MuzzleFlash(Weapon thiswep, entity actor,.entity weaponentity, vector shotorg, vector shotdir)
string W_Guide_DPS_onlyOne_unnamed(string name)
#define WEP_CVAR(wep, name)
const int MAX_WEAPONSLOTS
entity weaponentities[MAX_WEAPONSLOTS]
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)
void W_Reload(entity actor,.entity weaponentity, float sent_ammo_min, Sound sent_sound)
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
#define ATTACK_FINISHED(ent, w)
float weapon_load[REGISTRY_MAX(Weapons)]