X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fserver%2Fw_porto.qc;h=3134a8bb3b66805ac2981732e10952a432a4478d;hb=a83efc591039d68bc106b09001c3f46a14eb52a4;hp=d6e92a53728203ff5f648e797e2304e00a652fc1;hpb=766e44a12d34eda9b7e9b7963e6e083e877dfa8d;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/w_porto.qc b/qcsrc/server/w_porto.qc index d6e92a537..3134a8bb3 100644 --- a/qcsrc/server/w_porto.qc +++ b/qcsrc/server/w_porto.qc @@ -1,5 +1,5 @@ #ifdef REGISTER_WEAPON -REGISTER_WEAPON(PORTO, w_porto, 0, 0, WEP_TYPE_OTHER, 0, "porto" , "porto", _("Port-O-Launch")) +REGISTER_WEAPON(PORTO, w_porto, 0, 0, WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON, 0, "porto" , "porto", _("Port-O-Launch")) #else #ifdef SVQC .entity porto_current; @@ -9,42 +9,46 @@ REGISTER_WEAPON(PORTO, w_porto, 0, 0, WEP_TYPE_OTHER, 0, "porto" , "porto", _("P void W_Porto_Success (void) { - if(self.owner == world) + if(self.realowner == world) { objerror("Cannot succeed successfully: no owner\n"); return; } - self.owner.porto_current = world; + self.realowner.porto_current = world; remove(self); } string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo); void W_Porto_Fail (float failhard) { - if(self.owner == world) + if(self.realowner == world) { objerror("Cannot fail successfully: no owner\n"); return; } // no portals here! - Portal_ClearWithID(self.owner, self.portal_id); - self.owner.porto_current = world; + if(self.cnt < 0) + { + Portal_ClearWithID(self.realowner, self.portal_id); + } + + self.realowner.porto_current = world; - if(!failhard && self.owner.playerid == self.playerid && self.owner.deadflag == DEAD_NO && !(self.owner.weapons & WEPBIT_PORTO)) + if(self.cnt < 0 && !failhard && self.realowner.playerid == self.playerid && self.realowner.deadflag == DEAD_NO && !WEPSET_CONTAINS_EW(self.realowner, WEP_PORTO)) { setsize (self, '-16 -16 0', '16 16 32'); setorigin(self, self.origin + trace_plane_normal); if(move_out_of_solid(self)) { self.flags = FL_ITEM; - self.velocity = trigger_push_calculatevelocity(self.origin, self.owner, 128); + self.velocity = trigger_push_calculatevelocity(self.origin, self.realowner, 128); tracetoss(self, self); - if(vlen(trace_endpos - self.owner.origin) < 128) + if(vlen(trace_endpos - self.realowner.origin) < 128) { - W_ThrowNewWeapon(self.owner, WEP_PORTO, 0, self.origin, self.velocity); - centerprint(self.owner, "^1Portal deployment failed.\n\n^2Catch it to try again!"); + W_ThrowNewWeapon(self.realowner, WEP_PORTO, 0, self.origin, self.velocity); + centerprint(self.realowner, "^1Portal deployment failed.\n\n^2Catch it to try again!"); } } } @@ -53,7 +57,7 @@ void W_Porto_Fail (float failhard) void W_Porto_Remove (entity p) { - if(p.porto_current) + if(p.porto_current.realowner == p && p.porto_current.classname == "porto") { entity oldself; oldself = self; @@ -66,7 +70,7 @@ void W_Porto_Remove (entity p) void W_Porto_Think (void) { trace_plane_normal = '0 0 0'; - if(self.owner.playerid != self.playerid) + if(self.realowner.playerid != self.playerid) remove(self); else W_Porto_Fail(0); @@ -77,6 +81,7 @@ void W_Porto_Touch (void) vector norm; // do not use PROJECTILE_TOUCH here + // FIXME but DO handle warpzones! if(other.classname == "portal") return; // handled by the portal @@ -93,74 +98,111 @@ void W_Porto_Touch (void) return; } - if(self.owner.playerid != self.playerid) + if(self.realowner.playerid != self.playerid) { - sound(self, CHAN_PROJECTILE, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); remove(self); } else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP) { - spamsound(self, CHAN_PROJECTILE, "porto/bounce.wav", VOL_BASE, ATTN_NORM); + spamsound(self, CH_SHOTS, "porto/bounce.wav", VOL_BASE, ATTN_NORM); // just reflect self.right_vector = self.right_vector - 2 * trace_plane_normal * (self.right_vector * trace_plane_normal); self.angles = vectoangles(self.velocity - 2 * trace_plane_normal * (self.velocity * trace_plane_normal)); } else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) { - sound(self, CHAN_PROJECTILE, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); W_Porto_Fail(0); + if(self.cnt < 0) + Portal_ClearAll_PortalsOnly(self.realowner); + } + else if(self.cnt == 0) + { + // in-portal only + if(Portal_SpawnInPortalAtTrace(self.realowner, self.right_vector, self.portal_id)) + { + sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTN_NORM); + trace_plane_normal = norm; + centerprint(self.realowner, "^1In^7-portal created."); + W_Porto_Success(); + } + else + { + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + trace_plane_normal = norm; + W_Porto_Fail(0); + } + } + else if(self.cnt == 1) + { + // out-portal only + if(Portal_SpawnOutPortalAtTrace(self.realowner, self.right_vector, self.portal_id)) + { + sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTN_NORM); + trace_plane_normal = norm; + centerprint(self.realowner, "^1Out^7-portal created."); + W_Porto_Success(); + } + else + { + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + trace_plane_normal = norm; + W_Porto_Fail(0); + } } else if(self.effects & EF_RED) { self.effects += EF_BLUE - EF_RED; - if(Portal_SpawnInPortalAtTrace(self.owner, self.right_vector, self.portal_id)) + if(Portal_SpawnInPortalAtTrace(self.realowner, self.right_vector, self.portal_id)) { - sound(self, CHAN_PROJECTILE, "porto/create.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTN_NORM); trace_plane_normal = norm; - centerprint(self.owner, "^1In^7-portal created."); + centerprint(self.realowner, "^1In^7-portal created."); self.right_vector = self.right_vector - 2 * trace_plane_normal * (self.right_vector * norm); self.angles = vectoangles(self.velocity - 2 * trace_plane_normal * (self.velocity * norm)); CSQCProjectile(self, TRUE, PROJECTILE_PORTO_BLUE, TRUE); // change type } else { - sound(self, CHAN_PROJECTILE, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); trace_plane_normal = norm; + Portal_ClearAll_PortalsOnly(self.realowner); W_Porto_Fail(0); } } else { - if(self.owner.portal_in.portal_id == self.portal_id) + if(self.realowner.portal_in.portal_id == self.portal_id) { - if(Portal_SpawnOutPortalAtTrace(self.owner, self.right_vector, self.portal_id)) + if(Portal_SpawnOutPortalAtTrace(self.realowner, self.right_vector, self.portal_id)) { - sound(self, CHAN_PROJECTILE, "porto/create.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTN_NORM); trace_plane_normal = norm; - centerprint(self.owner, "^4Out^7-portal created."); + centerprint(self.realowner, "^4Out^7-portal created."); W_Porto_Success(); } else { - sound(self, CHAN_PROJECTILE, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + Portal_ClearAll_PortalsOnly(self.realowner); W_Porto_Fail(0); } } else { - sound(self, CHAN_PROJECTILE, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTN_NORM); + Portal_ClearAll_PortalsOnly(self.realowner); W_Porto_Fail(0); } } } -void W_Porto_Attack (void) +void W_Porto_Attack (float type) { - local entity gren; + entity gren; - if not(self.items & IT_UNLIMITED_SUPERWEAPONS) - self.weapons = self.weapons - (self.weapons & WEPBIT_PORTO); - W_SetupShot (self, FALSE, 4, "porto/fire.wav", CHAN_WEAPON, 0); + W_SetupShot (self, FALSE, 4, "porto/fire.wav", CH_WEAPON_A, 0); // always shoot from the eye w_shotdir = v_forward; w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward; @@ -168,7 +210,8 @@ void W_Porto_Attack (void) //pointparticles(particleeffectnum("grenadelauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); gren = spawn (); - gren.owner = self; + gren.cnt = type; + gren.owner = gren.realowner = self; gren.playerid = self.playerid; gren.classname = "porto"; gren.bot_dodge = TRUE; @@ -180,13 +223,27 @@ void W_Porto_Attack (void) setorigin(gren, w_shotorg); setsize(gren, '0 0 0', '0 0 0'); - gren.nextthink = time + autocvar_g_balance_porto_primary_lifetime; + if(type > 0) + gren.nextthink = time + autocvar_g_balance_porto_secondary_lifetime; + else + gren.nextthink = time + autocvar_g_balance_porto_primary_lifetime; gren.think = W_Porto_Think; gren.touch = W_Porto_Touch; - if(self.items & IT_STRENGTH) - W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_primary_speed * autocvar_g_balance_powerup_strength_force, 0); + + if(type > 0) + { + if(self.items & IT_STRENGTH) + W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_secondary_speed * autocvar_g_balance_powerup_strength_force, 0); + else + W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_secondary_speed, 0); + } else - W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_primary_speed, 0); + { + if(self.items & IT_STRENGTH) + W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_primary_speed * autocvar_g_balance_powerup_strength_force, 0); + else + W_SetupProjectileVelocity(gren, autocvar_g_balance_porto_primary_speed, 0); + } gren.angles = vectoangles (gren.velocity); gren.flags = FL_PROJECTILE; @@ -199,7 +256,10 @@ void W_Porto_Attack (void) gren.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; - CSQCProjectile(gren, TRUE, PROJECTILE_PORTO_RED, TRUE); + if(type > 0) + CSQCProjectile(gren, TRUE, PROJECTILE_PORTO_BLUE, TRUE); + else + CSQCProjectile(gren, TRUE, PROJECTILE_PORTO_RED, TRUE); other = gren; MUTATOR_CALLHOOK(EditProjectile); } @@ -219,41 +279,64 @@ float w_porto(float req) { self.BUTTON_ATCK = FALSE; self.BUTTON_ATCK2 = FALSE; - if(bot_aim(autocvar_g_balance_porto_primary_speed, 0, autocvar_g_balance_grenadelauncher_primary_lifetime, FALSE)) - self.BUTTON_ATCK = TRUE; + if(!autocvar_g_balance_porto_secondary) + if(bot_aim(autocvar_g_balance_porto_primary_speed, 0, autocvar_g_balance_grenadelauncher_primary_lifetime, FALSE)) + self.BUTTON_ATCK = TRUE; } else if (req == WR_THINK) { - if(self.porto_v_angle_held) + if(autocvar_g_balance_porto_secondary) { - if(!self.BUTTON_ATCK2) + if (self.BUTTON_ATCK) + if (!self.porto_current) + if (!self.porto_forbidden) + if (weapon_prepareattack(0, autocvar_g_balance_porto_primary_refire)) { - self.porto_v_angle_held = 0; + W_Porto_Attack(0); + weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_porto_primary_animtime, w_ready); + } - ClientData_Touch(self); + if (self.BUTTON_ATCK2) + if (!self.porto_current) + if (!self.porto_forbidden) + if (weapon_prepareattack(1, autocvar_g_balance_porto_secondary_refire)) + { + W_Porto_Attack(1); + weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_porto_secondary_animtime, w_ready); } } else { - if(self.BUTTON_ATCK2) + if(self.porto_v_angle_held) { - self.porto_v_angle = self.v_angle; - self.porto_v_angle_held = 1; + if(!self.BUTTON_ATCK2) + { + self.porto_v_angle_held = 0; - ClientData_Touch(self); + ClientData_Touch(self); + } } - } - v_angle_save = self.v_angle; - if(self.porto_v_angle_held) - makevectors(self.porto_v_angle); // override the previously set angles + else + { + if(self.BUTTON_ATCK2) + { + self.porto_v_angle = self.v_angle; + self.porto_v_angle_held = 1; - if (self.BUTTON_ATCK) - if (!self.porto_current) - if (!self.porto_forbidden) - if (weapon_prepareattack(0, autocvar_g_balance_porto_primary_refire)) - { - W_Porto_Attack(); - weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_porto_primary_animtime, w_ready); + ClientData_Touch(self); + } + } + if(self.porto_v_angle_held) + makevectors(self.porto_v_angle); // override the previously set angles + + if (self.BUTTON_ATCK) + if (!self.porto_current) + if (!self.porto_forbidden) + if (weapon_prepareattack(0, autocvar_g_balance_porto_primary_refire)) + { + W_Porto_Attack(-1); + weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_porto_primary_animtime, w_ready); + } } } else if (req == WR_PRECACHE) @@ -279,7 +362,7 @@ float w_porto(float req) self.porto_current = world; } return TRUE; -}; +} #endif #ifdef CSQC float w_porto(float req)