From 3f7c0ebf799037762948c79834c8c275aa5dadcb Mon Sep 17 00:00:00 2001 From: avirox Date: Fri, 17 Feb 2006 17:49:56 +0000 Subject: [PATCH] - Put Client Commands in a seperate file - Added Nexuiz 1.5 voting and rcon system - Added HUD item for grenade timer git-svn-id: svn://svn.icculus.org/nexuiz/trunk@1081 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- TeamNexuiz/game/Nexuiz.opt | Bin 66048 -> 70656 bytes TeamNexuiz/game/gamec/GameC.dsp | 4 + TeamNexuiz/game/gamec/cl_client.c | 185 +------ TeamNexuiz/game/gamec/cl_impulse.c | 2 +- TeamNexuiz/game/gamec/cl_weapons.c | 3 +- TeamNexuiz/game/gamec/tf_constants.c | 3 + TeamNexuiz/game/gamec/tfdefs.c | 3 + TeamNexuiz/game/gamec/tfgrenades.c | 1 + TeamNexuiz/game/gamec/tfhud.c | 52 +- TeamNexuiz/game/gamec/tn_clientcommands.c | 598 ++++++++++++++++++++++ TeamNexuiz/game/progs.src | 1 + 11 files changed, 656 insertions(+), 196 deletions(-) create mode 100644 TeamNexuiz/game/gamec/tn_clientcommands.c diff --git a/TeamNexuiz/game/Nexuiz.opt b/TeamNexuiz/game/Nexuiz.opt index 5357b4056f6986326e853f86b6557efbd00c026c..f5b0e77b57537f9c304a6379ffd16740b623e925 100644 GIT binary patch literal 70656 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 NU_dY+82ExR@c#o0w{`#k literal 66048 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 BGT;CJ diff --git a/TeamNexuiz/game/gamec/GameC.dsp b/TeamNexuiz/game/gamec/GameC.dsp index 69d5e07e9..480a301ec 100644 --- a/TeamNexuiz/game/gamec/GameC.dsp +++ b/TeamNexuiz/game/gamec/GameC.dsp @@ -483,6 +483,10 @@ SOURCE=.\tffunctions.c SOURCE=.\tfmenus.c # End Source File +# Begin Source File + +SOURCE=.\tn_clientcommands.c +# End Source File # End Group # Begin Group "TF Client" diff --git a/TeamNexuiz/game/gamec/cl_client.c b/TeamNexuiz/game/gamec/cl_client.c index 191356d29..4779f18bd 100644 --- a/TeamNexuiz/game/gamec/cl_client.c +++ b/TeamNexuiz/game/gamec/cl_client.c @@ -213,11 +213,12 @@ entity () SelectSpawnPoint = // self.origin_z = self.origin_z + 30; if (!cvar("g_teamnexuiz_version")) self.current_menu = MENU_NEED_TN; - - stuffcmd(self, "alias menu_showteamselect \"set scmenu_directmenu TeamSelect; togglemenu\"\n"); - stuffcmd(self, "set scmenu_directmenu TeamSelect; togglemenu\n"); - - stuffcmd(self, "alias classmenu \"impulse 73\"\n"); + else + { + stuffcmd(self, "alias menu_showteamselect \"set scmenu_directmenu TeamSelect; togglemenu\"\n"); + stuffcmd(self, "set scmenu_directmenu TeamSelect; togglemenu\n"); + stuffcmd(self, "alias classmenu \"impulse 73\"\n"); + } // spot = find (world, classname, "item_tfgoal"); // return (spot); } @@ -299,7 +300,7 @@ entity () SelectSpawnPoint = } if (!spot) { -// spot = find (world, classname, "info_tfgoal"); + spot = find (world, classname, "info_tfgoal"); } if (!spot) { @@ -1228,175 +1229,3 @@ void PlayerPostThink (void) PlayerLasergatePostThink(); } -// Parse team join, class etc. -void SV_ParseClientCommand (string s) -{ - local float args; -// local float h; - local string c; - local string d; - local string f; - local string g; - local string i; - args = tokenize(s); - c = argv(0); - d = argv(1); - f = argv(2); - g = argv(3); - i = argv(4); - - if (c == "join") - { - return; - } - if (c == "changeclass") - { - stuffcmd(self, "set scmenu_directmenu ClassSelect; togglemenu\n"); - return; - } - if (c == "selectteam") - { - if (self.team_no > 0) - { - sprint(self, "You are already on a team!\n"); - return; - } - if (d == "auto" || d == "5") - { - TeamFortress_TeamPutPlayerInTeam(); - PutClientInServer (); - } - if (d == "blue" || d == "1") - { - TeamFortress_TeamSet (1); - PutClientInServer (); - } - if (d == "red" || d == "2") - { - TeamFortress_TeamSet (2); - PutClientInServer (); - } - if (d == "yellow" || d == "3") - { - TeamFortress_TeamSet (3); - PutClientInServer (); - } - if (d == "green" || d == "pink" || d == "4") // Morphed set it to Pink in the menus. I think - { // we should make it white instead. - TeamFortress_TeamSet (4); - PutClientInServer (); - } - return; - } - if (c == "selectclass") - { - if (self.team_no < 1) - { - sprint(self, "You must select a team to join first!\n"); - return; - } - if (TeamFortress_TeamIsCivilian (self.team_no)) - { - self.impulse = 1; - TeamFortress_ChangeClass (); - return; - } - if (self.playerclass > 0) // if a class is already chosen - { - self.tfstate = self.tfstate - (self.tfstate & 8); - local string cname; - if (d == ftos(TF_CLASS_SCOUT)) - { - cname = "scout"; - } - if (d == ftos(TF_CLASS_SOLDIER)) - { - cname = "soldier"; - } - if (d == ftos(TF_CLASS_MEDIC)) - { - cname = "medic"; - } - if (d == ftos(TF_CLASS_PYRO)) - { - cname = "pyro"; - } - if (d == ftos(TF_CLASS_ENGINEER)) - { - cname = "engineer"; - } - if (d == ftos(TF_CLASS_SPY)) - { - cname = "spy"; - } - if (d == ftos(TF_CLASS_RANDOM)) - { - self.tfstate = self.tfstate | 8; - sprint(self, "You will respawn as a random class.\n"); - } - if (cname != "") - { -// stuffcmd(self, "_cl_playermodel \"models/class/"); -// stuffcmd(self, cname); -// stuffcmd(self, "_mechanical.zym\"\n"); - if (cname == "engineer") - { - self.playermodel = strcat("models/class/",cname,"_other.zym"); - } - else - { - self.playermodel = strcat("models/class/",cname,"_mechanical.zym"); - } - if (self.is_dead == 1) // if player is dead, can change class - CheckForClassChange(); - } - } - else // if no class is chosen - { - if (d == ftos(TF_CLASS_SCOUT)) - { - self.impulse = TF_CLASS_SCOUT; - } - if (d == ftos(TF_CLASS_SOLDIER)) - { - self.impulse = TF_CLASS_SOLDIER; - } - if (d == ftos(TF_CLASS_MEDIC)) - { - self.impulse = TF_CLASS_MEDIC; - } - if (d == ftos(TF_CLASS_PYRO)) - { - self.impulse = TF_CLASS_PYRO; - } - if (d == ftos(TF_CLASS_ENGINEER)) - { - self.impulse = TF_CLASS_ENGINEER; - } - if (d == ftos(TF_CLASS_SPY)) - { - self.impulse = TF_CLASS_SPY; - } - if (d == ftos(TF_CLASS_RANDOM)) - { - self.impulse = TF_CLASS_RANDOM; - } - TeamFortress_ChangeClass(); - } - return; - } - else if (c == "check_val") - { - if (d == "r_bloom") - { - if (f == "1") - self.uses_bloom = 1; - else - self.uses_bloom = 0; - } - } - else - { - clientcommand(self, s); - } -}; \ No newline at end of file diff --git a/TeamNexuiz/game/gamec/cl_impulse.c b/TeamNexuiz/game/gamec/cl_impulse.c index 9ef3c1274..758fb3c92 100644 --- a/TeamNexuiz/game/gamec/cl_impulse.c +++ b/TeamNexuiz/game/gamec/cl_impulse.c @@ -160,7 +160,7 @@ void ImpulseCommands (void) TeamNexuiz_Feign(); } if (self.impulse == 153) - TeamNexuiz_HUD_ShowGrenadeOne(); + TeamNexuiz_HUD_ShowSign(self, NO_AMMO_WARNING); if (self.impulse >= 1 && self.impulse <= 5) { if(self.buttonuse) diff --git a/TeamNexuiz/game/gamec/cl_weapons.c b/TeamNexuiz/game/gamec/cl_weapons.c index f8cf1a257..bc5f15130 100644 --- a/TeamNexuiz/game/gamec/cl_weapons.c +++ b/TeamNexuiz/game/gamec/cl_weapons.c @@ -161,7 +161,8 @@ void(float imp) W_SwitchWeapon if (!client_hasweapon(self, imp, TRUE)) { if (!weapon_hasammo) - sprint(self, "You don't have any ammo for that weapon\n"); +// sprint(self, "You don't have any ammo for that weapon\n"); + TeamNexuiz_HUD_ShowSign(self, NO_AMMO_WARNING); else sprint(self, "You don't own that weapon\n"); } diff --git a/TeamNexuiz/game/gamec/tf_constants.c b/TeamNexuiz/game/gamec/tf_constants.c index 1cb9c8b50..f348c7b36 100644 --- a/TeamNexuiz/game/gamec/tf_constants.c +++ b/TeamNexuiz/game/gamec/tf_constants.c @@ -55,3 +55,6 @@ float CHESTSHOT = 2; float HEADSHOT = 3; float JETJUMP_NEEDROCKETS = 15; vector PL_FEIGN_VIEW_OFS = '0 0 10'; // feign view offset +// T:N HUD Items +float NO_AMMO_WARNING = 1; +float HUD_PRIME_GREN = 2; \ No newline at end of file diff --git a/TeamNexuiz/game/gamec/tfdefs.c b/TeamNexuiz/game/gamec/tfdefs.c index e5b38b130..fc8b55505 100644 --- a/TeamNexuiz/game/gamec/tfdefs.c +++ b/TeamNexuiz/game/gamec/tfdefs.c @@ -274,6 +274,9 @@ void (entity Goal, entity AP) DoGoalWork; void () button_wait; void () SUB_Remove; +// tfhud +void (entity ownr, float selection) TeamNexuiz_HUD_ShowSign; // show sprite icon + // tfsentry .float super_damage_finished; // turrets can get super charged too! //DP_QC_GETTAGINFO diff --git a/TeamNexuiz/game/gamec/tfgrenades.c b/TeamNexuiz/game/gamec/tfgrenades.c index 9b838c434..8b98ef01d 100644 --- a/TeamNexuiz/game/gamec/tfgrenades.c +++ b/TeamNexuiz/game/gamec/tfgrenades.c @@ -531,6 +531,7 @@ void () TeamFortress_PrimeGrenade = sprint (self, " primed, "); sprint (self, ptime); sprint (self, " seconds...\n"); + TeamNexuiz_HUD_ShowSign(self, HUD_PRIME_GREN); } } else diff --git a/TeamNexuiz/game/gamec/tfhud.c b/TeamNexuiz/game/gamec/tfhud.c index 9bf834e65..f001d2835 100644 --- a/TeamNexuiz/game/gamec/tfhud.c +++ b/TeamNexuiz/game/gamec/tfhud.c @@ -4,26 +4,46 @@ .entity grenadeoneentity; //.entity grenadetwoentity; -void () CL_GrenadeOneEntity_Think = +void () TeamNexuiz_HUD_GrenThink = { - return; + if (self.frame >= 10) + dremove(self); + self.frame = self.frame + 1; + self.nextthink = time + .4; }; -// Displays a grenade model on screen for every grenade a player has +void () TeamNexuiz_HUD_SignThink = +{ + if (self.alpha <= 0) + dremove(self); + self.alpha = self.alpha - .2; + self.nextthink = time + .1; +}; + +// Displays "No Ammo" sign // ok this was a dumb idea >.< lets just use csqc -void () TeamNexuiz_HUD_ShowGrenadeOne = +void (entity ownr, float selection) TeamNexuiz_HUD_ShowSign = { precache_model("models/hud_nobul.sp2"); - self.grenadeoneentity = spawn(); - self.grenadeoneentity.solid = SOLID_NOT; - self.grenadeoneentity.owner = self; - self.grenadeoneentity.grenadeoneentity = self.grenadeoneentity; - setmodel(self.grenadeoneentity, "models/hud_nobul.sp2"); - self.grenadeoneentity.scale = .1; - self.grenadeoneentity.origin = '40 0 0'; - self.grenadeoneentity.angles = '0 0 0'; - self.grenadeoneentity.viewmodelforclient = self; - self.grenadeoneentity.flags = 0; - self.grenadeoneentity.think = CL_GrenadeOneEntity_Think; - self.grenadeoneentity.nextthink = time; + ownr.grenadeoneentity = spawn(); + ownr.grenadeoneentity.solid = SOLID_NOT; + ownr.grenadeoneentity.owner = ownr; + ownr.grenadeoneentity.grenadeoneentity = ownr.grenadeoneentity; + ownr.grenadeoneentity.think = TeamNexuiz_HUD_SignThink; + ownr.grenadeoneentity.nextthink = time + 1; + if (selection == NO_AMMO_WARNING) + setmodel(ownr.grenadeoneentity, "models/hud_nobul.sp2"); + else if (selection == HUD_PRIME_GREN) + { + setmodel(ownr.grenadeoneentity, "models/grentimer.sp2"); + ownr.grenadeoneentity.frame = 2; + ownr.grenadeoneentity.think = TeamNexuiz_HUD_GrenThink; + ownr.grenadeoneentity.nextthink = time + .4; + } + ownr.grenadeoneentity.scale = .1; + ownr.grenadeoneentity.alpha = 1; + ownr.grenadeoneentity.origin = '40 0 0'; + ownr.grenadeoneentity.angles = '0 0 0'; + ownr.grenadeoneentity.viewmodelforclient = ownr; + ownr.grenadeoneentity.flags = 0; }; \ No newline at end of file diff --git a/TeamNexuiz/game/gamec/tn_clientcommands.c b/TeamNexuiz/game/gamec/tn_clientcommands.c new file mode 100644 index 000000000..2eaf0933a --- /dev/null +++ b/TeamNexuiz/game/gamec/tn_clientcommands.c @@ -0,0 +1,598 @@ +// Team:Nexuiz Client Commands w/ Nexuiz 1.5 RCON/Vote system +.float adminstatus; +.float autoswitch; // need function for this!! +.float version; +.float ready; +// stahl's voting +float votecalled; +string votecalledvote; +float votecalledmaster; +entity votecaller; +float votefinished; +.float vote_master; +.float vote_next; +.float vote_vote; +void VoteThink(); +string VoteParse(); +float VoteAllowed(string vote); +void VoteReset(); +void VoteAccept(); +void VoteReject(); +void VoteTimeout(); +void VoteStop(entity stopper); +void VoteCount(); +void ReadyCount(); +// Parse team join, class etc. +void SV_ParseClientCommand (string s) +{ + local float index; + local float args; +// local float h; + local string c; + local string d; + local string f; + local string g; + local string i; + args = tokenize(s); + c = argv(0); + d = argv(1); + f = argv(2); + g = argv(3); + i = argv(4); + + if (c == "join") + { + return; + } + if (c == "changeclass") + { + stuffcmd(self, "set scmenu_directmenu ClassSelect; togglemenu\n"); + return; + } + if (c == "selectteam") + { + if (self.team_no > 0) + { + sprint(self, "You are already on a team!\n"); + return; + } + if (d == "auto" || d == "5") + { + TeamFortress_TeamPutPlayerInTeam(); + PutClientInServer (); + } + if (d == "blue" || d == "1") + { + TeamFortress_TeamSet (1); + PutClientInServer (); + } + if (d == "red" || d == "2") + { + TeamFortress_TeamSet (2); + PutClientInServer (); + } + if (d == "yellow" || d == "3") + { + TeamFortress_TeamSet (3); + PutClientInServer (); + } + if (d == "green" || d == "pink" || d == "4") // Morphed set it to Pink in the menus. I think + { // we should make it white instead. + TeamFortress_TeamSet (4); + PutClientInServer (); + } + return; + } + if (c == "selectclass") + { + if (self.team_no < 1) + { + sprint(self, "You must select a team to join first!\n"); + return; + } + if (TeamFortress_TeamIsCivilian (self.team_no)) + { + self.impulse = 1; + TeamFortress_ChangeClass (); + return; + } + if (self.playerclass > 0) // if a class is already chosen + { + self.tfstate = self.tfstate - (self.tfstate & 8); + local string cname; + if (d == ftos(TF_CLASS_SCOUT)) + { + cname = "scout"; + } + if (d == ftos(TF_CLASS_SOLDIER)) + { + cname = "soldier"; + } + if (d == ftos(TF_CLASS_MEDIC)) + { + cname = "medic"; + } + if (d == ftos(TF_CLASS_PYRO)) + { + cname = "pyro"; + } + if (d == ftos(TF_CLASS_ENGINEER)) + { + cname = "engineer"; + } + if (d == ftos(TF_CLASS_SPY)) + { + cname = "spy"; + } + if (d == ftos(TF_CLASS_RANDOM)) + { + self.tfstate = self.tfstate | 8; + sprint(self, "You will respawn as a random class.\n"); + } + if (cname != "") + { +// stuffcmd(self, "_cl_playermodel \"models/class/"); +// stuffcmd(self, cname); +// stuffcmd(self, "_mechanical.zym\"\n"); + if (cname == "engineer") + { + self.playermodel = strcat("models/class/",cname,"_other.zym"); + } + else + { + self.playermodel = strcat("models/class/",cname,"_mechanical.zym"); + } + if (self.is_dead == 1) // if player is dead, can change class + CheckForClassChange(); + } + } + else // if no class is chosen + { + if (d == ftos(TF_CLASS_SCOUT)) + { + self.impulse = TF_CLASS_SCOUT; + } + if (d == ftos(TF_CLASS_SOLDIER)) + { + self.impulse = TF_CLASS_SOLDIER; + } + if (d == ftos(TF_CLASS_MEDIC)) + { + self.impulse = TF_CLASS_MEDIC; + } + if (d == ftos(TF_CLASS_PYRO)) + { + self.impulse = TF_CLASS_PYRO; + } + if (d == ftos(TF_CLASS_ENGINEER)) + { + self.impulse = TF_CLASS_ENGINEER; + } + if (d == ftos(TF_CLASS_SPY)) + { + self.impulse = TF_CLASS_SPY; + } + if (d == ftos(TF_CLASS_RANDOM)) + { + self.impulse = TF_CLASS_RANDOM; + } + TeamFortress_ChangeClass(); + } + return; + } + else if (c == "check_val") + { + if (d == "r_bloom") + { + if (f == "1") + self.uses_bloom = 1; + else + self.uses_bloom = 0; + } + } + else if(argv(0) == "clogin") { + if(cvar("sv_clientcommands")) { + if(self.adminstatus < -5) { + sprint(self, "Too many unsuccessful tries.\n"); + } else if(argv(1) == cvar_string("sv_clientcommands_password")) { + self.adminstatus = 1; + sprint(self, "You now have remote admin status.\n"); + } else { + sprint(self, "Wrong password.\n"); + // use of -- produces compiler warning in the if() line??? + self.adminstatus = self.adminstatus - 1; + if(self.adminstatus == 0) + sprint(self, "You lost remote admin status.\n"); + } + } else { + sprint(self, "Clientside commands NOT allowed.\n"); + } + } else if(argv(0) == "ccmd") { + if(cvar("sv_clientcommands")) { + if(self.adminstatus > 0) { + local string command; + command = argv(1); + index = 2; + while(argv(index) != "") { + command = strcat(command, " ", argv(index)); + index++; + } + localcmd(command); + } else + sprint(self, "You don't have remote admin status.\n"); + } else { + sprint(self, "Clientside commands NOT allowed.\n"); + } + } else if(argv(0) == "vote") { + if(argv(1) == "help") { + local string vmasterdis; + if(!cvar("sv_vote_master")) { + vmasterdis = " ^1(disabled)"; + } + local string vcalldis; + if(!cvar("sv_vote_call")) { + vcalldis = " ^1(disabled)"; + } + sprint(self, "^7You can use voting with \"^2cmd vote help^7\" \"^2cmd vote status^7\" \"^2cmd vote call ^3COMMAND ARGUMENTS^7\" \"^2cmd vote stop^7\" \"^2cmd vote master^7\" \"^2cmd vote do ^3COMMAND ARGUMENTS^7\" \"^2cmd vote yes^7\" \"^2cmd vote no^7\".\n"); + sprint(self, "^7Or if your version is up to date you can use these aliases \"^2vhelp^7\" \"^2vstatus^7\" \"^2vcall ^3COMMAND ARGUMENTS^7\" \"^2vstop^7\" \"^2vmaster^7\" \"^2vdo ^3COMMAND ARGUMENTS^7\" \"^2vyes^7\" \"^2vno^7\".\n"); + sprint(self, "^7\"^2help^7\" shows this info.\n"); + sprint(self, "^7\"^2status^7\" shows if there is a vote called and who called it.\n"); + sprint(self, strcat("^7\"^2call^7\" is used to call a vote. See the list of allowed commands.", vcalldis, "^7\n")); + sprint(self, "^7\"^2stop^7\" can be used by the vote caller or an admin to stop a vote and maybe correct it.\n"); + sprint(self, strcat("^7\"^2master^7\" is used to call a vote to become a master.", vmasterdis, "^7\n")); + sprint(self, "^7\"^2do^7\" If you are a master you can execute a command without a vote. See the list of allowed commands.\n"); + sprint(self, "^7\"^2yes^7\" and \"^2no^7\" to make your vote.\n"); + sprint(self, "^7If more then 50% of the players vote yes the vote is accepted.\n"); + sprint(self, "^7If more then 50% of the players vote no the vote is rejected.\n"); + sprint(self, strcat("^7The vote will end after ", cvar_string("sv_vote_timeout"), "^7 seconds.\n")); + sprint(self, "^7You can call a vote for or execute these commands:\n"); + sprint(self, strcat("^3", cvar_string("sv_vote_commands"), "^7 and maybe further ^3arguments^7\n")); + } else if(argv(1) == "status") { + if(votecalled) { + sprint(self, strcat("^7Vote for \"^1", votecalledvote, "^7\" called by \"^7", votecaller.netname, "^7\".\n")); + } else { + sprint(self, "^1No vote called.\n"); + } + } else if(argv(1) == "call") { + if(cvar("sv_vote_call")) { + if(votecalled) { + sprint(self, "^1There is already a vote called.\n"); + } else { + local string vote; + vote = VoteParse(); + if(vote == "") { + sprint(self, "^1Your vote is empty. See help for more info.\n"); + } else if(time < self.vote_next) { + sprint(self, strcat("^1You have to wait ^2", ftos(self.vote_next - time), "^1 seconds before you can again call a vote.\n")); + } else if(VoteAllowed(strcat(argv(2)))) { // strcat seems to be necessary + votecalled = TRUE; + votecalledmaster = FALSE; + votecalledvote = strzone(vote); + votecaller = self; // remember who called the vote + votefinished = time + cvar("sv_vote_timeout"); + votecaller.vote_vote = 1; // of course you vote yes + votecaller.vote_next = time + cvar("sv_vote_wait"); + bprint(strcat("^3Vote for \"^1", votecalledvote, "^3\" called by \"^7", votecaller.netname, "^3\".\n")); + VoteCount(); // needed if you are the only one + } else { + sprint(self, "^1This vote is not ok. See help for more info.\n"); + } + } + } else { + sprint(self, "^1Vote calling is NOT allowed.\n"); + } + } else if(argv(1) == "stop") { + if(!votecalled) { + sprint(self, "^1No vote called.\n"); + } else if(self == votecaller + || self.adminstatus > 0) { // the votecaller and admins can stop a vote + VoteStop(self); + } else { + sprint(self, "^1You are not allowed to stop that Vote.\n"); + } + } else if(argv(1) == "master") { + if(cvar("sv_vote_master")) { + if(votecalled) { + sprint(self, "^1There is already a vote called.\n"); + } else { + votecalled = TRUE; + votecalledmaster = TRUE; + votecalledvote = strzone("^3master"); + votecaller = self; // remember who called the vote + votefinished = time + cvar("sv_vote_timeout"); + votecaller.vote_vote = 1; // of course you vote yes + votecaller.vote_next = time + cvar("sv_vote_wait"); + bprint(strcat("\"^3", votecaller.netname, "^3\" called a vote to become ^3master^3.\n")); + VoteCount(); // needed if you are the only one + } + } else { + sprint(self, "^1Vote to become master is NOT allowed.\n"); + } + } else if(argv(1) == "do") { + if(self.vote_master) { + local string dovote; + dovote = VoteParse(); + if(dovote == "") { + sprint(self, "^1Your command was empty. See help for more info.\n"); + } else if(VoteAllowed(strcat(argv(2)))) { // strcat seems to be necessary + bprint("\"^7", strcat(self.netname, "^2 used his ^3master^2 status to do \"^2", dovote, "^2\".\n")); + localcmd(dovote); + } else { + sprint(self, "^1This command is not ok. See help for more info.\n"); + } + } else { + sprint(self, "^1You are NOT a master.\n"); + } + } else if(argv(1) == "yes") { + if(!votecalled) { + sprint(self, "^1No vote called.\n"); + } else if(self.vote_vote == 0 + || cvar("sv_vote_change")) { + sprint(self, "^1You accepted the vote.\n"); + self.vote_vote = 1; + if(!cvar("sv_vote_singlecount")) { + VoteCount(); + } + } else { + sprint(self, "^1You have already voted.\n"); + } + } else if(argv(1) == "no") { + if(!votecalled) { + sprint(self, "^1No vote called.\n"); + } else if(self.vote_vote == 0 + || cvar("sv_vote_change")) { + sprint(self, "^1You rejected the vote.\n"); + self.vote_vote = -1; + if(!cvar("sv_vote_singlecount")) { + VoteCount(); + } + } else { + sprint(self, "^1You have already voted.\n"); + } + } else { + // ignore this? + sprint(self, "^1Unknown vote command.\n"); + } + } else if(argv(0) == "autoswitch") { + // be backwards compatible with older clients (enabled) + self.autoswitch = ("0" != argv(1)); + local string autoswitchmsg; + if (self.autoswitch) { + autoswitchmsg = "on"; + } else { + autoswitchmsg = "off"; + } + sprint(self, strcat("^1autoswitch turned ", autoswitchmsg, "\n")); + } else if(argv(0) == "clientversion") { + if (argv(1) == "$g_nexuizversion_major") { + //versionmsg = "^1client is too old to get versioninfo.\nUPDATE!!! (http://www.nexuiz.com)^8"; + // either that or someone wants to be funny + self.version = 1; + } else { + self.version = stof(argv(1)); + } + } else if(argv(0) == "spectate") { + if(cvar("g_lms")) + return; // don't allow spectating in lms, unless player runs out of lives + if(self.classname == "player" && cvar("sv_spectate") == 1) { + self.classname = "observer"; + PutClientInServer(); + } + } else if(argv(0) == "join") { + self.classname = "player"; + self.frags = 0; + // TODO: I have no idea whether this is needed or not + if(!cvar("g_lms")) { + bprint (strcat("^4", self.netname, "^4 is playing now\n")); + } + PutClientInServer(); + } else if(argv(0) == "ready") { + if(cvar("sv_ready_restart")) + { + self.ready = TRUE; + bprint(self.netname, "^2 is ready\n"); + ReadyCount(); + } + } + else + { + clientcommand(self, s); + } +}; + +void VoteThink() { + if(votefinished > 0 // a vote was called + && time > votefinished) // time is up + { + VoteCount(); + } +} + +string VoteParse() { + local float index; + index = 3; + local string vote; + vote = argv(2); + while(argv(index) != "") { + vote = strcat(vote, " ", argv(index)); + index++; + } + + // necessary for some of the string operations + vote = strzone(vote); + + // now we remove some things that could be misused + index = 0; + local float found; + found = FALSE; + local float votelength; + votelength = strlen(vote); + while(!found && index < votelength) + { + local string badchar; + badchar = substring(vote, index, 1); + if(badchar == ";" + || badchar == "\n") + { + found = TRUE; + } else { + index++; + } + } + return substring(vote, 0, index); +} + +float VoteAllowed(string votecommand) { + tokenize(cvar_string("sv_vote_commands")); + local float index; + index = 0; + while(argv(index) != "") { + local string allowed; + allowed = argv(index); + if(votecommand == allowed) { + return TRUE; + } + index++; + } + return FALSE; +} + +void VoteReset() { + local string searchclass; + searchclass = "player"; + + while (TRUE) + { + local entity player; + player = find(player, classname, searchclass); + while(player) + { + player.vote_vote = 0; + player = find(player, classname, searchclass); + } + + if("player" == searchclass) { + searchclass = "observer"; + } else if("observer" == searchclass) { + searchclass = "spectator"; + } else { + break; + } + } + + votecalled = FALSE; + votecalledmaster = FALSE; + votefinished = 0; +} + +void VoteAccept() { + bprint(strcat("^2The vote for \"^1", votecalledvote, "^2\" from \"^7", votecaller.netname, "^2\" was accepted.\n")); + if(votecalledmaster) + { + votecaller.vote_master = 1; + } else { + localcmd(votecalledvote); + } + votecaller.vote_next = 0; // people like your votes, no wait for next vote + VoteReset(); +} + +void VoteReject() { + bprint(strcat("^2The vote for \"^1", votecalledvote, "^2\" from \"^7", votecaller.netname, "^2\" was rejected.\n")); + VoteReset(); +} + +void VoteTimeout() { + bprint(strcat("^5The vote for \"^1", votecalledvote, "^5\" from \"^7", votecaller.netname, "^5\" did timeout.\n")); + VoteReset(); +} + +void VoteStop(entity stopper) { + bprint(strcat("^5The vote for \"^1", votecalledvote, "^5\" from \"^7", votecaller.netname, "^5\" was stopped by \"^5", stopper.netname, "^5\".\n")); + if(stopper == votecaller) { + // no wait for next vote so you can correct your vote + votecaller.vote_next = 0; + } + VoteReset(); +} + +void VoteCount() { + local float playercount; + playercount = 0; + local float yescount; + yescount = 0; + local float nocount; + nocount = 0; + local string searchclass; + searchclass = "player"; + + while (TRUE) + { + local entity player; + player = find(player, classname, searchclass); + + while(player) + { + if(clienttype(player) != CLIENTTYPE_BOT) { + if(player.vote_vote < 0) { + nocount++; + } else if(player.vote_vote > 0) { + yescount++; + } + playercount++; + } + player = find(player, classname, searchclass); + } + + if("player" == searchclass) { + searchclass = "observer"; + } else if("observer" == searchclass) { + searchclass = "specator"; + } else { + break; + } + } + + if((playercount == 1) && votecalledmaster) { + // if only one player is on the server becoming vote + // master is not allowed. This could be used for + // trolling or worse. 'self' is the user who has + // called the vote because this function is called + // by SV_ParseClientCommand. Maybe all voting should + // be disabled for a single player? + sprint(self, "^1You are the only player on this server so you can not become vote master.\n"); + votecaller.vote_next = 0; + VoteReset(); + } else if((playercount / 2) < yescount) { // vote accepted + VoteAccept(); + } else if((playercount / 2) < nocount) { // vote rejected + VoteReject(); + } else if(time > votefinished) { // vote timedout + VoteTimeout(); + } // else still running +} + + +void ReadyCount() +{ + local entity e; + local float r, p; + + e = find(world, classname, "player"); + + while(e) + { + if(clienttype(e) == CLIENTTYPE_REAL) + { + p += 1; + if(e.ready) r += 1; + } + e = find(e, classname, "player"); + } + + if(p && r == p) + { + bprint("^1Server is restarting...\n"); + localcmd("restart\n"); + } +} diff --git a/TeamNexuiz/game/progs.src b/TeamNexuiz/game/progs.src index e69887959..23ee12890 100644 --- a/TeamNexuiz/game/progs.src +++ b/TeamNexuiz/game/progs.src @@ -84,6 +84,7 @@ gamec/domination.c gamec/mauvebot.c +gamec/tn_clientcommands.c // TN Voting/Rcon/Team/Class-select etc. gamec/tf_ball.c // MegaTF/TN Ball&Goal gamec/tf_w_pistol.c // (Every Class?) Pistol -- 2.39.2