19 newmine.owner = this.
owner;
22 setmodel(newmine, MDL_MINELAYER_MINE);
23 setsize(newmine,
'-4 -4 -4',
'4 4 4');
31 newmine.event_damage = this.event_damage;
33 newmine.damagedbycontents =
true;
39 newmine.mine_time = this.mine_time;
42 setthink(newmine, W_MineLayer_Think);
43 newmine.nextthink =
time;
44 newmine.cnt = this.
cnt;
45 newmine.flags = this.
flags;
52 SetMovetypeFollow(newmine, to);
55 void W_MineLayer_Explode(
entity this,
entity directhitentity)
62 Send_Notification(NOTIF_ONE, this.
realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
67 RadiusDamage(
this, this.
realowner,
WEP_CVAR(minelayer, damage),
WEP_CVAR(minelayer, edgedamage),
WEP_CVAR(minelayer,
radius),
NULL,
NULL,
WEP_CVAR(minelayer, force), this.
projectiledeathtype, this.
weaponentity_fld, directhitentity);
70 Weapon thiswep = WEP_MINE_LAYER;
71 if(this.
realowner.(weaponentity).m_weapon == thiswep)
74 if(!thiswep.wr_checkammo1(thiswep, own, weaponentity))
76 own.cnt = thiswep.
m_id;
84 void W_MineLayer_Explode_think(
entity this)
86 W_MineLayer_Explode(
this,
NULL);
89 void W_MineLayer_DoRemoteExplode(
entity this)
101 Weapon thiswep = WEP_MINE_LAYER;
102 if(this.
realowner.(weaponentity).m_weapon == thiswep)
105 if(!thiswep.wr_checkammo1(thiswep, own, weaponentity))
107 own.cnt = thiswep.
m_id;
109 own.(weaponentity).m_switchweapon =
w_getbestweapon(own, weaponentity);
115 void W_MineLayer_RemoteExplode(
entity this)
123 W_MineLayer_DoRemoteExplode(
this);
127 void W_MineLayer_ProximityExplode(
entity this)
130 if(
WEP_CVAR(minelayer, protection) && this.mine_explodeanyway == 0)
143 W_MineLayer_Explode(
this,
NULL);
149 IL_EACH(g_mines, it.realowner == e && it.weaponentity_fld == weaponentity,
157 void W_MineLayer_Think(
entity this)
165 if(LostMovetypeFollow(
this))
167 UnsetMovetypeFollow(
this);
174 if((
time > this.
cnt) && (!this.mine_time) && (this.
cnt > 0))
176 if(
WEP_CVAR(minelayer, lifetime_countdown) > 0)
178 this.mine_time =
time +
WEP_CVAR(minelayer, lifetime_countdown);
179 this.mine_explodeanyway = 1;
187 W_MineLayer_Explode(
this,
NULL);
192 head = findradius(this.
origin,
WEP_CVAR(minelayer, proximityradius));
206 if(this.mine_time &&
time >= this.mine_time)
208 W_MineLayer_ProximityExplode(
this);
214 if(this.
realowner.(weaponentity).m_weapon == WEP_MINE_LAYER)
216 if(this.minelayer_detonate)
217 W_MineLayer_RemoteExplode(
this);
227 if((toucher &&
IS_PLAYER(toucher) && !
IS_DEAD(toucher)) || toucher.owner ==
this.owner)
234 W_MineLayer_Stick(
this, toucher);
243 float is_from_enemy = (inflictor.realowner != this.
realowner);
260 int minecount = W_MineLayer_Count(actor, weaponentity);
261 if(minecount >=
WEP_CVAR(minelayer, limit))
264 Send_Notification(NOTIF_ONE, actor, MSG_MULTI, WEAPON_MINELAYER_LIMIT,
WEP_CVAR(minelayer, limit));
265 play2(actor,
SND(UNAVAILABLE));
272 W_SetupShot_ProjectileSize(actor, weaponentity,
'-4 -4 -4',
'4 4 4',
false, 5, SND_MINE_FIRE,
CH_WEAPON_A,
WEP_CVAR(minelayer, damage), thiswep.
m_id);
276 mine.weaponentity_fld = weaponentity;
278 mine.owner = mine.realowner = actor;
279 if(
WEP_CVAR(minelayer, detonatedelay) >= 0)
280 mine.spawnshieldtime =
time +
WEP_CVAR(minelayer, detonatedelay);
282 mine.spawnshieldtime = -1;
283 mine.classname =
"mine";
284 mine.bot_dodge =
true;
285 mine.bot_dodgerating =
WEP_CVAR(minelayer, damage) * 2;
290 mine.event_damage = W_MineLayer_Damage;
291 mine.damagedbycontents =
true;
296 mine.projectiledeathtype = thiswep.
m_id;
297 mine.weaponentity_fld = weaponentity;
298 setsize(mine,
'-4 -4 -4',
'4 4 4');
304 settouch(mine, W_MineLayer_Touch);
306 mine.nextthink =
time;
308 mine.flags = FL_PROJECTILE;
313 if(mine.cnt > 0) { mine.cnt +=
time; }
322 bool W_MineLayer_PlacedMines(
entity this, .
entity weaponentity,
bool detonate)
324 bool minfound =
false;
326 IL_EACH(g_mines, it.realowner ==
this && it.weaponentity_fld == weaponentity,
330 if(!it.minelayer_detonate)
332 it.minelayer_detonate = true;
345 int minecount = W_MineLayer_Count(actor, weaponentity);
346 if(minecount >=
WEP_CVAR(minelayer, limit))
353 float edgedamage, coredamage, edgeradius, recipricoledgeradius;
354 float selfdamage, teamdamage, enemydamage;
355 edgedamage =
WEP_CVAR(minelayer, edgedamage);
356 coredamage =
WEP_CVAR(minelayer, damage);
358 recipricoledgeradius = 1 / edgeradius;
363 IL_EACH(g_mines, it.realowner == actor,
366 IL_EACH(g_bot_targets, it.bot_attack,
368 float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
369 d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
372 selfdamage = selfdamage + d;
373 else if(SAME_TEAM(it, actor))
374 teamdamage = teamdamage + d;
375 else if(bot_shouldattack(actor, it))
376 enemydamage = enemydamage + d;
380 float desirabledamage;
381 desirabledamage = enemydamage;
382 if(StatusEffects_active(STATUSEFFECT_Shield, actor) && !StatusEffects_active(STATUSEFFECT_SpawnShield, actor))
385 desirabledamage = desirabledamage - teamdamage;
388 IL_EACH(g_mines, it.realowner == actor,
393 IL_EACH(g_bot_targets, it.bot_attack,
395 if((v_forward * normalize(mine.origin - it.origin) < 0.1)
396 && desirabledamage > 0.1 * coredamage
397 ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
404 if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1)
405 && IS_PLAYER(actor.enemy)
406 && (desirabledamage >= 0.1 * coredamage)
409 float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
410 if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
411 PHYS_INPUT_BUTTON_ATCK2(actor) = true;
418 if(desirabledamage >= 0.75 * coredamage)
429 actor.(weaponentity).
minelayer_mines = W_MineLayer_Count(actor, weaponentity);
431 if(autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load <
WEP_CVAR(minelayer,
ammo))
434 if(!(W_MineLayer_PlacedMines(actor, weaponentity,
false) &&
GetResource(actor, thiswep.ammo_type) <
WEP_CVAR(minelayer,
ammo))) {
435 thiswep.wr_reload(thiswep, actor, weaponentity);
442 W_MineLayer_Attack(thiswep, actor, weaponentity);
449 if(W_MineLayer_PlacedMines(actor, weaponentity,
true))
466 if(W_MineLayer_PlacedMines(actor, weaponentity,
false))
485 return WEAPON_MINELAYER_SUICIDE;
489 return WEAPON_MINELAYER_MURDER;
498 org2 = w_org + w_backoff * 12;
#define PHYS_INPUT_BUTTON_ATCK2(s)
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
#define IL_EACH(this, cond, body)
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity)
float weapon_load[REGISTRY_MAX(Weapons)]
#define PROJECTILE_MAKETRIGGER(e)
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
#define w_getbestweapon(ent, wepent)
#define W_SetupShot_ProjectileSize(ent, wepent, mi, ma, antilag, recoil, snd, chan, maxdamage, deathtype)
float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
IntrusiveList g_damagedbycontents
const int PROJECTILE_MINE
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
#define WEP_CVAR(wepname, name)
#define METHOD(cname, name, prototype)
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
IntrusiveList g_bot_dodge
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
#define PROJECTILE_TOUCH(e, t)
#define setmodel(this, m)
float autocvar_g_balance_selfdamagepercent
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
const int MAX_WEAPONSLOTS
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode)
entity WarpZone_RefSys_SpawnSameRefSys(entity me)
#define PHYS_INPUT_BUTTON_ATCK(s)
bool IsFlying(entity this)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
IntrusiveList g_projectiles
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
entity Notification
always last
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
#define MUTATOR_CALLHOOK(id,...)
entity weaponentities[MAX_WEAPONSLOTS]
vector trace_plane_normal
#define ATTACK_FINISHED(ent, w)
void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use,.entity weaponentity)
#define sound(e, c, s, v, a)
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
void set_movetype(entity this, int mt)
void W_Reload(entity actor,.entity weaponentity, float sent_ammo_min, Sound sent_sound)