X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fweapon%2Fminelayer.qc;h=f25859e0532983b1b1fbf7c9605f8f902fcde27d;hb=b12384978a6b1ad4ca08c8a35f8a197a36ec5e05;hp=73b29a48de6a97a252843512bd7c480abad539f4;hpb=7e81470d4e18121c8ea577752929e657c33494e2;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/weapon/minelayer.qc b/qcsrc/common/weapons/weapon/minelayer.qc index 73b29a48d..f25859e05 100644 --- a/qcsrc/common/weapons/weapon/minelayer.qc +++ b/qcsrc/common/weapons/weapon/minelayer.qc @@ -1,68 +1,6 @@ #include "minelayer.qh" -#ifndef IMPLEMENTATION -CLASS(MineLayer, Weapon) -/* ammotype */ ATTRIB(MineLayer, ammo_field, .int, ammo_rockets); -/* impulse */ ATTRIB(MineLayer, impulse, int, 4); -/* flags */ ATTRIB(MineLayer, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH); -/* rating */ ATTRIB(MineLayer, bot_pickupbasevalue, float, 7000); -/* color */ ATTRIB(MineLayer, wpcolor, vector, '0.75 1 0'); -/* modelname */ ATTRIB(MineLayer, mdl, string, "minelayer"); -#ifdef GAMEQC -/* model */ ATTRIB(MineLayer, m_model, Model, MDL_MINELAYER_ITEM); -#endif -/* crosshair */ ATTRIB(MineLayer, w_crosshair, string, "gfx/crosshairminelayer"); -/* crosshair */ ATTRIB(MineLayer, w_crosshair_size, float, 0.9); -/* wepimg */ ATTRIB(MineLayer, model2, string, "weaponminelayer"); -/* refname */ ATTRIB(MineLayer, netname, string, "minelayer"); -/* wepname */ ATTRIB(MineLayer, m_name, string, _("Mine Layer")); - -#define X(BEGIN, P, END, class, prefix) \ - BEGIN(class) \ - P(class, prefix, ammo, float, NONE) \ - P(class, prefix, animtime, float, NONE) \ - P(class, prefix, damageforcescale, float, NONE) \ - P(class, prefix, damage, float, NONE) \ - P(class, prefix, detonatedelay, float, NONE) \ - P(class, prefix, edgedamage, float, NONE) \ - P(class, prefix, force, float, NONE) \ - P(class, prefix, health, float, NONE) \ - P(class, prefix, lifetime, float, NONE) \ - P(class, prefix, lifetime_countdown, float, NONE) \ - P(class, prefix, limit, float, NONE) \ - P(class, prefix, protection, float, NONE) \ - P(class, prefix, proximityradius, float, NONE) \ - P(class, prefix, radius, float, NONE) \ - P(class, prefix, refire, float, NONE) \ - P(class, prefix, reload_ammo, float, NONE) \ - P(class, prefix, reload_time, float, NONE) \ - P(class, prefix, remote_damage, float, NONE) \ - P(class, prefix, remote_edgedamage, float, NONE) \ - P(class, prefix, remote_force, float, NONE) \ - P(class, prefix, remote_radius, float, NONE) \ - P(class, prefix, speed, float, NONE) \ - P(class, prefix, switchdelay_drop, float, NONE) \ - P(class, prefix, switchdelay_raise, float, NONE) \ - P(class, prefix, time, float, NONE) \ - P(class, prefix, weaponreplace, string, NONE) \ - P(class, prefix, weaponstartoverride, float, NONE) \ - P(class, prefix, weaponstart, float, NONE) \ - P(class, prefix, weaponthrowable, float, NONE) \ - END() - W_PROPS(X, MineLayer, minelayer) -#undef X -ENDCLASS(MineLayer) -REGISTER_WEAPON(MINE_LAYER, minelayer, NEW(MineLayer)); #ifdef SVQC -void W_MineLayer_Think(entity this); -.float minelayer_detonate, mine_explodeanyway; -.float mine_time; -.vector mine_orientation; -#endif -#endif -#ifdef IMPLEMENTATION -#ifdef SVQC -spawnfunc(weapon_minelayer) { weapon_defaultspawnfunc(this, WEP_MINE_LAYER); } void W_MineLayer_Stick(entity this, entity to) { @@ -80,16 +18,16 @@ void W_MineLayer_Stick(entity this, entity to) newmine.owner = this.owner; newmine.realowner = this.realowner; - setsize(newmine, '-4 -4 -4', '4 4 4'); setorigin(newmine, this.origin); setmodel(newmine, MDL_MINELAYER_MINE); + setsize(newmine, '-4 -4 -4', '4 4 4'); newmine.angles = vectoangles(-trace_plane_normal); // face against the surface - newmine.mine_orientation = -trace_plane_normal; + newmine.movedir = -trace_plane_normal; newmine.takedamage = this.takedamage; newmine.damageforcescale = this.damageforcescale; - newmine.health = this.health; + SetResourceExplicit(newmine, RES_HEALTH, GetResource(this, RES_HEALTH)); newmine.event_damage = this.event_damage; newmine.spawnshieldtime = this.spawnshieldtime; newmine.damagedbycontents = true; @@ -126,22 +64,20 @@ void W_MineLayer_Explode(entity this, entity directhitentity) this.event_damage = func_null; this.takedamage = DAMAGE_NO; - RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, damage), WEP_CVAR(minelayer, edgedamage), WEP_CVAR(minelayer, radius), NULL, NULL, WEP_CVAR(minelayer, force), this.projectiledeathtype, directhitentity); + 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); .entity weaponentity = this.weaponentity_fld; - if(this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER) + Weapon thiswep = WEP_MINE_LAYER; + if(this.realowner.(weaponentity).m_weapon == thiswep) { entity own = this.realowner; - Weapon w = WEP_MINE_LAYER; - if(!w.wr_checkammo1(w, own, weaponentity)) + if(!thiswep.wr_checkammo1(thiswep, own, weaponentity)) { - own.cnt = WEP_MINE_LAYER.m_id; - int slot = weaponslot(weaponentity); - ATTACK_FINISHED(own, slot) = time; + own.cnt = thiswep.m_id; + ATTACK_FINISHED(own, weaponentity) = time; own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity); } } - this.realowner.(weaponentity).minelayer_mines -= 1; delete(this); } @@ -156,24 +92,23 @@ void W_MineLayer_DoRemoteExplode(entity this) this.takedamage = DAMAGE_NO; if(this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FOLLOW) - this.velocity = this.mine_orientation; // particle fx and decals need .velocity + this.velocity = this.movedir; // particle fx and decals need .velocity - RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), NULL, NULL, WEP_CVAR(minelayer, remote_force), this.projectiledeathtype | HITTYPE_BOUNCE, NULL); + RadiusDamage(this, this.realowner, WEP_CVAR(minelayer, remote_damage), WEP_CVAR(minelayer, remote_edgedamage), WEP_CVAR(minelayer, remote_radius), + NULL, NULL, WEP_CVAR(minelayer, remote_force), this.projectiledeathtype | HITTYPE_BOUNCE, this.weaponentity_fld, NULL); .entity weaponentity = this.weaponentity_fld; - if(this.realowner.(weaponentity).m_weapon == WEP_MINE_LAYER) + Weapon thiswep = WEP_MINE_LAYER; + if(this.realowner.(weaponentity).m_weapon == thiswep) { entity own = this.realowner; - Weapon w = WEP_MINE_LAYER; - if(!w.wr_checkammo1(w, own, weaponentity)) + if(!thiswep.wr_checkammo1(thiswep, own, weaponentity)) { - own.cnt = WEP_MINE_LAYER.m_id; - int slot = weaponslot(weaponentity); - ATTACK_FINISHED(own, slot) = time; + own.cnt = thiswep.m_id; + ATTACK_FINISHED(own, weaponentity) = time; own.(weaponentity).m_switchweapon = w_getbestweapon(own, weaponentity); } } - this.realowner.(weaponentity).minelayer_mines -= 1; delete(this); } @@ -287,15 +222,7 @@ void W_MineLayer_Touch(entity this, entity toucher) if(this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FOLLOW) return; // we're already a stuck mine, why do we get called? TODO does this even happen? - if(WarpZone_Projectile_Touch(this, toucher)) - { - if(wasfreed(this)) - { - .entity weaponentity = this.weaponentity_fld; - this.realowner.(weaponentity).minelayer_mines -= 1; - } - return; - } + PROJECTILE_TOUCH(this, toucher); if((toucher && IS_PLAYER(toucher) && !IS_DEAD(toucher)) || toucher.owner == this.owner) { @@ -308,9 +235,9 @@ void W_MineLayer_Touch(entity this, entity toucher) } } -void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) { - if(this.health <= 0) + if(GetResource(this, RES_HEALTH) <= 0) return; float is_from_enemy = (inflictor.realowner != this.realowner); @@ -318,22 +245,20 @@ void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float da if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_from_enemy ? 1 : -1))) return; // g_projectiles_damage says to halt - this.health = this.health - damage; + TakeResource(this, RES_HEALTH, damage); this.angles = vectoangles(this.velocity); - if(this.health <= 0) + if(GetResource(this, RES_HEALTH) <= 0) W_PrepareExplosionByDamage(this, attacker, W_MineLayer_Explode_think); } void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity) { - entity mine; - entity flash; - // scan how many mines we placed, and return if we reached our limit if(WEP_CVAR(minelayer, limit)) { - if(actor.(weaponentity).minelayer_mines >= WEP_CVAR(minelayer, limit)) + int minecount = W_MineLayer_Count(actor, weaponentity); + if(minecount >= WEP_CVAR(minelayer, limit)) { // the refire delay keeps this message from being spammed Send_Notification(NOTIF_ONE, actor, MSG_MULTI, WEAPON_MINELAYER_LIMIT, WEP_CVAR(minelayer, limit)); @@ -344,10 +269,10 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity) W_DecreaseAmmo(thiswep, actor, WEP_CVAR(minelayer, ammo), weaponentity); - W_SetupShot_ProjectileSize(actor, weaponentity, '-4 -4 -4', '4 4 4', false, 5, SND_MINE_FIRE, CH_WEAPON_A, WEP_CVAR(minelayer, damage)); - Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); + 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); + W_MuzzleFlash(thiswep, actor, weaponentity, w_shotorg, w_shotdir); - mine = WarpZone_RefSys_SpawnSameRefSys(actor); + entity mine = WarpZone_RefSys_SpawnSameRefSys(actor); mine.weaponentity_fld = weaponentity; IL_PUSH(g_mines, mine); mine.owner = mine.realowner = actor; @@ -361,14 +286,15 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity) mine.takedamage = DAMAGE_YES; mine.damageforcescale = WEP_CVAR(minelayer, damageforcescale); - mine.health = WEP_CVAR(minelayer, health); + SetResourceExplicit(mine, RES_HEALTH, WEP_CVAR(minelayer, health)); mine.event_damage = W_MineLayer_Damage; mine.damagedbycontents = true; IL_PUSH(g_damagedbycontents, mine); set_movetype(mine, MOVETYPE_TOSS); PROJECTILE_MAKETRIGGER(mine); - mine.projectiledeathtype = WEP_MINE_LAYER.m_id; + mine.projectiledeathtype = thiswep.m_id; + mine.weaponentity_fld = weaponentity; setsize(mine, '-4 -4 -4', '4 4 4'); // give it some size so it can be shot setorigin(mine, w_shotorg - v_forward * 4); // move it back so it hits the wall at the right point @@ -388,18 +314,9 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity) CSQCProjectile(mine, true, PROJECTILE_MINE, true); - // muzzle flash for 1st person view - flash = spawn(); - setmodel(flash, MDL_MINELAYER_MUZZLEFLASH); // precision set below - SUB_SetFade(flash, time, 0.1); - flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION; - W_AttachToShotorg(actor, weaponentity, flash, '5 0 0'); - // common properties MUTATOR_CALLHOOK(EditProjectile, actor, mine); - - actor.(weaponentity).minelayer_mines = W_MineLayer_Count(actor, weaponentity); } bool W_MineLayer_PlacedMines(entity this, .entity weaponentity, bool detonate) @@ -425,7 +342,8 @@ bool W_MineLayer_PlacedMines(entity this, .entity weaponentity, bool detonate) METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity)) { // aim and decide to fire if appropriate - if(actor.(weaponentity).minelayer_mines >= WEP_CVAR(minelayer, limit)) + int minecount = W_MineLayer_Count(actor, weaponentity); + if(minecount >= WEP_CVAR(minelayer, limit)) PHYS_INPUT_BUTTON_ATCK(actor) = false; else PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, WEP_CVAR(minelayer, speed), 0, WEP_CVAR(minelayer, lifetime), false); @@ -461,7 +379,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentit float desirabledamage; desirabledamage = enemydamage; - if(time > actor.invincible_finished && time > actor.spawnshieldtime) + if(StatusEffects_active(STATUSEFFECT_Shield, actor) && !StatusEffects_active(STATUSEFFECT_SpawnShield, actor)) desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent; if(teamplay && actor.team) desirabledamage = desirabledamage - teamdamage; @@ -499,7 +417,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentit // 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 PHYS_INPUT_BUTTON_ATCK2(actor) = true; - if((skill > 6.5) && (selfdamage > actor.health)) + if((skill > 6.5) && (selfdamage > GetResource(actor, RES_HEALTH))) PHYS_INPUT_BUTTON_ATCK2(actor) = false; //if(PHYS_INPUT_BUTTON_ATCK2(actor) == true) // dprint(ftos(desirabledamage),"\n"); @@ -508,13 +426,12 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentit } METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) { - if(weaponslot(weaponentity) == 0) - actor.minelayer_mines = actor.(weaponentity).minelayer_mines; + actor.(weaponentity).minelayer_mines = W_MineLayer_Count(actor, weaponentity); if(autocvar_g_balance_minelayer_reload_ammo && actor.(weaponentity).clip_load < WEP_CVAR(minelayer, ammo)) // forced reload { // not if we're holding the minelayer without enough ammo, but can detonate existing mines - if(!(W_MineLayer_PlacedMines(actor, weaponentity, false) && actor.(thiswep.ammo_field) < WEP_CVAR(minelayer, ammo))) { + if(!(W_MineLayer_PlacedMines(actor, weaponentity, false) && GetResource(actor, thiswep.ammo_type) < WEP_CVAR(minelayer, ammo))) { thiswep.wr_reload(thiswep, actor, weaponentity); } } @@ -535,12 +452,11 @@ METHOD(MineLayer, wr_think, void(entity thiswep, entity actor, .entity weaponent } METHOD(MineLayer, wr_checkammo1, bool(entity thiswep, entity actor, .entity weaponentity)) { - //int slot = 0; // TODO: unhardcode // actually do // don't switch while placing a mine - //if(ATTACK_FINISHED(actor, slot) <= time || PS(actor).m_weapon != WEP_MINE_LAYER) + //if(ATTACK_FINISHED(actor, weaponentity) <= time || PS(actor).m_weapon != WEP_MINE_LAYER) //{ - float ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(minelayer, ammo); - ammo_amount += actor.(weaponentity).(weapon_load[WEP_MINE_LAYER.m_id]) >= WEP_CVAR(minelayer, ammo); + float ammo_amount = GetResource(actor, thiswep.ammo_type) >= WEP_CVAR(minelayer, ammo); + ammo_amount += actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR(minelayer, ammo); return ammo_amount; //} //return true; @@ -554,7 +470,6 @@ METHOD(MineLayer, wr_checkammo2, bool(entity thiswep, entity actor, .entity weap } METHOD(MineLayer, wr_resetplayer, void(entity thiswep, entity actor)) { - actor.minelayer_mines = 0; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity weaponentity = weaponentities[slot]; @@ -587,4 +502,3 @@ METHOD(MineLayer, wr_impacteffect, void(entity thiswep, entity actor)) } #endif -#endif