X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Fbuffs%2Fsv_buffs.qc;h=6994c81761ad8ac68f289516ea405eda1a75f7c4;hb=9e113dae328809b5e7432f434649a35ebb185a52;hp=c02ac5687ea5664ec4a1b0498b067d3b9d3cbdc4;hpb=bc8f083fa131e0ac511f4ee7dd093e684a9f2cd6;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc index c02ac5687..6994c8176 100644 --- a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc @@ -85,7 +85,7 @@ bool buff_Waypoint_visible_for_player(entity this, entity player, entity view) if (view.buffs) { - return view.cvar_cl_buffs_autoreplace == false || view.buffs != this.owner.buffs; + return CS(view).cvar_cl_buffs_autoreplace == false || view.buffs != this.owner.buffs; } return WaypointSprite_visible_for_player(this, player, view); @@ -157,16 +157,8 @@ void buff_Touch(entity this, entity toucher) return; } - if((this.team && DIFF_TEAM(toucher, this)) - || (STAT(FROZEN, toucher)) - || (toucher.vehicle) - || (time < toucher.buff_shield) - || (!this.buff_active) - ) - { - // can't touch this + if(!this.buff_active) return; - } if(MUTATOR_CALLHOOK(BuffTouch, this, toucher)) return; @@ -175,9 +167,19 @@ void buff_Touch(entity this, entity toucher) if(!IS_PLAYER(toucher)) return; // incase mutator changed toucher + if((this.team && DIFF_TEAM(toucher, this)) + || (STAT(FROZEN, toucher)) + || (toucher.vehicle) + || (time < PS(toucher).buff_shield) + ) + { + // can't touch this + return; + } + if (toucher.buffs) { - if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs) + if (CS(toucher).cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs) { int buffid = buff_FirstFromFlags(toucher.buffs).m_id; //Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_DROP, toucher.buffs); @@ -214,15 +216,17 @@ float buff_Available(entity buff) .int buff_seencount; -void buff_NewType(entity ent, float cb) +void buff_NewType(entity ent) { RandomSelection_Init(); - FOREACH(Buffs, buff_Available(it), LAMBDA( - it.buff_seencount += 1; + FOREACH(Buffs, buff_Available(it), + { // if it's already been chosen, give it a lower priority - RandomSelection_AddFloat(it.m_itemid, 1, max(0.2, 1 / it.buff_seencount)); - )); - ent.buffs = RandomSelection_chosen_float; + RandomSelection_AddEnt(it, max(0.2, 1 / it.buff_seencount), 1); + }); + entity newbuff = RandomSelection_chosen_ent; + newbuff.buff_seencount += 1; // lower chances of seeing this buff again soon + ent.buffs = newbuff.m_itemid; } void buff_Think(entity this) @@ -258,12 +262,12 @@ void buff_Think(entity this) } if(!this.buff_active && !this.buff_activetime) - if(!this.owner || STAT(FROZEN, this.owner) || IS_DEAD(this.owner) || !this.owner.iscreature || !(this.owner.buffs & this.buffs) || this.pickup_anyway > 0 || (this.pickup_anyway >= 0 && autocvar_g_buffs_pickup_anyway)) + if(!this.owner || STAT(FROZEN, this.owner) || IS_DEAD(this.owner) || !this.owner.iscreature || this.owner.vehicle || !(this.owner.buffs & this.buffs) || this.pickup_anyway > 0 || (this.pickup_anyway >= 0 && autocvar_g_buffs_pickup_anyway)) { buff_SetCooldown(this, autocvar_g_buffs_cooldown_respawn + frametime); this.owner = NULL; if(autocvar_g_buffs_randomize) - buff_NewType(this, this.buffs); + buff_NewType(this); if(autocvar_g_buffs_random_location || (this.spawnflags & 64)) buff_Respawn(this); @@ -307,7 +311,7 @@ void buff_Waypoint_Reset(entity this) void buff_Reset(entity this) { if(autocvar_g_buffs_randomize) - buff_NewType(this, this.buffs); + buff_NewType(this); this.owner = NULL; buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate); buff_Waypoint_Reset(this); @@ -345,7 +349,7 @@ void buff_Init(entity this) entity buff = buff_FirstFromFlags(this.buffs); if(!this.buffs || !buff_Available(buff)) - buff_NewType(this, 0); + buff_NewType(this); this.classname = "item_buff"; this.solid = SOLID_TRIGGER; @@ -368,7 +372,7 @@ void buff_Init(entity this) //this.gravity = 100; this.color = buff.m_color; this.glowmod = buff_GlowColor(this); - buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate + game_starttime); + buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate + max(0, game_starttime - time)); this.buff_active = !this.buff_activetime; this.pflags = PFLAGS_FULLDYNAMIC; @@ -420,12 +424,17 @@ void buff_Medic_Heal(entity this) { FOREACH_CLIENT(IS_PLAYER(it) && it != this && vdist(it.origin - this.origin, <=, autocvar_g_buffs_medic_heal_range), { - if(SAME_TEAM(it, this)) - if(it.health < autocvar_g_balance_health_regenstable) + if (!SAME_TEAM(it, this)) + { + continue; + } + float hp = GetResourceAmount(it, RESOURCE_HEALTH); + if(hp >= autocvar_g_balance_health_regenstable) { - Send_Effect(EFFECT_HEALING, it.origin, '0 0 0', 1); - it.health = bound(0, it.health + autocvar_g_buffs_medic_heal_amount, autocvar_g_balance_health_regenstable); + continue; } + Send_Effect(EFFECT_HEALING, it.origin, '0 0 0', 1); + SetResourceAmount(it, RESOURCE_HEALTH, bound(0, hp + autocvar_g_buffs_medic_heal_amount, autocvar_g_balance_health_regenstable)); }); } @@ -435,22 +444,6 @@ float buff_Inferno_CalculateTime(float damg, float offset_x, float offset_y, flo } // mutator hooks -MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor) -{ - entity frag_target = M_ARGV(2, entity); - float frag_deathtype = M_ARGV(6, float); - float frag_damage = M_ARGV(7, float); - - if(frag_deathtype == DEATH_BUFF.m_id) { return; } - - if(frag_target.buffs & BUFF_RESISTANCE.m_itemid) - { - vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage); - M_ARGV(4, float) = v.x; // take - M_ARGV(5, float) = v.y; // save - } -} - MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) { entity frag_attacker = M_ARGV(1, entity); @@ -461,16 +454,22 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) if(frag_deathtype == DEATH_BUFF.m_id) { return; } + if(frag_target.buffs & BUFF_RESISTANCE.m_itemid) + { + float reduced = frag_damage * autocvar_g_buffs_resistance_blockpercent; + frag_damage = bound(0, frag_damage - reduced, frag_damage); + } + if(frag_target.buffs & BUFF_SPEED.m_itemid) if(frag_target != frag_attacker) frag_damage *= autocvar_g_buffs_speed_damage_take; if(frag_target.buffs & BUFF_MEDIC.m_itemid) - if((frag_target.health - frag_damage) <= 0) + if((GetResourceAmount(frag_target, RESOURCE_HEALTH) - frag_damage) <= 0) if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype)) if(frag_attacker) if(random() <= autocvar_g_buffs_medic_survive_chance) - frag_damage = max(5, frag_target.health - autocvar_g_buffs_medic_survive_health); + frag_damage = max(5, GetResourceAmount(frag_target, RESOURCE_HEALTH) - autocvar_g_buffs_medic_survive_health); if(frag_target.buffs & BUFF_JUMP.m_itemid) if(frag_deathtype == DEATH_FALL.m_id) @@ -543,9 +542,15 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) if(frag_target.takedamage) if(DIFF_TEAM(frag_attacker, frag_target)) { - frag_attacker.health = bound(0, frag_attacker.health + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.health), g_pickup_healthsmall_max); - if(frag_target.armorvalue) - frag_attacker.armorvalue = bound(0, frag_attacker.armorvalue + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.armorvalue), g_pickup_armorsmall_max); + float amount = bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, + GetResourceAmount(frag_target, RESOURCE_HEALTH)); + GiveResourceWithLimit(frag_attacker, RESOURCE_HEALTH, amount, g_pickup_healthsmall_max); + if (frag_target.armorvalue) + { + amount = bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, + GetResourceAmount(frag_target, RESOURCE_ARMOR)); + GiveResourceWithLimit(frag_attacker, RESOURCE_ARMOR, amount, g_pickup_armorsmall_max); + } } M_ARGV(4, float) = frag_damage; @@ -558,44 +563,31 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn) player.buffs = 0; player.buff_time = 0; + PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately // reset timers here to prevent them continuing after re-spawn player.buff_disability_time = 0; player.buff_disability_effect_time = 0; } -.float stat_sv_maxspeed; -.float stat_sv_airspeedlimit_nonqw; -.float stat_sv_jumpvelocity; - -MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics) +MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics_UpdateStats) { entity player = M_ARGV(0, entity); + // these automatically reset, no need to worry if(player.buffs & BUFF_SPEED.m_itemid) - { - player.stat_sv_maxspeed *= autocvar_g_buffs_speed_speed; - player.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_speed_speed; - } + STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_buffs_speed_speed; if(time < player.buff_disability_time) - { - player.stat_sv_maxspeed *= autocvar_g_buffs_disability_speed; - player.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_disability_speed; - } - - if(player.buffs & BUFF_JUMP.m_itemid) - { - // automatically reset, no need to worry - player.stat_sv_jumpvelocity = autocvar_g_buffs_jump_height; - } + STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_buffs_disability_speed; } -MUTATOR_HOOKFUNCTION(buffs, PlayerJump) +MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics) { entity player = M_ARGV(0, entity); + // these automatically reset, no need to worry if(player.buffs & BUFF_JUMP.m_itemid) - M_ARGV(1, float) = autocvar_g_buffs_jump_height; + STAT(MOVEVARS_JUMPVELOCITY, player) = autocvar_g_buffs_jump_height; } MUTATOR_HOOKFUNCTION(buffs, MonsterMove) @@ -640,7 +632,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; - player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); + PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); //player.buff_time = 0; // already notified sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); return true; @@ -656,7 +648,7 @@ MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon) { float best_distance = autocvar_g_buffs_swapper_range; entity closest = NULL; - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it), { if(!IS_DEAD(it) && !STAT(FROZEN, it) && !it.vehicle) if(DIFF_TEAM(it, player)) { @@ -667,7 +659,7 @@ MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon) closest = it; } } - )); + }); if(closest) { @@ -758,7 +750,7 @@ MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST) switch(ent.classname) { case "item_strength": - case "item_invincible": + case "item_shield": { entity e = spawn(); buff_SpawnReplacement(e, ent); @@ -795,7 +787,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) { entity player = M_ARGV(0, entity); - if(game_stopped || IS_DEAD(player)) return; + if(game_stopped || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return; if(player.buffs & BUFF_FLIGHT.m_itemid) { @@ -842,7 +834,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) else Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; - player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small + PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small } } @@ -970,7 +962,8 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) } else { - delete(player.buff_model); + if(player.buff_model) + delete(player.buff_model); player.buff_model = NULL; player.effects &= ~(EF_NOSHADOW); @@ -996,28 +989,7 @@ MUTATOR_HOOKFUNCTION(buffs, SpectateCopy) entity client = M_ARGV(1, entity); client.buffs = spectatee.buffs; -} - -MUTATOR_HOOKFUNCTION(buffs, VehicleEnter) -{ - entity player = M_ARGV(0, entity); - entity veh = M_ARGV(1, entity); - - veh.buffs = player.buffs; - player.buffs = 0; - veh.buff_time = max(0, player.buff_time - time); - player.buff_time = 0; -} - -MUTATOR_HOOKFUNCTION(buffs, VehicleExit) -{ - entity player = M_ARGV(0, entity); - entity veh = M_ARGV(1, entity); - - player.buffs = player.oldbuffs = veh.buffs; - veh.buffs = 0; - player.buff_time = time + veh.buff_time; - veh.buff_time = 0; + client.buff_time = spectatee.buff_time; } MUTATOR_HOOKFUNCTION(buffs, PlayerRegen)