mirror of
https://git.code.sf.net/p/quake/game-source
synced 2024-11-28 22:52:26 +00:00
171 lines
4.5 KiB
C++
171 lines
4.5 KiB
C++
/*
|
|
ctfgame.qc
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
|
|
$Id$
|
|
*/
|
|
|
|
float VOTEEXIT_TIME_LIMIT = 60; // 60 seconds after first vote
|
|
float voteexit_time;
|
|
entity vote_leader; // current leader
|
|
entity lastvotespawn;
|
|
|
|
void (vector org) spawn_tfog;
|
|
void (vector org, entity death_owner) spawn_tdeath;
|
|
void () InitTrigger;
|
|
|
|
/*QUAKED info_vote_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
|
|
This is the destination marker for a voteexit. It should have a "targetname"
|
|
field with the same value as a voteexit's "target" field.
|
|
*/
|
|
void ()
|
|
info_vote_destination =
|
|
{
|
|
// this does nothing, just serves as a target spot
|
|
self.mangle = self.angles;
|
|
self.angles = '0 0 0';
|
|
self.model = "";
|
|
self.origin = self.origin + '0 0 27';
|
|
if (!self.targetname)
|
|
objerror ("no targetname");
|
|
};
|
|
|
|
void ()
|
|
voteexit_teleport =
|
|
{
|
|
local entity t;
|
|
local vector org;
|
|
|
|
// put a tfog where the player was
|
|
spawn_tfog (other.origin);
|
|
|
|
// if we aren't in custom mode, just find a deathmatch target
|
|
// find the destination
|
|
if (!self.target) {
|
|
lastvotespawn = find (lastvotespawn, classname,
|
|
"info_player_deathmatch");
|
|
if (lastvotespawn == world)
|
|
lastvotespawn = find (lastvotespawn, classname,
|
|
"info_player_deathmatch");
|
|
t = lastvotespawn;
|
|
} else
|
|
t = find (world, targetname, self.target);
|
|
|
|
if (!t)
|
|
objerror ("couldn't find target");
|
|
|
|
// spawn a tfog flash in front of the destination
|
|
makevectors (t.mangle);
|
|
org = t.origin + 32 * v_forward;
|
|
|
|
spawn_tfog (org);
|
|
spawn_tdeath(t.origin, other);
|
|
|
|
// move the player and lock him down for a little while
|
|
if (!other.health) {
|
|
other.origin = t.origin;
|
|
other.velocity = v_forward * (other.velocity_x + other.velocity_y);
|
|
return;
|
|
}
|
|
setorigin (other, t.origin);
|
|
other.angles = t.mangle;
|
|
|
|
other.fixangle = 1; // turn this way immediately
|
|
other.teleport_time = time + 0.7;
|
|
|
|
if (other.flags & FL_ONGROUND)
|
|
other.flags &= ~FL_ONGROUND;
|
|
other.velocity = v_forward * 300;
|
|
};
|
|
|
|
void ()
|
|
voteexit_touch =
|
|
{
|
|
local entity t;
|
|
|
|
if (other.classname != "player")
|
|
return;
|
|
|
|
// only teleport living creatures
|
|
if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
|
|
return;
|
|
if (other.voted) {
|
|
if (other.voted < time)
|
|
TeamPlayerUpdate (other, "You have already voted.");
|
|
other.voted = time + 1;
|
|
voteexit_teleport ();
|
|
return;
|
|
}
|
|
|
|
// non-zero for vote, time is when to display a 'you voted' msg
|
|
other.voted = time + 1;
|
|
|
|
SUB_UseTargets ();
|
|
|
|
bprint (PRINT_HIGH, other.netname);
|
|
bprint (PRINT_HIGH, " has voted for ");
|
|
bprint (PRINT_HIGH, self.message);
|
|
bprint (PRINT_HIGH, "\n");
|
|
|
|
// ok, the player has voted for this exit
|
|
self.cnt++;
|
|
|
|
// find new leader
|
|
// we're on the start map, something special is happening
|
|
vote_leader = world;
|
|
t = find(world, classname, "trigger_voteexit");
|
|
while (t != world) {
|
|
if ((t.cnt > vote_leader.cnt) && (t != self))
|
|
vote_leader = t;
|
|
t = find(t, classname, "trigger_voteexit");
|
|
}
|
|
// if we are higher than the current leader, then we are the new
|
|
// leader, if we are same, half chance
|
|
if (self.cnt > vote_leader.cnt)
|
|
vote_leader = self;
|
|
else if ((self.cnt == vote_leader.cnt) && (random() > 0.5))
|
|
vote_leader = self;
|
|
|
|
// we check here about exit time
|
|
if (vote_leader != world && voteexit_time == 0)
|
|
voteexit_time = time + VOTEEXIT_TIME_LIMIT;
|
|
|
|
// notify everyone about the change
|
|
TeamCaptureResetUpdate ();
|
|
|
|
voteexit_teleport ();
|
|
};
|
|
|
|
/*QUAKED trigger_voteexit (.5 .5 .5) ?
|
|
A merge of trigger_changelevel and trigger_teleport. A player touching
|
|
this this teleported just like a trigger_teleport, except this triggers
|
|
.cnt field gets incremented. This allows players to vote for their exit.
|
|
See status.qc for the display and total of the voting.
|
|
Any object touching this will be transported to the corresponding
|
|
info_vote_destination entity. You must set the "target" field, and
|
|
create an object with a "targetname" field that matches.
|
|
*/
|
|
void ()
|
|
trigger_voteexit =
|
|
{
|
|
InitTrigger ();
|
|
self.touch = voteexit_touch;
|
|
self.cnt = 0;
|
|
};
|