X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Fbuffs%2Fsv_buffs.qc;h=83b471cd810e0c6ae992c9f115d70abc0cabff2a;hp=95216fe548c1c9c6bfe9c5a2c53cff1ea0cd39d5;hb=3cd90b2dd499cbe6419a8fe5e8a0ee339aaa191b;hpb=0dec7bcf5fa101452e59fe30b74daf24251d93e8 diff --git a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc index 95216fe548..83b471cd81 100644 --- a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc @@ -180,9 +180,11 @@ void buff_Touch(entity this, entity toucher) { if (CS(toucher).cvar_cl_buffs_autoreplace && STAT(BUFFS, toucher) != STAT(BUFFS, this)) { + // TODO: lost-gained notification for this case int buffid = buff_FirstFromFlags(STAT(BUFFS, toucher)).m_id; - //Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_DROP, STAT(BUFFS, toucher)); - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ITEM_BUFF_LOST, toucher.netname, buffid); + Send_Notification(NOTIF_ONE, toucher, MSG_INFO, INFO_ITEM_BUFF_LOST, toucher.netname, buffid); + if(!IS_INDEPENDENT_PLAYER(toucher)) + Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_INFO, INFO_ITEM_BUFF_LOST, toucher.netname, buffid); STAT(BUFFS, toucher) = 0; //sound(toucher, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); @@ -193,20 +195,25 @@ void buff_Touch(entity this, entity toucher) this.owner = toucher; this.buff_active = false; this.lifetime = 0; - int buffid = buff_FirstFromFlags(STAT(BUFFS, this)).m_id; - Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_GOT, buffid); - Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_INFO, INFO_ITEM_BUFF, toucher.netname, buffid); + entity thebuff = buff_FirstFromFlags(STAT(BUFFS, this)); + Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_GOT, thebuff.m_id); + if(!IS_INDEPENDENT_PLAYER(toucher)) + Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_INFO, INFO_ITEM_BUFF, toucher.netname, thebuff.m_id); Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1); sound(toucher, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM); STAT(BUFFS, toucher) |= (STAT(BUFFS, this)); + STAT(LAST_PICKUP, toucher) = time; + float bufftime = ((this.count) ? this.count : thebuff.m_time(thebuff)); + if(bufftime) + STAT(BUFF_TIME, toucher) = min(time + bufftime, max(STAT(BUFF_TIME, toucher), time) + bufftime); } float buff_Available(entity buff) { if (buff == BUFF_Null) return false; - if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only")))) + if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_AMMO) || cvar("g_melee_only"))) return false; if (buff == BUFF_VAMPIRE && cvar("g_vampire")) return false; @@ -221,7 +228,8 @@ void buff_NewType(entity ent) FOREACH(Buffs, buff_Available(it), { // if it's already been chosen, give it a lower priority - RandomSelection_AddEnt(it, max(0.2, 1 / it.buff_seencount), 1); + float myseencount = (it.buff_seencount > 0) ? it.buff_seencount : 1; // no division by zero please! + RandomSelection_AddEnt(it, max(0.2, 1 / myseencount), 1); }); entity newbuff = RandomSelection_chosen_ent; newbuff.buff_seencount += 1; // lower chances of seeing this buff again soon @@ -265,7 +273,7 @@ void buff_Think(entity this) { buff_SetCooldown(this, autocvar_g_buffs_cooldown_respawn + frametime); this.owner = NULL; - if(autocvar_g_buffs_randomize) + if(autocvar_g_buffs_randomize && (!teamplay || autocvar_g_buffs_randomize_teamplay)) buff_NewType(this); if(autocvar_g_buffs_random_location || (this.spawnflags & 64)) @@ -309,7 +317,7 @@ void buff_Waypoint_Reset(entity this) void buff_Reset(entity this) { - if(autocvar_g_buffs_randomize) + if(autocvar_g_buffs_randomize && (!teamplay || autocvar_g_buffs_randomize_teamplay)) buff_NewType(this); this.owner = NULL; buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate); @@ -339,6 +347,12 @@ bool buff_Customize(entity this, entity client) return true; } +void buff_Delete(entity this) +{ + WaypointSprite_Kill(this.buff_waypoint); + delete_fn(this); +} + void buff_Init(entity this) { if(!cvar("g_buffs")) { delete(this); return; } @@ -374,6 +388,7 @@ void buff_Init(entity this) buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate + max(0, game_starttime - time)); this.buff_active = !this.buff_activetime; this.pflags = PFLAGS_FULLDYNAMIC; + this.dtor = buff_Delete; if(this.spawnflags & 1) this.noalign = true; @@ -427,13 +442,13 @@ void buff_Medic_Heal(entity this) { continue; } - float hp = GetResourceAmount(it, RESOURCE_HEALTH); + float hp = GetResource(it, RES_HEALTH); if(hp >= 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)); + SetResource(it, RES_HEALTH, bound(0, hp + autocvar_g_buffs_medic_heal_amount, autocvar_g_balance_health_regenstable)); }); } @@ -464,11 +479,11 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) frag_damage *= autocvar_g_buffs_speed_damage_take; if(STAT(BUFFS, frag_target) & BUFF_MEDIC.m_itemid) - if((GetResourceAmount(frag_target, RESOURCE_HEALTH) - frag_damage) <= 0) + if((GetResource(frag_target, RES_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, GetResourceAmount(frag_target, RESOURCE_HEALTH) - autocvar_g_buffs_medic_survive_health); + frag_damage = max(5, GetResource(frag_target, RES_HEALTH) - autocvar_g_buffs_medic_survive_health); if(STAT(BUFFS, frag_target) & BUFF_JUMP.m_itemid) if(frag_deathtype == DEATH_FALL.m_id) @@ -494,10 +509,12 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) if(STAT(BUFFS, frag_attacker) & BUFF_BASH.m_itemid) if(frag_force) - if(frag_attacker == frag_target) - frag_force *= autocvar_g_buffs_bash_force_self; - else - frag_force *= autocvar_g_buffs_bash_force; + { + if(frag_attacker == frag_target) + frag_force *= autocvar_g_buffs_bash_force_self; + else + frag_force *= autocvar_g_buffs_bash_force; + } if(STAT(BUFFS, frag_attacker) & BUFF_DISABILITY.m_itemid) if(frag_target != frag_attacker) @@ -542,13 +559,13 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) if(DIFF_TEAM(frag_attacker, frag_target)) { 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 (GetResourceAmount(frag_target, RESOURCE_ARMOR)) + GetResource(frag_target, RES_HEALTH)); + GiveResourceWithLimit(frag_attacker, RES_HEALTH, amount, g_pickup_healthsmall_max); + if (GetResource(frag_target, RES_ARMOR)) { 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); + GetResource(frag_target, RES_ARMOR)); + GiveResourceWithLimit(frag_attacker, RES_ARMOR, amount, g_pickup_armorsmall_max); } } @@ -560,9 +577,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn) { entity player = M_ARGV(0, entity); - STAT(BUFFS, player) = 0; - STAT(BUFF_TIME, player) = 0; - PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately + player.oldbuffs = 0; // reset timers here to prevent them continuing after re-spawn player.buff_disability_time = 0; player.buff_disability_effect_time = 0; @@ -607,8 +622,10 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDies) if(STAT(BUFFS, frag_target)) { int buffid = buff_FirstFromFlags(STAT(BUFFS, frag_target)).m_id; - Send_Notification(NOTIF_ALL_EXCEPT, frag_target, MSG_INFO, INFO_ITEM_BUFF_LOST, frag_target.netname, buffid); + if(!IS_INDEPENDENT_PLAYER(frag_target)) + Send_Notification(NOTIF_ALL_EXCEPT, frag_target, MSG_INFO, INFO_ITEM_BUFF_LOST, frag_target.netname, buffid); STAT(BUFFS, frag_target) = 0; + STAT(BUFF_TIME, frag_target) = 0; if(frag_target.buff_model) { @@ -628,11 +645,12 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) { int buffid = buff_FirstFromFlags(STAT(BUFFS, player)).m_id; Send_Notification(NOTIF_ONE, player, MSG_MULTI, ITEM_BUFF_DROP, buffid); - Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); + if(!IS_INDEPENDENT_PLAYER(player)) + Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); STAT(BUFFS, player) = 0; + STAT(BUFF_TIME, player) = 0; PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); - //STAT(BUFF_TIME, player) = 0; // already notified sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); return true; } @@ -844,7 +862,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) Send_Notification(NOTIF_ONE, player, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message? sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); } - else + else if(!IS_INDEPENDENT_PLAYER(player)) Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); STAT(BUFFS, player) = 0; PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small @@ -896,12 +914,13 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) { entity buff = buff_FirstFromFlags(STAT(BUFFS, player)); float bufftime = buff != BUFF_Null ? buff.m_time(buff) : 0; - STAT(BUFF_TIME, player) = (bufftime) ? time + bufftime : 0; + if(STAT(BUFF_TIME, player) <= time) // if the player still has a buff countdown, don't reset it! + STAT(BUFF_TIME, player) = (bufftime) ? time + bufftime : 0; BUFF_ONADD(BUFF_AMMO) { - player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_WEAPON_AMMO); - player.items |= IT_UNLIMITED_WEAPON_AMMO; + player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_AMMO); + player.items |= IT_UNLIMITED_AMMO; if(STAT(BUFFS, player) & BUFF_AMMO.m_itemid) { @@ -919,9 +938,9 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) BUFF_ONREM(BUFF_AMMO) { if(player.buff_ammo_prev_infitems) - player.items |= IT_UNLIMITED_WEAPON_AMMO; + player.items |= IT_UNLIMITED_AMMO; else - player.items &= ~IT_UNLIMITED_WEAPON_AMMO; + player.items &= ~IT_UNLIMITED_AMMO; if(STAT(BUFFS, player) & BUFF_AMMO.m_itemid) {