forked from id/quake-qw-qc
Compare commits
No commits in common. "master" and "master" have entirely different histories.
6 changed files with 17 additions and 459 deletions
16
client.qc
16
client.qc
|
@ -160,7 +160,21 @@ entity() FindIntermission =
|
||||||
|
|
||||||
void() GotoNextMap =
|
void() GotoNextMap =
|
||||||
{
|
{
|
||||||
localcmd("nextmap\n");
|
local string newmap;
|
||||||
|
|
||||||
|
//ZOID: 12-13-96, samelevel is overloaded, only 1 works for same level
|
||||||
|
|
||||||
|
if (cvar("samelevel") == 1) // if samelevel is set, stay on same level
|
||||||
|
changelevel (mapname);
|
||||||
|
else {
|
||||||
|
// configurable map lists, see if the current map exists as a
|
||||||
|
// serverinfo/localinfo var
|
||||||
|
newmap = infokey(world, mapname);
|
||||||
|
if (newmap != "")
|
||||||
|
changelevel (newmap);
|
||||||
|
else
|
||||||
|
changelevel (nextmap);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
75
mapcycle.qc
75
mapcycle.qc
|
@ -1,75 +0,0 @@
|
||||||
/* public domain, do whatever you please. */
|
|
||||||
typedef float filestream;
|
|
||||||
|
|
||||||
/* builtins used */
|
|
||||||
filestream(string filename, float mode) fopen = #110;
|
|
||||||
void(filestream fhandle) fclose = #111;
|
|
||||||
string(filestream fhandle) fgets = #112;
|
|
||||||
string(string, optional string, optional string, optional string, optional string, optional string, optional string, optional string) strcat = #115;
|
|
||||||
string(string filename, optional enumflags:float{WP_REFERENCEPACKAGE,WP_FULLPACKAGEPATH} flags) whichpack = #503;
|
|
||||||
void(string text,...) print = #339;
|
|
||||||
void(string cmd) readcmd = #0:readcmd;
|
|
||||||
string(string fmt, ...) sprintf = #627;
|
|
||||||
string(string cvarname) cvar_string = #448;
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
const float FILE_READ = 0;
|
|
||||||
|
|
||||||
void
|
|
||||||
Mapcycle_Load(string filename)
|
|
||||||
{
|
|
||||||
filestream fs_mapcycle;
|
|
||||||
string temp;
|
|
||||||
float mapcount = 0;
|
|
||||||
string lastmap = "";
|
|
||||||
float map_next = 0;
|
|
||||||
|
|
||||||
fs_mapcycle = fopen(filename, FILE_READ);
|
|
||||||
|
|
||||||
if (fs_mapcycle < 0) {
|
|
||||||
print(strcat("^1could not load ", filename, "\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the lines in, see if the map exists and define an enumerated alias */
|
|
||||||
while ((temp = fgets(fs_mapcycle))) {
|
|
||||||
if not (whichpack(strcat("maps/", temp, ".bsp")))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
readcmd(sprintf("alias m%d \"map %s;alias nextmap m%d\"\n", mapcount, temp, mapcount + 1));
|
|
||||||
|
|
||||||
if (mapname == lastmap)
|
|
||||||
map_next = mapcount;
|
|
||||||
|
|
||||||
lastmap = temp;
|
|
||||||
mapcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fs_mapcycle);
|
|
||||||
|
|
||||||
if (mapcount <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* override the last map so that it goes back to m0 */
|
|
||||||
readcmd(sprintf("alias m%d \"map %s;alias nextmap m0\"\n", mapcount - 1, lastmap));
|
|
||||||
|
|
||||||
/* the current map in the list will decide the nextmap */
|
|
||||||
readcmd(sprintf("alias nextmap m%d\n", map_next));
|
|
||||||
|
|
||||||
print(sprintf("mapcycle initialized with %d entries.\n", mapcount));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Mapcycle_Init(void)
|
|
||||||
{
|
|
||||||
string cycleFile = autocvar(mapcycle_file, "mapcycle.txt");
|
|
||||||
|
|
||||||
/* in case some server admin wants a map to continously loop */
|
|
||||||
if not (cycleFile) {
|
|
||||||
print("mapcycle disabled via cvar. skipping\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("--------- Initializing MapCycle ----------\n");
|
|
||||||
Mapcycle_Load(cycleFile);
|
|
||||||
}
|
|
|
@ -1,11 +1,10 @@
|
||||||
../qwprogs.dat
|
./qwprogs.dat
|
||||||
|
|
||||||
defs.qc
|
defs.qc
|
||||||
subs.qc
|
subs.qc
|
||||||
combat.qc
|
combat.qc
|
||||||
items.qc
|
items.qc
|
||||||
weapons.qc
|
weapons.qc
|
||||||
mapcycle.qc
|
|
||||||
world.qc
|
world.qc
|
||||||
client.qc
|
client.qc
|
||||||
spectate.qc
|
spectate.qc
|
||||||
|
@ -15,5 +14,5 @@ buttons.qc
|
||||||
triggers.qc
|
triggers.qc
|
||||||
plats.qc
|
plats.qc
|
||||||
misc.qc
|
misc.qc
|
||||||
|
|
||||||
server.qc
|
server.qc
|
||||||
voting.qc
|
|
||||||
|
|
49
triggers.qc
49
triggers.qc
|
@ -601,57 +601,8 @@ void() trigger_hurt =
|
||||||
|
|
||||||
float PUSH_ONCE = 1;
|
float PUSH_ONCE = 1;
|
||||||
|
|
||||||
float(float value) sqrt = #62;
|
|
||||||
|
|
||||||
vector
|
|
||||||
trigger_push_velfortarget(vector vecFrom, vector vecTo, float flGravMod)
|
|
||||||
{
|
|
||||||
float flHeight, flGravity, flTime, flDistance, flDir;
|
|
||||||
vector vecJump = [0,0,0];
|
|
||||||
|
|
||||||
if (flGravMod <= 0.0)
|
|
||||||
flGravMod = 1.0f;
|
|
||||||
|
|
||||||
flGravity = cvar("sv_gravity") * flGravMod;
|
|
||||||
flHeight = vecTo[2] - vecFrom[2];
|
|
||||||
|
|
||||||
/* this may not be a much verticality to this jump, use distance instead */
|
|
||||||
if (flHeight <= 0) {
|
|
||||||
flHeight = vlen(vecTo - vecFrom);
|
|
||||||
flTime = flHeight / flGravity;
|
|
||||||
} else {
|
|
||||||
flTime = sqrt(flHeight / (flGravity * 0.5f));
|
|
||||||
if (flTime <= 0) {
|
|
||||||
return [0,0,0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vecJump = vecTo - vecFrom;
|
|
||||||
vecJump[2] = 0;
|
|
||||||
flDistance = vlen(normalize(vecJump));
|
|
||||||
|
|
||||||
flDir = flDistance / flTime;
|
|
||||||
vecJump *= flDir;
|
|
||||||
vecJump[2] = flTime * flGravity;
|
|
||||||
|
|
||||||
return vecJump;
|
|
||||||
}
|
|
||||||
|
|
||||||
void() trigger_push_touch =
|
void() trigger_push_touch =
|
||||||
{
|
{
|
||||||
/* if our trigger_push has a target, bah */
|
|
||||||
if (self.target) {
|
|
||||||
entity targetPos = find(world, ::targetname, self.target);
|
|
||||||
vector pushCenter = ( self.absmin + ( 0.5 * ( self.absmax - self.absmin ) ) );
|
|
||||||
|
|
||||||
if (targetPos) {
|
|
||||||
self.movedir = targetPos.origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
other.velocity = trigger_push_velfortarget(pushCenter, self.movedir, 1.0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.classname == "grenade")
|
if (other.classname == "grenade")
|
||||||
other.velocity = self.speed * self.movedir * 10;
|
other.velocity = self.speed * self.movedir * 10;
|
||||||
else if (other.health > 0)
|
else if (other.health > 0)
|
||||||
|
|
327
voting.qc
327
voting.qc
|
@ -1,327 +0,0 @@
|
||||||
/* In order to incorporate this file into your mod, you have to do two things:
|
|
||||||
|
|
||||||
1. Include this file in your progs.src
|
|
||||||
2. Call Vote_Init(); inside worldspawn.
|
|
||||||
|
|
||||||
You need fteqcc and fteqw-sv for this to work.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* builtins required */
|
|
||||||
float(string) tokenize = #441;
|
|
||||||
string(float) argv = #442;
|
|
||||||
void(entity e, string s) clientcommand = #440;
|
|
||||||
void(entity player, string key, string value) forceinfokey = #213;
|
|
||||||
string(string key) serverkey = #354;
|
|
||||||
float(string key, optional float assumevalue) serverkeyfloat = #0:serverkeyfloat;
|
|
||||||
|
|
||||||
void ChatMessage_Parse( entity, string );
|
|
||||||
string Util_TimeToString(float fTime);
|
|
||||||
void Vote_Cmd_VoteYes(void);
|
|
||||||
void Vote_Cmd_VoteNo(void);
|
|
||||||
void Vote_Cmd_CallVote(string);
|
|
||||||
void Vote_Help(entity);
|
|
||||||
|
|
||||||
var string g_strVoteCmd;
|
|
||||||
var float g_flVoteTime;
|
|
||||||
var float g_iVoteState;
|
|
||||||
var float autocvar_mp_allowvote = 1;
|
|
||||||
|
|
||||||
.float voted;
|
|
||||||
entity voteHandler;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
VOTE_INACTIVE,
|
|
||||||
VOTE_INPROGRESS,
|
|
||||||
VOTE_PASSED
|
|
||||||
};
|
|
||||||
|
|
||||||
/* callback from fteqw-sv */
|
|
||||||
void
|
|
||||||
SV_ParseClientCommand(string cmd)
|
|
||||||
{
|
|
||||||
float argc;
|
|
||||||
|
|
||||||
argc = tokenize(cmd);
|
|
||||||
|
|
||||||
switch (argv(0)) {
|
|
||||||
case "say":
|
|
||||||
clientcommand(self, cmd);
|
|
||||||
ChatMessage_Parse(self, argv(1));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
clientcommand(self, cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ChatMessage_Parse(entity sayingEnt, string commandString)
|
|
||||||
{
|
|
||||||
float isMap = 0;
|
|
||||||
if (whichpack(strcat("maps/", commandString, ".bsp"))) {
|
|
||||||
isMap = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
float args = tokenize(commandString);
|
|
||||||
|
|
||||||
switch (argv(0)) {
|
|
||||||
case "yes":
|
|
||||||
self = sayingEnt;
|
|
||||||
Vote_Cmd_VoteYes();
|
|
||||||
break;
|
|
||||||
case "no":
|
|
||||||
self = sayingEnt;
|
|
||||||
Vote_Cmd_VoteNo();
|
|
||||||
break;
|
|
||||||
case "rtv":
|
|
||||||
bprint(PRINT_CHAT, sprintf("rock the vote requested by %s\n", sayingEnt.netname));
|
|
||||||
break;
|
|
||||||
case "timeleft":
|
|
||||||
string msg;
|
|
||||||
string timestring;
|
|
||||||
float timeleft;
|
|
||||||
timeleft = cvar("timelimit") - (time / 60);
|
|
||||||
timestring = Util_TimeToString(timeleft);
|
|
||||||
msg = sprintf("we have %s minutes remaining\n", timestring);
|
|
||||||
sprint(sayingEnt, PRINT_CHAT, msg);
|
|
||||||
break;
|
|
||||||
case "callvote":
|
|
||||||
Vote_Cmd_CallVote(commandString);
|
|
||||||
break;
|
|
||||||
case "votehelp":
|
|
||||||
Vote_Help(sayingEnt);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (isMap) {
|
|
||||||
bprint(PRINT_CHAT, sprintf("%s was nominated by %s\n", commandString, sayingEnt.netname));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
|
||||||
Util_TimeToString(float fTime)
|
|
||||||
{
|
|
||||||
fTime = rint(fTime);
|
|
||||||
|
|
||||||
switch (fTime) {
|
|
||||||
case 0: return "less than one";
|
|
||||||
case 1: return "one";
|
|
||||||
case 2: return "two";
|
|
||||||
case 3: return "three";
|
|
||||||
case 4: return "four";
|
|
||||||
case 5: return "five";
|
|
||||||
case 6: return "six";
|
|
||||||
case 7: return "seven";
|
|
||||||
case 8: return "eight";
|
|
||||||
case 9: return "nine";
|
|
||||||
case 10: return "ten";
|
|
||||||
default: return "over ten";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_End(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
localcmd(sprintf("%s\n", g_strVoteCmd));
|
|
||||||
g_flVoteTime = 0.0f;
|
|
||||||
g_iVoteState = VOTE_INACTIVE;
|
|
||||||
remove(voteHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Reset(void)
|
|
||||||
{
|
|
||||||
forceinfokey(world, "votes_y", "0");
|
|
||||||
forceinfokey(world, "votes_n", "0");
|
|
||||||
forceinfokey(world, "vote_cmd", "");
|
|
||||||
|
|
||||||
for (entity e = world; (e = find(e, ::classname, "player"));) {
|
|
||||||
e.voted = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Passed(void)
|
|
||||||
{
|
|
||||||
g_flVoteTime = time + 5.0f;
|
|
||||||
g_iVoteState = VOTE_PASSED;
|
|
||||||
bprint(PRINT_CHAT, "Vote passed.\n");
|
|
||||||
g_strVoteCmd = serverkey("vote_cmd");
|
|
||||||
Vote_Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Failed(void)
|
|
||||||
{
|
|
||||||
g_flVoteTime = 0.0;
|
|
||||||
g_iVoteState = VOTE_INACTIVE;
|
|
||||||
bprint(PRINT_CHAT, "Vote failed.\n");
|
|
||||||
Vote_Reset();
|
|
||||||
remove(voteHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Frame(void)
|
|
||||||
{
|
|
||||||
if (time >= g_flVoteTime) {
|
|
||||||
if (g_iVoteState == VOTE_INPROGRESS) {
|
|
||||||
if (serverkeyfloat("votes_y") > serverkeyfloat("votes_n")) {
|
|
||||||
Vote_Passed();
|
|
||||||
} else {
|
|
||||||
Vote_Failed();
|
|
||||||
}
|
|
||||||
} else if (g_iVoteState == VOTE_PASSED) {
|
|
||||||
Vote_End();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.nextthink = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Cmd_VoteYes(void)
|
|
||||||
{
|
|
||||||
/* No vote is in progress */
|
|
||||||
if (g_iVoteState != VOTE_INPROGRESS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.classname != "player") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.voted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinfokey(world, "votes_y", ftos(serverkeyfloat("votes_y")+1));
|
|
||||||
self.voted = 1;
|
|
||||||
|
|
||||||
/* HACK: Is there a better way to do this? */
|
|
||||||
float playernums = 0;
|
|
||||||
for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) {
|
|
||||||
playernums++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need at least half the players agreeing. */
|
|
||||||
if (serverkeyfloat("votes_y") > rint(playernums / 2)) {
|
|
||||||
Vote_Passed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) {
|
|
||||||
g_flVoteTime = time + 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Cmd_VoteNo(void)
|
|
||||||
{
|
|
||||||
/* No vote is in progress */
|
|
||||||
if (g_iVoteState != VOTE_INPROGRESS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.classname != "player") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.voted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinfokey(world, "votes_n", ftos(serverkeyfloat("votes_n")+1));
|
|
||||||
self.voted = 1;
|
|
||||||
|
|
||||||
/* HACK: Is there a better way to do this? */
|
|
||||||
float playernums = 0;
|
|
||||||
for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) {
|
|
||||||
playernums++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need at least half the players disagreeing. */
|
|
||||||
if (serverkeyfloat("votes_n") > rint(playernums / 2)) {
|
|
||||||
Vote_Failed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) {
|
|
||||||
g_flVoteTime = time + 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_InitiateVote(string votemsg)
|
|
||||||
{
|
|
||||||
/* A vote is in progress */
|
|
||||||
if (g_iVoteState != VOTE_INACTIVE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.classname != "player") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vote_Reset();
|
|
||||||
|
|
||||||
forceinfokey(world, "vote_cmd", votemsg);
|
|
||||||
g_flVoteTime = time + 30.0f;
|
|
||||||
g_iVoteState = VOTE_INPROGRESS;
|
|
||||||
|
|
||||||
bprint(PRINT_CHAT, sprintf("vote: %S, type yes/no in chat!\n", votemsg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Cmd_CallVote(string text)
|
|
||||||
{
|
|
||||||
if (autocvar_mp_allowvote == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No vote is in progress */
|
|
||||||
if (g_iVoteState != VOTE_INACTIVE) {
|
|
||||||
sprint(self, PRINT_CHAT, "A vote is already in progress.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
voteHandler = spawn();
|
|
||||||
voteHandler.think = Vote_Frame;
|
|
||||||
voteHandler.nextthink = time;
|
|
||||||
|
|
||||||
tokenize(text);
|
|
||||||
switch (argv(1)) {
|
|
||||||
case "map":
|
|
||||||
if not (whichpack(sprintf("maps/%s.bsp", argv(2)))) {
|
|
||||||
sprint(self, PRINT_CHAT, sprintf("Map '%s' not available on server.\n", argv(2)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "kick":
|
|
||||||
case "slowmo":
|
|
||||||
case "timelimit":
|
|
||||||
case "fraglimit":
|
|
||||||
case "map_restart":
|
|
||||||
case "nextmap":
|
|
||||||
Vote_InitiateVote(sprintf("%s %s", argv(1), argv(2)));
|
|
||||||
Vote_Cmd_VoteYes();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sprint(self, PRINT_CHAT, sprintf("Cannot callvote for '%s'.\n", argv(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Init(void)
|
|
||||||
{
|
|
||||||
Vote_Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vote_Help(entity targetPlayer)
|
|
||||||
{
|
|
||||||
centerprint(targetPlayer, "Voting is easy:\nsay: callvote map dm3\n\nplayers say 'yes' or 'no'\nto decide the outcome!\n\ncommands include:\nmap, kick, fraglimit, timelimit");
|
|
||||||
}
|
|
4
world.qc
4
world.qc
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void() InitBodyQue;
|
void() InitBodyQue;
|
||||||
void() Vote_Init;
|
|
||||||
|
|
||||||
|
|
||||||
void() main =
|
void() main =
|
||||||
|
@ -199,7 +198,6 @@ World Types:
|
||||||
void() worldspawn =
|
void() worldspawn =
|
||||||
{
|
{
|
||||||
lastspawn = world;
|
lastspawn = world;
|
||||||
Mapcycle_Init();
|
|
||||||
InitBodyQue ();
|
InitBodyQue ();
|
||||||
|
|
||||||
// custom map attributes
|
// custom map attributes
|
||||||
|
@ -371,8 +369,6 @@ void() worldspawn =
|
||||||
|
|
||||||
// 63 testing
|
// 63 testing
|
||||||
lightstyle(63, "a");
|
lightstyle(63, "a");
|
||||||
|
|
||||||
Vote_Init();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void() StartFrame =
|
void() StartFrame =
|
||||||
|
|
Loading…
Reference in a new issue