From: Mario Date: Mon, 7 Oct 2013 16:39:24 +0000 (-0700) Subject: Fix some missing stuff X-Git-Tag: xonotic-v0.8.0~70^2~31 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=320de1a62a99a19446fff6953d66d4cbe827c245;p=xonotic%2Fxonotic-data.pk3dir.git Fix some missing stuff --- diff --git a/balance25.cfg b/balance25.cfg index 0ef954953..2b69a187c 100644 --- a/balance25.cfg +++ b/balance25.cfg @@ -706,7 +706,6 @@ set g_balance_fireball_switchdelay_drop 0.15 set g_balance_fireball_switchdelay_raise 0.15 // }}} - // {{{ heavy machine gun set g_balance_hmg_spread_min 0.02 set g_balance_hmg_spread_max 0.05 @@ -724,6 +723,8 @@ set g_balance_hmg_bulletconstant 115 // 13.1qu set g_balance_hmg_reload_ammo 120 //default: 30 set g_balance_hmg_reload_time 1 +set g_balance_hmg_switchdelay_drop 0.2 +set g_balance_hmg_switchdelay_raise 0.2 // }}} // {{{ RPC @@ -743,4 +744,6 @@ set g_balance_rpc_speedaccel 0 set g_balance_rpc_speedstart 1250 set g_balance_rpc_reload_ammo 10 set g_balance_rpc_reload_time 1 +set g_balance_rpc_switchdelay_drop 0.2 +set g_balance_rpc_switchdelay_raise 0.2 // }}} diff --git a/balanceFruitieX.cfg b/balanceFruitieX.cfg index 599c7ce14..ae480f9de 100644 --- a/balanceFruitieX.cfg +++ b/balanceFruitieX.cfg @@ -706,7 +706,6 @@ set g_balance_fireball_switchdelay_drop 0.15 set g_balance_fireball_switchdelay_raise 0.15 // }}} - // {{{ heavy machine gun set g_balance_hmg_spread_min 0.02 set g_balance_hmg_spread_max 0.05 @@ -724,6 +723,8 @@ set g_balance_hmg_bulletconstant 115 // 13.1qu set g_balance_hmg_reload_ammo 120 //default: 30 set g_balance_hmg_reload_time 1 +set g_balance_hmg_switchdelay_drop 0.2 +set g_balance_hmg_switchdelay_raise 0.2 // }}} // {{{ RPC @@ -743,4 +744,6 @@ set g_balance_rpc_speedaccel 0 set g_balance_rpc_speedstart 1250 set g_balance_rpc_reload_ammo 10 set g_balance_rpc_reload_time 1 +set g_balance_rpc_switchdelay_drop 0.2 +set g_balance_rpc_switchdelay_raise 0.2 // }}} diff --git a/balanceXDF.cfg b/balanceXDF.cfg index 591bc8d43..4481e28f7 100644 --- a/balanceXDF.cfg +++ b/balanceXDF.cfg @@ -705,6 +705,7 @@ set g_balance_fireball_secondary_spread 0 set g_balance_fireball_switchdelay_drop 0 set g_balance_fireball_switchdelay_raise 0 // }}} + // {{{ heavy machine gun set g_balance_hmg_spread_min 0.02 set g_balance_hmg_spread_max 0.05 @@ -722,7 +723,10 @@ set g_balance_hmg_bulletconstant 115 // 13.1qu set g_balance_hmg_reload_ammo 120 //default: 30 set g_balance_hmg_reload_time 1 +set g_balance_hmg_switchdelay_drop 0.2 +set g_balance_hmg_switchdelay_raise 0.2 // }}} + // {{{ RPC set g_balance_rpc_ammo 10 set g_balance_rpc_animtime 1 @@ -740,5 +744,7 @@ set g_balance_rpc_speedaccel 0 set g_balance_rpc_speedstart 1250 set g_balance_rpc_reload_ammo 10 set g_balance_rpc_reload_time 1 +set g_balance_rpc_switchdelay_drop 0.2 +set g_balance_rpc_switchdelay_raise 0.2 // }}} diff --git a/balanceXPM.cfg b/balanceXPM.cfg index fdce03b72..17fdbb727 100644 --- a/balanceXPM.cfg +++ b/balanceXPM.cfg @@ -723,6 +723,8 @@ set g_balance_hmg_bulletconstant 115 // 13.1qu set g_balance_hmg_reload_ammo 120 //default: 30 set g_balance_hmg_reload_time 1 +set g_balance_hmg_switchdelay_drop 0.2 +set g_balance_hmg_switchdelay_raise 0.2 // }}} // {{{ RPC @@ -742,4 +744,6 @@ set g_balance_rpc_speedaccel 0 set g_balance_rpc_speedstart 1250 set g_balance_rpc_reload_ammo 10 set g_balance_rpc_reload_time 1 +set g_balance_rpc_switchdelay_drop 0.2 +set g_balance_rpc_switchdelay_raise 0.2 // }}} diff --git a/qcsrc/client/waypointsprites.qc b/qcsrc/client/waypointsprites.qc index 6b3c52be2..22677604c 100644 --- a/qcsrc/client/waypointsprites.qc +++ b/qcsrc/client/waypointsprites.qc @@ -304,8 +304,8 @@ string spritelookuptext(string s) case "wpn-hlac": return _("HLAC"); case "wpn-campingrifle": return _("Rifle"); case "wpn-minelayer": return _("Mine Layer"); - case "wpn-hmg": return _("Heavy Machine Gun"); - case "wpn-rpc": return _("Rocket-Propelled Chainsaw"); + case "wpn-ok_hmg": return _("Heavy Machine Gun"); + case "wpn-ok_rl": return _("Rocket-Propelled Chainsaw"); case "dom-neut": return _("Control point"); case "dom-red": return _("Control point"); case "dom-blue": return _("Control point"); diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index c19757916..0ff90298c 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -1282,3 +1282,13 @@ float autocvar_g_campcheck_damage; float autocvar_g_campcheck_distance; float autocvar_g_campcheck_interval; float autocvar_g_jump_grunt; +float autocvar_g_overkill_spawnsystem; +float autocvar_g_overkill_spawnsystem_delay; +float autocvar_g_overkill_spawnsystem_delay_death; +float autocvar_g_overkill_spawnsystem_check_health; +float autocvar_g_overkill_spawnsystem_close2death; +float autocvar_g_overkill_powerups_replace; +float autocvar_g_overkill_superguns_respawn_time; +float autocvar_g_overkill_100h_anyway; +float autocvar_g_overkill_100a_anyway; +float autocvar_g_overkill_ammo_start; diff --git a/qcsrc/server/mutators/mutator_overkill.qc b/qcsrc/server/mutators/mutator_overkill.qc new file mode 100644 index 000000000..b5836b95a --- /dev/null +++ b/qcsrc/server/mutators/mutator_overkill.qc @@ -0,0 +1,364 @@ +MUTATOR_HOOKFUNCTION(ok_PlayerDamage_Calculate) +{ + if(!IS_PLAYER(frag_target) || frag_target == frag_attacker) + return FALSE; + + if not (DEATH_ISWEAPON(frag_deathtype, WEP_LASER)) + return FALSE; + + frag_damage = 0; + if(frag_target.health >= 1 && !frag_target.freezetag_frozen) + Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY); + + frag_force = '0 0 0'; + //frag_attacker = frag_target; + + return FALSE; +} + +MUTATOR_HOOKFUNCTION(ok_BuildMutatorsString) +{ + ret_string = strcat(ret_string, ":OK"); + return FALSE; +} + +MUTATOR_HOOKFUNCTION(ok_BuildMutatorsPrettyString) +{ + ret_string = strcat(ret_string, ", Overkill"); + return FALSE; +} + +void ok_Item_Touch() +{ + if(IS_PLAYER(other) && other.deadflag == DEAD_NO && !other.freezetag_frozen) + { + Item_Touch(); + remove(self); + } +} + +MUTATOR_HOOKFUNCTION(ok_PlayerDies) +{ + entity oldself = self; + float gpi = autocvar_g_pickup_items; + + self.ok_lastwep = self.weapon; + self.ok_deathloc = self.origin; + cvar_set("g_pickup_items", "1"); + self = spawn(); + self.noalign = TRUE; + spawnfunc_item_armor_small(); + self.movetype = MOVETYPE_TOSS; + self.gravity = 1; + setorigin(self, frag_target.origin + '0 0 32'); + self.velocity = '0 0 200' + normalize(frag_attacker.origin - self.origin) * 500; + self.touch = ok_Item_Touch; + SUB_SetFade(self, time + 5, 1); + self = oldself; + cvar_set("g_pickup_items", ftos(gpi)); + + return FALSE; +} + +MUTATOR_HOOKFUNCTION(ok_ForbidThrowCurrentWeapon) +{ + return TRUE; +} + +MUTATOR_HOOKFUNCTION(ok_PlayerPreThink) +{ + if(intermission_running || gameover) + return FALSE; + + if(self.deadflag != DEAD_NO || !IS_PLAYER(self)) + return FALSE; + + if(self.freezetag_frozen) + return FALSE; + + if(self.BUTTON_ATCK2) + if(self.jump_interval <= time) + { + self.jump_interval = time + autocvar_g_balance_laser_primary_refire * W_WeaponRateFactor(); + makevectors(self.v_angle); + float w = self.weapon; + self.weapon = WEP_LASER; + W_Laser_Attack(3); + self.weapon = w; + } + + self.BUTTON_ATCK2 = 0; + return FALSE; +} + +MUTATOR_HOOKFUNCTION(ok_PlayerSpawn) +{ + if(autocvar_g_overkill_spawnsystem_delay_death) + self.ok_spawnsys_timer = time + autocvar_g_overkill_spawnsystem_delay_death; + + if(teamplay == 0 || autocvar_g_overkill_spawnsystem == 0) + return FALSE; + + entity team_mate, best_mate = world; + vector best_spot = '0 0 0'; + float pc = 0., best_dist = 0., dist = 0.; + FOR_EACH_PLAYER(team_mate) + { + if((autocvar_g_overkill_spawnsystem_check_health != 0 && team_mate.health >= 100) || autocvar_g_overkill_spawnsystem_check_health == 0) + if(team_mate.deadflag == DEAD_NO) + if(team_mate.ok_spawnsys_timer < time) + if(team_mate.team == self.team && (g_ctf || g_tdm || g_keyhunt)) + if(team_mate != self) + { + tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate); + if(trace_fraction != 1.0) + if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) + { + pc = pointcontents(trace_endpos + '0 0 1'); + if(pc == CONTENT_EMPTY) + { + if(vlen(team_mate.velocity) > 5) + fixedmakevectors(vectoangles(team_mate.velocity)); + else + fixedmakevectors(team_mate.angles); + + for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate + { + switch(pc) + { + case 0: + tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate); + break; + case 1: + tracebox(team_mate.origin , PL_MIN, PL_MAX,team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate); + break; + case 2: + tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate); + break; + case 3: + tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate); + break; + case 4: + tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate); + break; + } + + if(trace_fraction == 1.0) + { + traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate); + if(trace_fraction != 1.0) + { + if(autocvar_g_overkill_spawnsystem_close2death) + { + dist = vlen(trace_endpos - self.ok_deathloc); + if(dist < best_dist || best_dist == 0) + { + best_dist = dist; + best_spot = trace_endpos; + best_mate = team_mate; + } + } + else + { + setorigin(self, trace_endpos); + self.angles = team_mate.angles; + team_mate.ok_spawnsys_timer = time + autocvar_g_overkill_spawnsystem_delay; + return FALSE; + } + } + } + } + } + } + } + } + + if(autocvar_g_overkill_spawnsystem_close2death) + if(best_dist) + { + setorigin(self, best_spot); + self.angles = best_mate.angles; + best_mate.ok_spawnsys_timer = time + autocvar_g_overkill_spawnsystem_delay; + } + + return 0; +} + +void start_hmg() +{ + float gpi = autocvar_g_pickup_items; + cvar_set("g_pickup_items", "1"); + self.classname = "weapon_hmg"; + //self.weapons = WEP_HMG; + //self.flags |= FL_POWERUP; + self.respawntime = autocvar_g_overkill_superguns_respawn_time; + setmodel(self, "models/weapons/g_ok_hmg.md3"); + spawnfunc_weapon_hmg(); + + cvar_set("g_pickup_items", ftos(gpi)); +} + +void start_rpc() +{ + float gpi = autocvar_g_pickup_items; + cvar_set("g_pickup_items", "1"); + self.classname = "weapon_rpc"; + self.respawntime = autocvar_g_overkill_superguns_respawn_time; + //self.weapons = WEP_RPC; + //self.flags |= FL_POWERUP; + setmodel(self, "models/weapons/g_ok_rl.md3"); + spawnfunc_weapon_rpc(); + cvar_set("g_pickup_items", ftos(gpi)); +} + +void start_mh_anyway() +{ + cvar_set("g_pickup_items", "1"); + self.classname = "item_health_mega"; + spawnfunc_item_health_mega(); + cvar_set("g_pickup_items", "0"); +} + +void start_ma_anyway() +{ + cvar_set("g_pickup_items", "1"); + self.classname = "item_armor_large"; + spawnfunc_item_armor_large(); + cvar_set("g_pickup_items", "0"); +} + +MUTATOR_HOOKFUNCTION(ok_OnEntityPreSpawn) +{ + if(autocvar_g_powerups != 0) + if(autocvar_g_overkill_powerups_replace) + if(self.classname == "item_strength") + { + entity wep = spawn(); + setorigin(wep, self.origin); + wep.think = start_hmg; + wep.nextthink = time + 0.1; + return TRUE; + } + + if(autocvar_g_powerups != 0) + if(autocvar_g_overkill_powerups_replace) + if(self.classname == "item_invincible") + { + entity wep = spawn(); + setorigin(wep, self.origin); + wep.think = start_rpc; + wep.nextthink = time + 0.1; + return TRUE; + } + + return FALSE; +} + +MUTATOR_HOOKFUNCTION(ok_ItemRemove) +{ + switch(self.items) + { + case IT_HEALTH: return !(autocvar_g_overkill_100h_anyway); + case IT_ARMOR: return !(autocvar_g_overkill_100a_anyway); + } + + return TRUE; +} + +MUTATOR_HOOKFUNCTION(ok_SetModname) +{ + modname = "Overkill"; + return TRUE; +} + +MUTATOR_HOOKFUNCTION(ok_StartItems) +{ + start_items |= IT_UNLIMITED_WEAPON_AMMO; + start_weapons = (WEPSET_UZI | WEPSET_NEX | WEPSET_SHOTGUN); + + start_ammo_nails = start_ammo_cells = start_ammo_shells = start_ammo_rockets = + warmup_start_ammo_nails = warmup_start_ammo_cells = warmup_start_ammo_shells = warmup_start_ammo_rockets = autocvar_g_overkill_ammo_start; + + return FALSE; +} + +void ok_Initialize() +{ + precache_all_playermodels("models/ok_player/*.dpm"); + + precache_model("models/weapons/h_ok_rl.iqm"); + precache_model("models/weapons/v_ok_rl.md3"); + precache_model("models/weapons/g_ok_rl.md3"); + precache_model("models/weapons/ok_rocket.md3"); + + precache_model("models/weapons/h_ok_mg.iqm"); + precache_model("models/weapons/v_ok_mg.md3"); + precache_model("models/weapons/g_ok_mg.md3"); + + precache_model("models/weapons/h_ok_hmg.iqm"); + precache_model("models/weapons/v_ok_hmg.md3"); + precache_model("models/weapons/g_ok_hmg.md3"); + + precache_model("models/weapons/h_ok_shotgun.iqm"); + precache_model("models/weapons/v_ok_shotgun.md3"); + precache_model("models/weapons/g_ok_shotgun.md3"); + + precache_model("models/weapons/h_ok_sniper.iqm"); + precache_model("models/weapons/v_ok_sniper.md3"); + precache_model("models/weapons/g_ok_sniper.md3"); + + w_uzi(WR_PRECACHE); + w_nex(WR_PRECACHE); + w_shotgun(WR_PRECACHE); + w_laser(WR_PRECACHE); + + (get_weaponinfo(WEP_RPC)).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED; + (get_weaponinfo(WEP_HMG)).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED; + + (get_weaponinfo(WEP_SHOTGUN)).mdl = "ok_shotgun"; + (get_weaponinfo(WEP_UZI)).mdl = "ok_mg"; + (get_weaponinfo(WEP_NEX)).mdl = "ok_sniper"; + + string s; + float fh = fopen("overkill.cfg", FILE_READ); + if(fh >= 0) + { + while((s = fgets(fh))) + { + tokenize_console(s); + if not(argv(0) == "" || argv(1) == "//" || argv(1) == "") + cvar_settemp(argv(0), argv(1)); + } + fclose(fh); + } + else + dprint("^1Mutator Overkill: WARNING! overkill.cfg NOT found, things will be strange!\n"); +} + +MUTATOR_DEFINITION(mutator_overkill) +{ + MUTATOR_HOOK(ForbidThrowCurrentWeapon, ok_ForbidThrowCurrentWeapon, CBC_ORDER_ANY); + MUTATOR_HOOK(BuildMutatorsString, ok_BuildMutatorsString, CBC_ORDER_ANY); + MUTATOR_HOOK(BuildMutatorsPrettyString, ok_BuildMutatorsPrettyString, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerPreThink, ok_PlayerPreThink, CBC_ORDER_LAST); + MUTATOR_HOOK(PlayerSpawn, ok_PlayerSpawn, CBC_ORDER_LAST); + MUTATOR_HOOK(PlayerDamage_Calculate, ok_PlayerDamage_Calculate, CBC_ORDER_LAST); + MUTATOR_HOOK(PlayerDies, ok_PlayerDies, CBC_ORDER_ANY); + MUTATOR_HOOK(OnEntityPreSpawn, ok_OnEntityPreSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(SetModname, ok_SetModname, CBC_ORDER_ANY); + MUTATOR_HOOK(FilterItem, ok_ItemRemove, CBC_ORDER_ANY); + MUTATOR_HOOK(SetStartItems, ok_StartItems, CBC_ORDER_ANY); + + MUTATOR_ONADD + { + ok_Initialize(); + } + + MUTATOR_ONREMOVE + { + (get_weaponinfo(WEP_RPC)).spawnflags |= WEP_FLAG_MUTATORBLOCKED; + (get_weaponinfo(WEP_HMG)).spawnflags |= WEP_FLAG_MUTATORBLOCKED; + } + + return FALSE; +} diff --git a/qcsrc/server/mutators/mutator_overkill.qh b/qcsrc/server/mutators/mutator_overkill.qh new file mode 100644 index 000000000..61b5f81fe --- /dev/null +++ b/qcsrc/server/mutators/mutator_overkill.qh @@ -0,0 +1,3 @@ +.vector ok_deathloc; +.float ok_spawnsys_timer; +.float ok_lastwep; diff --git a/qcsrc/server/w_hmg.qc b/qcsrc/server/w_hmg.qc new file mode 100644 index 000000000..3c9913dc6 --- /dev/null +++ b/qcsrc/server/w_hmg.qc @@ -0,0 +1,186 @@ +#ifdef REGISTER_WEAPON +REGISTER_WEAPON( +/* WEP_##id */ HMG, +/* function */ w_hmg, +/* ammotype */ IT_NAILS, +/* impulse */ 3, +/* flags */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON, +/* rating */ BOT_PICKUP_RATING_HIGH, +/* model */ "ok_hmg", +/* shortname */ "hmg", +/* fullname */ _("Heavy Machine Gun") +); +#else +#ifdef SVQC + +// weapon frames + +void hmg_fire_auto() +{ + float uzi_spread; + + if (!self.BUTTON_ATCK) + { + w_ready(); + return; + } + + if(autocvar_g_balance_hmg_reload_ammo) + if (!weapon_action(self.weapon, WR_CHECKAMMO1)) + if not(self.items & IT_UNLIMITED_WEAPON_AMMO) + { + W_SwitchWeapon_Force(self, w_getbestweapon(self)); + w_ready(); + return; + } + + W_DecreaseAmmo(ammo_nails, autocvar_g_balance_hmg_sustained_ammo, autocvar_g_balance_hmg_reload_ammo); + + W_SetupShot (self, autocvar_g_antilag_bullets && autocvar_g_balance_hmg_speed >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, autocvar_g_balance_hmg_sustained_damage); + if not(autocvar_g_norecoil) + { + self.punchangle_x = random () - 0.5; + self.punchangle_y = random () - 0.5; + } + + uzi_spread = bound(autocvar_g_balance_hmg_spread_min, autocvar_g_balance_hmg_spread_min + (autocvar_g_balance_hmg_spread_add * self.misc_bulletcounter), autocvar_g_balance_hmg_spread_max); + fireBallisticBullet(w_shotorg, w_shotdir, uzi_spread, autocvar_g_balance_hmg_speed, 5, autocvar_g_balance_hmg_sustained_damage, autocvar_g_balance_hmg_sustained_force, WEP_HMG, 0, 1, autocvar_g_balance_hmg_bulletconstant); + endFireBallisticBullet(); + + self.misc_bulletcounter = self.misc_bulletcounter + 1; + + pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); + + UziFlash(); + W_AttachToShotorg(self.muzzle_flash, '5 0 0'); + + if (autocvar_g_casings >= 2) // casing code + SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self); + + ATTACK_FINISHED(self) = time + autocvar_g_balance_hmg_sustained_refire * W_WeaponRateFactor(); + weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hmg_sustained_refire, hmg_fire_auto); +} + +void spawnfunc_weapon_hmg() +{ + weapon_defaultspawnfunc(WEP_HMG); +} + +float w_hmg(float req) +{ + float ammo_amount; + if (req == WR_AIM) + if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200) + self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE); + else + { + self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE); + } + else if (req == WR_THINK) + { + if(autocvar_g_balance_hmg_reload_ammo && self.clip_load < autocvar_g_balance_hmg_sustained_ammo) // forced reload + weapon_action(self.weapon, WR_RELOAD); + else + { + if (self.BUTTON_ATCK) + if (weapon_prepareattack(0, 0)) + { + self.misc_bulletcounter = 0; + hmg_fire_auto(); + } + + /* + if(self.BUTTON_ATCK2) + if(weapon_prepareattack(1, 0)) + { + if (!weapon_action(self.weapon, WR_CHECKAMMO2)) + if not(self.items & IT_UNLIMITED_WEAPON_AMMO) + { + W_SwitchWeapon_Force(self, w_getbestweapon(self)); + w_ready(); + return FALSE; + } + + W_DecreaseAmmo(ammo_nails, autocvar_g_balance_hmg_burst_ammo, autocvar_g_balance_hmg_reload_ammo); + + self.misc_bulletcounter = autocvar_g_balance_hmg_burst * -1; + uzi_mode1_fire_burst(); + } + */ + } + } + else if (req == WR_PRECACHE) + { + precache_model ("models/uziflash.md3"); + precache_model ("models/weapons/g_ok_hmg.md3"); + precache_model ("models/weapons/v_ok_hmg.md3"); + precache_model ("models/weapons/h_ok_hmg.iqm"); + precache_sound ("weapons/uzi_fire.wav"); + } + else if (req == WR_SETUP) + { + weapon_setup(WEP_HMG); + self.current_ammo = ammo_nails; + } + else if (req == WR_CHECKAMMO1) + { + ammo_amount = self.ammo_nails >= autocvar_g_balance_hmg_sustained_ammo; + + if(autocvar_g_balance_hmg_reload_ammo) + ammo_amount += self.(weapon_load[WEP_HMG]) >= autocvar_g_balance_hmg_sustained_ammo; + + return ammo_amount; + } + else if (req == WR_CHECKAMMO2) + { + ammo_amount = self.ammo_nails >= autocvar_g_balance_hmg_sustained_ammo; + + if(autocvar_g_balance_hmg_reload_ammo) + ammo_amount += self.(weapon_load[WEP_HMG]) >= autocvar_g_balance_hmg_sustained_ammo; + + return ammo_amount; + } + else if (req == WR_RELOAD) + { + W_Reload(autocvar_g_balance_hmg_sustained_ammo, autocvar_g_balance_hmg_reload_ammo, autocvar_g_balance_hmg_reload_time, "weapons/reload.wav"); + } + else if (req == WR_SUICIDEMESSAGE) + { + return WEAPON_THINKING_WITH_PORTALS; + } + else if (req == WR_KILLMESSAGE) + { + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_HMG_MURDER_SNIPE; + else + return WEAPON_HMG_MURDER_SPRAY; + } + return TRUE; +} +#endif +#ifdef CSQC +float w_hmg(float req) +{ + if(req == WR_IMPACTEFFECT) + { + vector org2; + org2 = w_org + w_backoff * 2; + pointparticles(particleeffectnum("machinegun_impact"), org2, w_backoff * 1000, 1); + if(!w_issilent) + if(w_random < 0.05) + sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTEN_NORM); + else if(w_random < 0.1) + sound(self, CH_SHOTS, "weapons/ric2.wav", VOL_BASE, ATTEN_NORM); + else if(w_random < 0.2) + sound(self, CH_SHOTS, "weapons/ric3.wav", VOL_BASE, ATTEN_NORM); + } + else if(req == WR_PRECACHE) + { + precache_sound("weapons/ric1.wav"); + precache_sound("weapons/ric2.wav"); + precache_sound("weapons/ric3.wav"); + } + return TRUE; +} +#endif +#endif diff --git a/qcsrc/server/w_rpc.qc b/qcsrc/server/w_rpc.qc new file mode 100644 index 000000000..5f3a7246f --- /dev/null +++ b/qcsrc/server/w_rpc.qc @@ -0,0 +1,226 @@ +#ifdef REGISTER_WEAPON +REGISTER_WEAPON( +/* WEP_##id */ RPC, +/* function */ w_rpc, +/* ammotype */ IT_ROCKETS, +/* impulse */ 7, +/* flags */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_SUPERWEAPON, +/* rating */ BOT_PICKUP_RATING_HIGH, +/* model */ "ok_rl", +/* shortname */ "rpc", +/* fullname */ _("Rocket Propelled Chainsaw") +); +#else +#ifdef SVQC + +void W_RPC_Explode() +{ + self.event_damage = func_null; + self.takedamage = DAMAGE_NO; + + RadiusDamage (self, self.realowner, autocvar_g_balance_rpc_damage, autocvar_g_balance_rpc_edgedamage, autocvar_g_balance_rpc_radius, world, autocvar_g_balance_rpc_force, self.projectiledeathtype, other); + + remove (self); +} + +void W_RPC_Touch (void) +{ + if(WarpZone_Projectile_Touch()) + if(wasfreed(self)) + return; + + //if(other.solid != SOLID_BSP) + // return; + + W_RPC_Explode(); +} + +void W_RPC_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + if (self.health <= 0) + return; + + if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions + return; // g_projectiles_damage says to halt + + self.health = self.health - damage; + + if (self.health <= 0) + W_PrepareExplosionByDamage(attacker, W_RPC_Explode); +} + +void W_RPC_Think() +{ + if(self.cnt <= time) + { + remove(self); + return; + } + + self.cnt = vlen(self.velocity); + self.wait = self.cnt * sys_frametime; + self.pos1 = normalize(self.velocity); + + tracebox(self.origin, self.mins, self.maxs, self.origin + self.pos1 * (2 * self.wait), MOVE_NORMAL, self); + if(IS_PLAYER(trace_ent)) + Damage (trace_ent, self, self.realowner, autocvar_g_balance_rpc_damage2, self.projectiledeathtype, self.origin, normalize(self.origin - other.origin) * autocvar_g_balance_rpc_force); + + self.velocity = self.pos1 * (self.cnt + (autocvar_g_balance_rpc_speedaccel * sys_frametime)); + + UpdateCSQCProjectile(self); + self.nextthink = time; +} + +void W_RPC_Attack (void) +{ + entity missile = spawn(); //WarpZone_RefSys_SpawnSameRefSys(self); + entity flash = spawn (); + + W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_rpc_ammo, autocvar_g_balance_rpc_reload_ammo); + W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", CH_WEAPON_A, autocvar_g_balance_rpc_damage); + pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1); + PROJECTILE_MAKETRIGGER(missile); + + missile.owner = missile.realowner = self; + missile.bot_dodge = TRUE; + missile.bot_dodgerating = autocvar_g_balance_rpc_damage * 2; + + missile.takedamage = DAMAGE_YES; + missile.damageforcescale = autocvar_g_balance_rpc_damageforcescale; + missile.health = autocvar_g_balance_rpc_health; + missile.event_damage = W_RPC_Damage; + missile.damagedbycontents = TRUE; + missile.movetype = MOVETYPE_FLY; + + missile.projectiledeathtype = WEP_RPC; + 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, autocvar_g_balance_rpc_speed, 0); + + missile.touch = W_RPC_Touch; + + missile.think = W_RPC_Think; + //missile.think = SUB_Remove; + missile.cnt = time + autocvar_g_balance_rpc_lifetime; + missile.nextthink = time; + //missile.nextthink = time + autocvar_g_balance_rpc_lifetime; + missile.flags = FL_PROJECTILE; + + CSQCProjectile(missile, TRUE, PROJECTILE_RPC, FALSE); + //CSQCProjectile(missile, TRUE, PROJECTILE_ROCKET, FALSE); + + setmodel (flash, "models/flash.md3"); // precision set below + SUB_SetFade (flash, time, 0.1); + flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION; + W_AttachToShotorg(flash, '5 0 0'); + missile.pos1 = missile.velocity; + + other = missile; MUTATOR_CALLHOOK(EditProjectile); + //BITXOR_ASSIGN(self.weaponentity.effects, EF_RESTARTANIM_BIT); +} + +void spawnfunc_weapon_rpc() +{ + weapon_defaultspawnfunc(WEP_RPC); +} + +float w_rpc(float req) +{ + float ammo_amount = FALSE; + + if (req == WR_AIM) + { + self.BUTTON_ATCK = bot_aim(autocvar_g_balance_rpc_speed, 0, autocvar_g_balance_rpc_lifetime, FALSE); + } + else if (req == WR_THINK) + { + if(autocvar_g_balance_rpc_reload_ammo && self.clip_load < autocvar_g_balance_rpc_ammo) + weapon_action(self.weapon, WR_RELOAD); + else + { + if (self.BUTTON_ATCK) + { + if(weapon_prepareattack(0, autocvar_g_balance_rpc_refire)) + { + W_RPC_Attack(); + weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_rpc_animtime, w_ready); + } + } + + if (self.BUTTON_ATCK2) + { + // to-do + } + } + } + else if (req == WR_PRECACHE) + { + precache_model ("models/flash.md3"); + /*precache_model ("models/weapons/g_rl.md3"); + precache_model ("models/weapons/v_rl.md3"); + precache_model ("models/weapons/h_rl.iqm");*/ + precache_sound ("weapons/rocket_det.wav"); + precache_sound ("weapons/rocket_fire.wav"); + precache_sound ("weapons/rocket_mode.wav"); + } + else if (req == WR_SETUP) + { + weapon_setup(WEP_RPC); + self.current_ammo = ammo_rockets; + } + else if (req == WR_CHECKAMMO1) + { + if(autocvar_g_balance_rpc_reload_ammo) + { + if(self.ammo_rockets < autocvar_g_balance_rpc_ammo && self.(weapon_load[WEP_RPC]) < autocvar_g_balance_rpc_ammo) + ammo_amount = TRUE; + } + else if(self.ammo_rockets < autocvar_g_balance_rpc_ammo) + ammo_amount = TRUE; + + return !ammo_amount; + } + else if (req == WR_CHECKAMMO2) + return FALSE; + else if (req == WR_RESETPLAYER) + { + } + else if (req == WR_RELOAD) + { + W_Reload(autocvar_g_balance_rpc_ammo, autocvar_g_balance_rpc_reload_ammo, autocvar_g_balance_rpc_reload_time, "weapons/reload.wav"); + } + else if (req == WR_SUICIDEMESSAGE) + { + return WEAPON_RPC_SUICIDE; + } + else if (req == WR_KILLMESSAGE) + { + if((w_deathtype & HITTYPE_BOUNCE) || (w_deathtype & HITTYPE_SPLASH)) + return WEAPON_RPC_MURDER_SPLASH; + else + return WEAPON_RPC_MURDER_DIRECT; + } + return TRUE; +} +#endif + +#ifdef CSQC +float w_rpc(float req) +{ + if(req == WR_IMPACTEFFECT) + { + vector org2; + org2 = w_org + w_backoff * 12; + pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1); + if(!w_issilent) + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + } + else if(req == WR_PRECACHE) + { + precache_sound("weapons/rocket_impact.wav"); + } + return TRUE; +} +#endif +#endif