X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_hook.qc;h=68aa7154ecdc3928261ea584bd251be2c86d2c03;hb=32190d3dc9786c24001a66dc8e2a07f41b6cc0a6;hp=cccba42bb42128fff96050498f317875c050c360;hpb=b4cde52de1bde884b6900277989abfb1c93d1bd4;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index cccba42bb..68aa7154e 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -1,5 +1,8 @@ #include "g_hook.qh" +#include +#include +#include #include "weapons/common.qh" #include "weapons/csqcprojectile.qh" #include "weapons/weaponsystem.qh" @@ -71,27 +74,42 @@ And you should be done! .float hook_length; -void RemoveGrapplingHook(entity pl) +void RemoveGrapplingHooks(entity pl) { - if(pl.hook == NULL) - return; - delete(pl.hook); - pl.hook = NULL; if(pl.move_movetype == MOVETYPE_FLY) set_movetype(pl, MOVETYPE_WALK); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(!pl.(weaponentity)) + continue; // continue incase other slots exist? + if(pl.(weaponentity).hook) + delete(pl.(weaponentity).hook); + pl.(weaponentity).hook = NULL; + } + //pl.disableclientprediction = false; } +void RemoveHook(entity this) +{ + entity player = this.realowner; + .entity weaponentity = this.weaponentity_fld; + + if(player.(weaponentity).hook == this) + player.(weaponentity).hook = NULL; + + if(player.move_movetype == MOVETYPE_FLY) + set_movetype(player, MOVETYPE_WALK); + delete(this); +} + void GrapplingHookReset(entity this) { - if(this.realowner.hook == this) - RemoveGrapplingHook(this.owner); - else // in any case: - delete(this); + RemoveHook(this); } -void GrapplingHookThink(entity this); void GrapplingHook_Stop(entity this) { Send_Effect(EFFECT_HOOK_IMPACT, this.origin, '0 0 0', 1); @@ -117,18 +135,15 @@ bool GrapplingHookSend(entity this, entity to, int sf) if(sf & 1) { WriteByte(MSG_ENTITY, etof(this.realowner)); + WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld)); } if(sf & 2) { - WriteCoord(MSG_ENTITY, this.hook_start.x); - WriteCoord(MSG_ENTITY, this.hook_start.y); - WriteCoord(MSG_ENTITY, this.hook_start.z); + WriteVector(MSG_ENTITY, this.hook_start); } if(sf & 4) { - WriteCoord(MSG_ENTITY, this.hook_end.x); - WriteCoord(MSG_ENTITY, this.hook_end.y); - WriteCoord(MSG_ENTITY, this.hook_end.z); + WriteVector(MSG_ENTITY, this.hook_end); } return true; } @@ -139,14 +154,15 @@ void GrapplingHookThink(entity this) { float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch; vector dir, org, end, v0, dv, v, myorg, vs; - if(this.realowner.hook != this) // how did that happen? + .entity weaponentity = this.weaponentity_fld; + if(this.realowner.(weaponentity).hook != this) // how did that happen? { error("Owner lost the hook!\n"); return; } - if(LostMovetypeFollow(this) || gameover || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade")) + if(LostMovetypeFollow(this) || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade")) { - RemoveGrapplingHook(this.realowner); + RemoveHook(this); return; } if(this.aiment) @@ -154,7 +170,7 @@ void GrapplingHookThink(entity this) this.nextthink = time; - int s = W_GetGunAlignment(this.realowner); + int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner)) - 1; vs = hook_shotorigin[s]; makevectors(this.realowner.v_angle); @@ -206,7 +222,7 @@ void GrapplingHookThink(entity this) v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity); // first pull the rope... - if(this.realowner.hook_state & HOOK_PULLING) + if(this.realowner.(weaponentity).hook_state & HOOK_PULLING) { newlength = this.hook_length; newlength = max(newlength - pullspeed * frametime, minlength); @@ -224,7 +240,7 @@ void GrapplingHookThink(entity this) if(pull_entity.move_movetype == MOVETYPE_FLY) set_movetype(pull_entity, MOVETYPE_WALK); - if(this.realowner.hook_state & HOOK_RELEASING) + if(this.realowner.(weaponentity).hook_state & HOOK_RELEASING) { newlength = dist; this.hook_length = newlength; @@ -266,7 +282,7 @@ void GrapplingHookThink(entity this) if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment)) { - RemoveGrapplingHook(this.realowner); + RemoveHook(this); return; } } @@ -311,7 +327,7 @@ void GrapplingHookTouch(entity this, entity toucher) GrapplingHook_Stop(this); if(toucher) - if(toucher.move_movetype != MOVETYPE_NONE) + //if(toucher.move_movetype != MOVETYPE_NONE) { SetMovetypeFollow(this, toucher); WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment); @@ -320,17 +336,17 @@ void GrapplingHookTouch(entity this, entity toucher) //this.realowner.disableclientprediction = true; } -void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) { - if(this.health <= 0) + if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0) return; if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions return; // g_balance_projectiledamage says to halt - this.health = this.health - damage; + TakeResource(this, RESOURCE_HEALTH, damage); - if (this.health <= 0) + if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0) { if(attacker != this.realowner) { @@ -338,36 +354,23 @@ void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float this.realowner.pushltime = time + autocvar_g_maxpushtime; this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner); } - RemoveGrapplingHook(this.realowner); + RemoveHook(this); } } -void FireGrapplingHook(entity actor) +void FireGrapplingHook(entity actor, .entity weaponentity) { - entity missile; - vector org; - vector vs; - if(forbidWeaponUse(actor)) return; if(actor.vehicle) return; - makevectors(actor.v_angle); - - int s = W_GetGunAlignment(actor); - vs = hook_shotorigin[s]; - - // UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds - sound (actor, CH_WEAPON_B, SND_HOOK_FIRE, VOL_BASE, ATTEN_NORM); - org = actor.origin + actor.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z; - - tracebox(actor.origin + actor.view_ofs, '-3 -3 -3', '3 3 3', org, MOVE_NORMAL, actor); - org = trace_endpos; - - Send_Effect(EFFECT_HOOK_MUZZLEFLASH, org, '0 0 0', 1); + // TODO: offhand hook shoots from eye + W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', true, 0, SND_HOOK_FIRE, CH_WEAPON_B, 0, WEP_HOOK.m_id); + Send_Effect(EFFECT_HOOK_MUZZLEFLASH, w_shotorg, '0 0 0', 1); - missile = WarpZone_RefSys_SpawnSameRefSys(actor); + entity missile = WarpZone_RefSys_SpawnSameRefSys(actor); missile.owner = missile.realowner = actor; - actor.hook = missile; + actor.(weaponentity).hook = missile; + missile.weaponentity_fld = weaponentity; missile.reset = GrapplingHookReset; missile.classname = "grapplinghook"; missile.flags = FL_PROJECTILE; @@ -379,11 +382,11 @@ void FireGrapplingHook(entity actor) //setmodel (missile, MDL_HOOK); // precision set below setsize (missile, '-3 -3 -3', '3 3 3'); - setorigin(missile, org); + setorigin(missile, w_shotorg); missile.state = 0; // not latched onto anything - W_SetupProjVelocity_Explicit(missile, v_forward, v_up, autocvar_g_balance_grapplehook_speed_fly, 0, 0, 0, false); + W_SetupProjVelocity_Explicit(missile, w_shotdir, v_up, autocvar_g_balance_grapplehook_speed_fly, 0, 0, 0, false); missile.angles = vectoangles (missile.velocity); //missile.glow_color = 250; // 244, 250 @@ -394,7 +397,7 @@ void FireGrapplingHook(entity actor) missile.effects = /*EF_FULLBRIGHT | EF_ADDITIVE |*/ EF_LOWPRECISION; - missile.health = autocvar_g_balance_grapplehook_health;//120 + SetResourceAmountExplicit(missile, RESOURCE_HEALTH, autocvar_g_balance_grapplehook_health); missile.event_damage = GrapplingHook_Damage; missile.takedamage = DAMAGE_AIM; missile.damageforcescale = 0;