From e8738b522328064026d220fffa3681853ec9de0b Mon Sep 17 00:00:00 2001 From: Jakob MG Date: Sat, 25 Aug 2012 18:08:09 +0200 Subject: [PATCH] new functions for g_superspectate: cmd autospec [strength|shield|mega_health|mega_armor] [on|off] Allows automatic switcihng to client that grabbed the relevant item. Options can be combined rpn style (ex: strength mega_health on shield mega_armor off --- qcsrc/server/miscfunctions.qc | 1 + qcsrc/server/mutators/base.qh | 5 ++ qcsrc/server/mutators/mutator_superspec.qc | 84 ++++++++++++++++++++++ qcsrc/server/t_items.qc | 4 +- 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index 1e8cb45aa..bb0d52803 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -95,6 +95,7 @@ string STR_OBSERVER = "observer"; #define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(v.flags & FL_CLIENT) #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL) #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(v.classname == STR_PLAYER) +#define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if(v.classname != STR_PLAYER) #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(v.classname == STR_PLAYER) #endif diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index 236e311b6..2ab407e1c 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -212,3 +212,8 @@ MUTATOR_HOOKABLE(SetWeaponreplace); entity other; // weapon info // IN+OUT string ret_string; + +MUTATOR_HOOKABLE(ItemTouch); + // called at when a item is touched. Called early, can edit item properties. + entity self; // item + entity other; // player diff --git a/qcsrc/server/mutators/mutator_superspec.qc b/qcsrc/server/mutators/mutator_superspec.qc index 2adef63df..5e5e44460 100644 --- a/qcsrc/server/mutators/mutator_superspec.qc +++ b/qcsrc/server/mutators/mutator_superspec.qc @@ -1,3 +1,11 @@ +#define ASF_STRENGTH 1 +#define ASF_SHIELD 2 +#define ASF_MEGA_AR 4 +#define ASF_MEGA_HP 8 +#define ASF_ALL 0xFFFFFF + +.float autospec_flags; + float _spectate(entity _player) { if(SpectateNext(_player) == 1) @@ -8,6 +16,25 @@ float _spectate(entity _player) return TRUE; } +MUTATOR_HOOKFUNCTION(superspec_ItemTouch) +{ + entity _oldself = self; + entity _item = self; + + FOR_EACH_SPEC(self) + { + if( (self.autospec_flags & ASF_SHIELD && _item.invincible_finished) || + (self.autospec_flags & ASF_STRENGTH && _item.strength_finished) || + (self.autospec_flags & ASF_MEGA_AR && _item.classname == "item_armor_large") || + (self.autospec_flags & ASF_MEGA_HP && _item.classname == "item_health_mega") ) + _spectate(other); + } + + self = _oldself; + + return FALSE; +} + MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand) { if(MUTATOR_RETURNVALUE) // command was already handled? @@ -16,6 +43,62 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand) if(self.classname == "player") return FALSE; + if(cmd_name == "autospec") + { + if(cmd_argc > 1) + { +#define STRING2FLAG(str,flg) if(argv(i) == str) _bits |= flg + float i, _bits, _start = 1; + if(argv(1) == "clear") + { + self.autospec_flags = 0; + _start = 2; + } + + for(i = _start; i < cmd_argc; ++i) + { + if(argv(i) == "on" || argv(i) == "1")ยง + { + self.autospec_flags |= _bits; + _bits = 0; + } + else if(argv(i) == "off" || argv(i) == "0") + { + if(_start == 1) + self.autospec_flags &~= _bits; + + _bits = 0; + } + else + { + STRING2FLAG("strength", ASF_STRENGTH); + STRING2FLAG("shield", ASF_SHIELD); + STRING2FLAG("mega_health", ASF_MEGA_HP); + STRING2FLAG("mega_armor", ASF_MEGA_AR); + STRING2FLAG("all", ASF_ALL); + } + } + } + + string _aspeco = "^3Current auto spectate options are:\n\n\n\n\n"; +#undef STRING2FLAG + +#define SPECOCLR(var,test,text) \ + var = strcat(var, ((self.autospec_flags & test) ? "^2" : "^1")); \ + var = strcat(var,text) + + SPECOCLR(_aspeco, ASF_STRENGTH, "Strength\n\n"); + SPECOCLR(_aspeco, ASF_SHIELD, "Shiled\n\n"); + SPECOCLR(_aspeco, ASF_MEGA_HP, "Mega Health\n\n"); + SPECOCLR(_aspeco, ASF_MEGA_AR, "Mega Armor\n\n"); +#undef SPECOCLR + + centerprint(self, _aspeco); + return TRUE; + + return TRUE; + } + if(cmd_name == "followpowerup") { entity _player; @@ -120,6 +203,7 @@ MUTATOR_DEFINITION(mutator_superspec) MUTATOR_HOOK(BuildMutatorsString, superspec_BuildMutatorsString, CBC_ORDER_ANY); MUTATOR_HOOK(BuildMutatorsPrettyString, superspec_BuildMutatorsPrettyString, CBC_ORDER_ANY); MUTATOR_HOOK(SV_ParseClientCommand, superspec_SV_ParseClientCommand, CBC_ORDER_ANY); + MUTATOR_HOOK(ItemTouch, superspec_ItemTouch, CBC_ORDER_ANY); //MUTATOR_HOOK(ClientConnect, superspec_ClientConnect, CBC_ORDER_ANY); //MUTATOR_HOOK(PlayerSpawn, superspec_PlayerSpawn, CBC_ORDER_ANY); //MUTATOR_HOOK(PlayerPreThink, superspec_PlayerPreThink, CBC_ORDER_ANY); diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index 13850fcad..9ed5acb92 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -747,7 +747,7 @@ float Item_GiveTo(entity item, entity player) void Item_Touch (void) { entity e, head; - + // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky) if(self.classname == "droppedweapon") { @@ -766,6 +766,8 @@ void Item_Touch (void) return; if (self.owner == other) return; + if(MUTATOR_CALLHOOK(ItemTouch)) + return; if (self.classname == "droppedweapon") { -- 2.39.2