X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Finstagib%2Fsv_instagib.qc;h=fefad540b24c6b18cb76a1f1d22196023458ce9e;hb=7a450de6b250eccb737d4c428b634496b933e4ff;hp=6135e72b556a1aa3d7934fdbc4d631b161981df4;hpb=f31fd63f70c9577ca1ad9a0292c73f42a33ce11f;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc index 6135e72b5..63f3182ea 100644 --- a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc +++ b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc @@ -1,6 +1,15 @@ #include "sv_instagib.qh" -int autocvar_g_instagib_ammo_drop; +#include +#include +#include "../random_items/sv_random_items.qh" + +bool autocvar_g_instagib_damagedbycontents = true; +bool autocvar_g_instagib_blaster_keepdamage = false; +bool autocvar_g_instagib_blaster_keepforce = false; +bool autocvar_g_instagib_mirrordamage; +bool autocvar_g_instagib_friendlypush = true; +//int autocvar_g_instagib_ammo_drop; bool autocvar_g_instagib_ammo_convert_cells; bool autocvar_g_instagib_ammo_convert_rockets; bool autocvar_g_instagib_ammo_convert_shells; @@ -8,22 +17,19 @@ bool autocvar_g_instagib_ammo_convert_bullets; int autocvar_g_instagib_extralives; float autocvar_g_instagib_speed_highspeed; -#include - -#include - -REGISTER_MUTATOR(mutator_instagib, cvar("g_instagib") && !g_nexball); - -spawnfunc(item_minst_cells) +IntrusiveList g_instagib_items; +STATIC_INIT(instagib) { - if (!g_instagib) { delete(this); return; } - if (!this.ammo_cells) this.ammo_cells = autocvar_g_instagib_ammo_drop; - StartItem(this, ITEM_VaporizerCells); + g_instagib_items = IL_NEW(); + IL_PUSH(g_instagib_items, ITEM_VaporizerCells); + IL_PUSH(g_instagib_items, ITEM_ExtraLife); + IL_PUSH(g_instagib_items, ITEM_Invisibility); + IL_PUSH(g_instagib_items, ITEM_Speed); } void instagib_invisibility(entity this) { - this.strength_finished = autocvar_g_balance_powerup_strength_time; + this.strength_finished = autocvar_g_instagib_invisibility_time; StartItem(this, ITEM_Invisibility); } @@ -34,10 +40,30 @@ void instagib_extralife(entity this) void instagib_speed(entity this) { - this.invincible_finished = autocvar_g_balance_powerup_invincible_time; + this.invincible_finished = autocvar_g_instagib_speed_time; StartItem(this, ITEM_Speed); } +/// \brief Returns a random classname of the instagib item. +/// \param[in] prefix Prefix of the cvars that hold probabilities. +/// \return Random classname of the instagib item. +string RandomItems_GetRandomInstagibItemClassName(string prefix) +{ + RandomSelection_Init(); + IL_EACH(g_instagib_items, Item_IsDefinitionAllowed(it), + { + string cvar_name = sprintf("g_%s_%s_probability", prefix, + it.m_canonical_spawnfunc); + if (!(cvar_type(cvar_name) & CVAR_TYPEFLAG_EXISTS)) + { + LOG_WARNF("Random items: cvar %s doesn't exist.", cvar_name); + continue; + } + RandomSelection_AddString(it.m_canonical_spawnfunc, cvar(cvar_name), 1); + }); + return RandomSelection_chosen_string; +} + .float instagib_nextthink; .float instagib_needammo; void instagib_stop_countdown(entity e) @@ -54,9 +80,9 @@ void instagib_ammocheck(entity this) if(!IS_PLAYER(this)) return; // not a player - if(IS_DEAD(this) || gameover) + if(IS_DEAD(this) || game_stopped) instagib_stop_countdown(this); - else if (this.ammo_cells > 0 || (this.items & IT_UNLIMITED_WEAPON_AMMO) || (this.flags & FL_GODMODE)) + else if (GetResource(this, RES_CELLS) > 0 || (this.items & IT_UNLIMITED_WEAPON_AMMO) || (this.flags & FL_GODMODE)) instagib_stop_countdown(this); else if(autocvar_g_rm && autocvar_g_rm_laser) { @@ -68,62 +94,63 @@ void instagib_ammocheck(entity this) } else { + float hp = GetResource(this, RES_HEALTH); this.instagib_needammo = true; - if (this.health <= 5) + if (hp <= 5) { - Damage(this, this, this, 5, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 5, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_INSTAGIB_TERMINATED); } - else if (this.health <= 10) + else if (hp <= 10) { - Damage(this, this, this, 5, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 5, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_1); } - else if (this.health <= 20) + else if (hp <= 20) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_2); } - else if (this.health <= 30) + else if (hp <= 30) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_3); } - else if (this.health <= 40) + else if (hp <= 40) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_4); } - else if (this.health <= 50) + else if (hp <= 50) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_5); } - else if (this.health <= 60) + else if (hp <= 60) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_6); } - else if (this.health <= 70) + else if (hp <= 70) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_7); } - else if (this.health <= 80) + else if (hp <= 80) { - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_8); } - else if (this.health <= 90) + else if (hp <= 90) { Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_INSTAGIB_FINDAMMO); - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); Send_Notification(NOTIF_ONE, this, MSG_ANNCE, ANNCE_NUM_9); } else { Send_Notification(NOTIF_ONE_ONLY, this, MSG_MULTI, MULTI_INSTAGIB_FINDAMMO); - Damage(this, this, this, 10, DEATH_NOAMMO.m_id, this.origin, '0 0 0'); + Damage(this, this, this, 10, DEATH_NOAMMO.m_id, DMG_NOWEP, this.origin, '0 0 0'); } } this.instagib_nextthink = time + 1; @@ -131,14 +158,21 @@ void instagib_ammocheck(entity this) MUTATOR_HOOKFUNCTION(mutator_instagib, MatchEnd) { - FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(instagib_stop_countdown(it))); + FOREACH_CLIENT(IS_PLAYER(it), { instagib_stop_countdown(it); }); +} + +MUTATOR_HOOKFUNCTION(mutator_instagib, RandomItems_GetRandomItemClassName) +{ + M_ARGV(1, string) = RandomItems_GetRandomInstagibItemClassName( + M_ARGV(0, string)); + return true; } MUTATOR_HOOKFUNCTION(mutator_instagib, MonsterDropItem) { entity item = M_ARGV(1, entity); - item.monster_loot = spawnfunc_item_minst_cells; + item.monster_loot = ITEM_VaporizerCells; } MUTATOR_HOOKFUNCTION(mutator_instagib, MonsterSpawn) @@ -165,6 +199,11 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, MakePlayerObserver) instagib_stop_countdown(player); } +MUTATOR_HOOKFUNCTION(mutator_instagib, ForbidRandomStartWeapons) +{ + return true; +} + MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerSpawn) { entity player = M_ARGV(0, entity); @@ -235,14 +274,13 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPowerups) } } -.float stat_sv_maxspeed; - -MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPhysics) +MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPhysics_UpdateStats) { entity player = M_ARGV(0, entity); + // these automatically reset, no need to worry if(player.items & ITEM_Speed.m_itemid) - player.stat_sv_maxspeed = player.stat_sv_maxspeed * autocvar_g_instagib_speed_highspeed; + STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_instagib_speed_highspeed; } MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_SplitHealthArmor) @@ -257,7 +295,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, ForbidThrowCurrentWeapon) return true; } -MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_Calculate) +MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate) { entity frag_attacker = M_ARGV(1, entity); entity frag_target = M_ARGV(2, entity); @@ -290,13 +328,15 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_Calculate) if(!autocvar_g_instagib_friendlypush && SAME_TEAM(frag_target, frag_attacker)) frag_force = '0 0 0'; - if(frag_target.armorvalue) + float armor = GetResource(frag_target, RES_ARMOR); + if(armor) { - frag_target.armorvalue -= 1; + armor -= 1; + SetResource(frag_target, RES_ARMOR, armor); frag_damage = 0; frag_target.damage_dealt += 1; frag_attacker.damage_dealt += 1; - Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, frag_target.armorvalue); + Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, armor); } } @@ -313,7 +353,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_Calculate) if(frag_target != frag_attacker) { - if(frag_damage <= 0 && frag_target.health > 0) { Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE); } + if(frag_damage <= 0 && GetResource(frag_target, RES_HEALTH) > 0) { Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE); } if(!autocvar_g_instagib_blaster_keepforce) frag_force = '0 0 0'; } @@ -326,10 +366,12 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerDamage_Calculate) if(frag_mirrordamage > 0) { // just lose extra LIVES, don't kill the player for mirror damage - if(frag_attacker.armorvalue > 0) + float armor = GetResource(frag_attacker, RES_ARMOR); + if(armor > 0) { - frag_attacker.armorvalue -= 1; - Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, frag_attacker.armorvalue); + armor -= 1; + SetResource(frag_attacker, RES_ARMOR, armor); + Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, armor); frag_attacker.damage_dealt += frag_mirrordamage; } frag_mirrordamage = 0; @@ -354,21 +396,27 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, SetStartItems) start_ammo_cells = warmup_start_ammo_cells = cvar("g_instagib_ammo_start"); start_ammo_plasma = warmup_start_ammo_plasma = 0; start_ammo_rockets = warmup_start_ammo_rockets = 0; - start_ammo_fuel = warmup_start_ammo_fuel = 0; + //start_ammo_fuel = warmup_start_ammo_fuel = 0; start_weapons = warmup_start_weapons = WEPSET(VAPORIZER); start_items |= IT_UNLIMITED_SUPERWEAPONS; } +MUTATOR_HOOKFUNCTION(mutator_instagib, SetWeaponArena) +{ + // turn weapon arena off + M_ARGV(0, string) = "off"; +} + void replace_with_insta_cells(entity item) { - entity e = spawn(); + entity e = new(item_vaporizer_cells); setorigin(e, item.origin); - e.noalign = item.noalign; + e.noalign = Item_ShouldKeepPosition(item); e.cnt = item.cnt; e.team = item.team; e.spawnfunc_checked = true; - spawnfunc_item_minst_cells(e); + spawnfunc_item_vaporizer_cells(e); } MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem) @@ -408,9 +456,9 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem) return true; } - if(item.weapon == WEP_VAPORIZER.m_id && item.classname == "droppedweapon") + if(item.weapon == WEP_VAPORIZER.m_id && Item_IsLoot(item)) { - item.ammo_cells = autocvar_g_instagib_ammo_drop; + SetResource(item, RES_CELLS, autocvar_g_instagib_ammo_drop); return false; } @@ -423,10 +471,11 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem) if(item.flags & FL_POWERUP) return false; - if(item.ammo_cells > autocvar_g_instagib_ammo_drop && item.classname != "item_minst_cells") - item.ammo_cells = autocvar_g_instagib_ammo_drop; + float cells = GetResource(item, RES_CELLS); + if(cells > autocvar_g_instagib_ammo_drop && item.classname != "item_vaporizer_cells") + SetResource(item, RES_CELLS, autocvar_g_instagib_ammo_drop); - if(item.ammo_cells && !item.weapon) + if(cells && !item.weapon) return false; return true; @@ -459,26 +508,27 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, ItemTouch) entity item = M_ARGV(0, entity); entity toucher = M_ARGV(1, entity); - if(item.ammo_cells) + if(GetResource(item, RES_CELLS)) { // play some cool sounds ;) + float hp = GetResource(toucher, RES_HEALTH); if (IS_CLIENT(toucher)) { - if(toucher.health <= 5) + if(hp <= 5) Send_Notification(NOTIF_ONE, toucher, MSG_ANNCE, ANNCE_INSTAGIB_LASTSECOND); - else if(toucher.health < 50) + else if(hp < 50) Send_Notification(NOTIF_ONE, toucher, MSG_ANNCE, ANNCE_INSTAGIB_NARROWLY); } - if(toucher.health < 100) - toucher.health = 100; + if(hp < 100) + SetResource(toucher, RES_HEALTH, 100); return MUT_ITEMTOUCH_CONTINUE; } if(item.itemdef == ITEM_ExtraLife) { - toucher.armorvalue = bound(toucher.armorvalue, 999, toucher.armorvalue + autocvar_g_instagib_extralives); + GiveResource(toucher, RES_ARMOR, autocvar_g_instagib_extralives); Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES); return MUT_ITEMTOUCH_PICKUP; } @@ -491,18 +541,27 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, OnEntityPreSpawn) if (!autocvar_g_powerups) { return; } entity ent = M_ARGV(0, entity); // Can't use .itemdef here - if (!(ent.classname == "item_strength" || ent.classname == "item_invincible" || ent.classname == "item_health_mega")) + if (!(ent.classname == "item_strength" || ent.classname == "item_shield" || ent.classname == "item_health_mega")) return; entity e = spawn(); float r = random(); if (r < 0.3) + { + e.classname = "item_invisibility"; setthink(e, instagib_invisibility); + } else if (r < 0.6) + { + e.classname = "item_extralife"; setthink(e, instagib_extralife); + } else + { + e.classname = "item_speed"; setthink(e, instagib_speed); + } e.nextthink = time + 0.1; e.spawnflags = ent.spawnflags;