X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Finstagib%2Fsv_instagib.qc;h=63f3182ea6ba4746abb57d5491c5c97d29294adc;hp=1561dc10db9a326acf932de70df86365e179bd4f;hb=3331142a41bd023ef15ced5210a2e1a2206bbb3c;hpb=da674c235adfdc6b7a33bebb22f42e1be34224e8 diff --git a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc index 1561dc10d..63f3182ea 100644 --- a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc +++ b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc @@ -1,5 +1,9 @@ #include "sv_instagib.qh" +#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; @@ -13,21 +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, autocvar_g_instagib && !g_nexball); - -spawnfunc(item_minst_cells) +IntrusiveList g_instagib_items; +STATIC_INIT(instagib) { - if (!g_instagib) { delete(this); return; } - 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); } @@ -38,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) @@ -60,7 +82,7 @@ void instagib_ammocheck(entity this) if(IS_DEAD(this) || game_stopped) instagib_stop_countdown(this); - else if (GetResourceAmount(this, RESOURCE_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) { @@ -72,63 +94,63 @@ void instagib_ammocheck(entity this) } else { - float hp = GetResourceAmount(this, RESOURCE_HEALTH); + float hp = GetResource(this, RES_HEALTH); this.instagib_needammo = true; 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 (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 (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 (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 (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 (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 (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 (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 (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 (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; @@ -139,6 +161,13 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, MatchEnd) 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); @@ -170,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); @@ -240,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) @@ -295,11 +328,11 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate) if(!autocvar_g_instagib_friendlypush && SAME_TEAM(frag_target, frag_attacker)) frag_force = '0 0 0'; - float armor = GetResourceAmount(frag_target, RESOURCE_ARMOR); + float armor = GetResource(frag_target, RES_ARMOR); if(armor) { armor -= 1; - SetResourceAmount(frag_target, RESOURCE_ARMOR, armor); + SetResource(frag_target, RES_ARMOR, armor); frag_damage = 0; frag_target.damage_dealt += 1; frag_attacker.damage_dealt += 1; @@ -320,7 +353,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate) if(frag_target != frag_attacker) { - if(frag_damage <= 0 && GetResourceAmount(frag_target, RESOURCE_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'; } @@ -333,11 +366,11 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate) if(frag_mirrordamage > 0) { // just lose extra LIVES, don't kill the player for mirror damage - float armor = GetResourceAmount(frag_attacker, RESOURCE_ARMOR); + float armor = GetResource(frag_attacker, RES_ARMOR); if(armor > 0) { armor -= 1; - SetResourceAmount(frag_attacker, RESOURCE_ARMOR, armor); + 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; } @@ -377,13 +410,13 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, SetWeaponArena) 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) @@ -423,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)) { - SetResourceAmount(item, RESOURCE_CELLS, autocvar_g_instagib_ammo_drop); + SetResource(item, RES_CELLS, autocvar_g_instagib_ammo_drop); return false; } @@ -438,9 +471,9 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, FilterItem) if(item.flags & FL_POWERUP) return false; - float cells = GetResourceAmount(item, RESOURCE_CELLS); - if(cells > autocvar_g_instagib_ammo_drop && item.classname != "item_minst_cells") - SetResourceAmount(item, RESOURCE_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(cells && !item.weapon) return false; @@ -475,10 +508,10 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, ItemTouch) entity item = M_ARGV(0, entity); entity toucher = M_ARGV(1, entity); - if(GetResourceAmount(item, RESOURCE_CELLS)) + if(GetResource(item, RES_CELLS)) { // play some cool sounds ;) - float hp = GetResourceAmount(toucher, RESOURCE_HEALTH); + float hp = GetResource(toucher, RES_HEALTH); if (IS_CLIENT(toucher)) { if(hp <= 5) @@ -488,14 +521,14 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, ItemTouch) } if(hp < 100) - SetResourceAmount(toucher, RESOURCE_HEALTH, 100); + SetResource(toucher, RES_HEALTH, 100); return MUT_ITEMTOUCH_CONTINUE; } if(item.itemdef == ITEM_ExtraLife) { - GiveResource(toucher, RESOURCE_ARMOR, 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; } @@ -508,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;