home *** CD-ROM | disk | FTP | other *** search
- /* teamplay.qc
-
- From
- The Comlete Enhanced Teamplay
-
- John Spickes -- jspickes@eng.umd.edu
-
- $Id: teamplay.qc 1.17 1996/08/17 16:52:45 jspickes Exp $
-
- $Log: teamplay.qc $
- Revision 1.17 1996/08/17 16:52:45 jspickes
- Fixed a problem with displaying the current team settings that could cause
- the wrong output when teamplay was negative. Also added code to indicate
- when ID's silly teamplay code is being used.
-
- Revision 1.16 1996/08/17 00:41:52 jspickes
- Turned off strict coop by default.
- Fixed a bug that could have caused strange behavior if TEAM_COLOR* was
- set to -2.
-
- Revision 1.15 1996/08/17 00:34:17 jspickes
- Added instructions on drop-item use in current settings output.
- Fixed a problem that would allow you to drop lots of backpacks with
- nothing in them.
-
- */
-
- /** Defs **/
-
- /** MODIFIABLE CONSTANTS **/
-
- float TEAM_DEFAULT_PENALTY = 1; // Default frag penalty
- float TEAM_STRICT_COOP = 0; // Strict Coop
-
- // Allowed team colors
- // -1 indicates no color
-
- float TEAM_COLOR1 = 4;
- float TEAM_COLOR2 = 13;
- float TEAM_COLOR3 = -1;
- float TEAM_COLOR4 = -1;
-
- /** End of MODIFIABLE CONSTANTS **/
-
- // Globals
-
- // Teamplay bitfield entries
-
- float TEAM_HEALTH_PROTECT = 1; // No health damage from friendly fire
- float TEAM_ARMOR_PROTECT = 2; // No armor damage from friendly fire
- float TEAM_ATTACKER_DAMAGE = 4; // Attacker takes damage from hitting teammates
- float TEAM_FRAG_PENALTY = 8; // One frag penalty for killing teammate
- float TEAM_DEATH_PENALTY = 16; // Die when you kill a teammate.
- float TEAM_LOCK_COLORS = 32; // Allow only team colors
- float TEAM_STATIC_TEAMS = 64; // Don't allow players to switch teams
- float TEAM_DROP_ITEMS = 128; // Allow players to drop packs and
- // weapons.
-
- // Prototypes
- float() W_BestWeapon;
- void() W_SetCurrentAmmo;
- void() bound_other_ammo;
- void(float o, float n) Deathmatch_Weapon;
- void() BackpackTouch;
-
- /*
- ================
- TeamPrintSettings
-
- Print out current teamplay options
- ================
- */
-
- void() TeamPrintSettings =
- {
- local string s;
-
- sprint(self,"The following Teamplay options are set:\n");
-
- if(teamplay < 0)
- {
- sprint(self, "Frag penalty manually set to ");
- s = ftos(teamplay);
- sprint(self, s);
- sprint(self, "\n");
- return;
- }
-
- if(!teamplay)
- {
- sprint(self, "None\n");
- return;
- }
-
- if(1 == teamplay)
- {
- sprint(self, "ID's original teamplay 1\n");
- return;
- }
-
- if(teamplay & TEAM_HEALTH_PROTECT)
- sprint(self, "Health-Protect ");
-
- if(teamplay & TEAM_ARMOR_PROTECT)
- sprint(self, "Armor-Protect ");
-
- if(teamplay & TEAM_ATTACKER_DAMAGE)
- sprint(self, "Mirror-Damage ");
-
- if(teamplay & TEAM_FRAG_PENALTY)
- sprint(self, "Frag-Penalty ");
-
- if(teamplay & TEAM_DEATH_PENALTY)
- sprint(self, "Death-Penalty ");
-
- if(teamplay & TEAM_LOCK_COLORS)
- sprint(self, "Lock-Colors ");
-
- if(teamplay & TEAM_STATIC_TEAMS)
- sprint(self, "Static-Teams ");
-
- if(teamplay & TEAM_DROP_ITEMS)
- sprint(self, "Drop-Items (Backpack Impulse 20, Weapon Impulse 21)");
-
- sprint(self, "\n");
- };
-
- /*
- ================
- TeamArmorDam
-
- Return TRUE if the target's armor can take damage from this attacker.
- ================
- */
-
- float(entity targ, entity inflictor, entity attacker, float damage) TeamArmorDam =
- {
- if( teamplay < 0 )
- return TRUE;
- if( (teamplay & TEAM_ARMOR_PROTECT) && (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
- {
- // Armor is protected
- return FALSE;
- }
- return TRUE;
- };
-
- /*
- ================
- TeamHealthDam
-
- Return TRUE if the target can take health damage from this attacker.
- ================
- */
-
- float(entity targ, entity inflictor, entity attacker, float damage) TeamHealthDam =
- {
- if( teamplay < 0 )
- {
- return TRUE;
- }
- if( (attacker.team == targ.team) && (attacker != targ) && (targ.team > 0) )
- {
- // Attacker and target are on the same team.
- if( teamplay & TEAM_ATTACKER_DAMAGE )
- {
- // Damage applied to teammate.
- T_Damage(attacker, inflictor, attacker, damage);
- }
- if( teamplay & TEAM_HEALTH_PROTECT )
- {
- // Health is protected
- return FALSE;
- }
- }
- return TRUE;
- };
-
- /*
- ================
- TeamPFrags
-
- Return the number of frags we should penalize attacker for killing targ.
- ================
- */
-
- float(entity targ, entity attacker) TeamPFrags =
- {
- if( teamplay < 0 )
- return (-1 * teamplay);
- if( (targ.team > 0) && (targ != attacker) && (targ.team == attacker.team) )
- {
- // targ and attacker are on the same team
- if( teamplay < 0 )
- {
- // teamplay indicates frag penalty
- return ( -1 * teamplay );
- }
- if( teamplay & TEAM_FRAG_PENALTY )
- {
- // default penalty
- return TEAM_DEFAULT_PENALTY;
- }
- }
- // No frag penalty
- return 0;
- };
-
- /*
- ================
- TeamFragPenalty
-
- If attacker should be penalized for killing targ, penalize attacker
- and return TRUE.
- ================
- */
-
- float(entity targ, entity attacker) TeamFragPenalty =
- {
- local float f;
-
- f = TeamPFrags(targ, attacker);
-
- if( f )
- {
- // We should penalize some frags.
- attacker.frags = attacker.frags - f;
- return TRUE;
- }
- // No penalty
- return FALSE;
- };
-
- /*
- =================
- TeamDeathPenalty
-
- If attacker should be killed for killing targ, kill attacker and
- add a frag to offset the one attacker will lose for killing himself.
- */
-
- void(entity targ, entity attacker) TeamDeathPenalty =
- {
- //Don't kill anyone if teamplay is negative.
- if ( teamplay < 0 )
- return;
-
- if ( (teamplay & TEAM_DEATH_PENALTY) && (targ.team > 0) && (attacker != targ) && (attacker.team == targ.team) )
- {
- //We should kill the attacker.
- T_Damage(attacker,attacker,attacker,1000);
- //Add a frag to offset the self-kill penalty.
- attacker.frags = attacker.frags + 1;
- }
- };
-
- /*
- ==================
- TeamColorIsLegal
-
- Return TRUE if the indicated color is legal
- ==================
- */
- float(float color) TeamColorIsLegal =
- {
- // All colors are legal if teamplay is negative.
- if( teamplay < 0 )
- return TRUE;
- // All colors are legal if TEAM_LOCK_COLORS is off.
- if( !(teamplay & TEAM_LOCK_COLORS) )
- return TRUE;
- if( (color == TEAM_COLOR1) && (TEAM_COLOR1 >= 0) )
- return TRUE;
- if( (color == TEAM_COLOR2) && (TEAM_COLOR2 >= 0) )
- return TRUE;
- if( (color == TEAM_COLOR3) && (TEAM_COLOR3 >= 0) )
- return TRUE;
- if( (color == TEAM_COLOR4) && (TEAM_COLOR4 >= 0) )
- return TRUE;
- };
-
- /*
- ==================
- TeamCheckTeam
-
- Check if the team self is on is legal, and put self in a legal team if not.
- Return TRUE if the current color is ok, FALSE if we have to set it.
- ==================
- */
- float() TeamCheckTeam =
- {
- local float TEAM1;
- local float TEAM2;
- local float TEAM3;
- local float TEAM4;
-
- local float newcolor;
- local float t;
-
- local entity p;
-
- local string n;
-
-
- // If self.lastteam is negative, force a team assignment.
- if( self.lastteam >= 0 )
- {
- if(TeamColorIsLegal(self.team - 1))
- return TRUE;
- }
-
- // Assign the player to a team.
-
- // Sum the players on all the teams.
-
- TEAM1 = 0;
- TEAM2 = 0;
- TEAM3 = 0;
- TEAM4 = 0;
-
- p = find (world, classname, "player");
-
- while(p)
- {
- if( (TEAM_COLOR1 >= 0) && (p.team == (TEAM_COLOR1 +1)) )
- TEAM1 = TEAM1 + 1;
- if( (TEAM_COLOR2 >= 0) && (p.team == (TEAM_COLOR2 +1)) )
- TEAM2 = TEAM2 + 1;
- if( (TEAM_COLOR3 >= 0) && (p.team == (TEAM_COLOR3 +1)) )
- TEAM3 = TEAM3 + 1;
- if( (TEAM_COLOR4 >= 0) && (p.team == (TEAM_COLOR4 +1)) )
- TEAM4 = TEAM4 + 1;
-
- p = find(p, classname, "player");
- }
-
- // Find the team with the least players.
-
- newcolor = TEAM_COLOR1;
- t = TEAM1;
-
- if ( (TEAM_COLOR2 >= 0) && (TEAM2 < t) )
- {
- newcolor = TEAM_COLOR2;
- t = TEAM2;
- }
-
- if ( (TEAM_COLOR3 >= 0) && (TEAM3 < t) )
- {
- newcolor = TEAM_COLOR3;
- t = TEAM3;
- }
-
- if ( (TEAM_COLOR4 >= 0) && (TEAM4 < t) )
- {
- newcolor = TEAM_COLOR4;
- t = TEAM4;
- }
-
- // Put the player on a the new team.
-
- n = ftos(newcolor);
- stuffcmd(self, "color ");
- stuffcmd(self, n);
- stuffcmd(self, "\n");
-
- sprint(self, "You have been assigned color ");
- sprint(self, n);
- sprint(self, "\nLegal colors are:");
- if(TEAM_COLOR1 >= 0)
- {
- n = ftos(TEAM_COLOR1);
- sprint(self, " ");
- sprint(self, n);
- }
- if(TEAM_COLOR2 >= 0)
- {
- n = ftos(TEAM_COLOR2);
- sprint(self, " ");
- sprint(self, n);
- }
- if(TEAM_COLOR3 >= 0)
- {
- n = ftos(TEAM_COLOR3);
- sprint(self, " ");
- sprint(self, n);
- }
- if(TEAM_COLOR4 >= 0)
- {
- n = ftos(TEAM_COLOR4);
- sprint(self, " ");
- sprint(self, n);
- }
-
- sprint(self, "\n");
-
- self.lastteam = newcolor + 1; // Remember what team we're on
- return FALSE;
- };
-
-
-
- /*
- ===============
- TeamCheckLock
-
- Check for team changing and perform whatever actions are neccessary.
- ===============
- */
- void() TeamCheckLock =
- {
- local float n;
- local string s;
-
- // Don't do anything if teamplay is negative
- if ( teamplay < 0 )
- return;
-
- if ( !TeamColorIsLegal(self.team - 1) && (self.team == self.lastteam) )
- self.lastteam = -1;
-
- // Check to see if the player has changed colors
- if (self.team != self.lastteam)
- {
- // Player has changed colors
-
- // If teams are static and we've been on some team already,
- // put us back on the team we were on.
-
- if ( (teamplay & TEAM_STATIC_TEAMS) && (self.lastteam >= 0) )
- {
- if ( TeamColorIsLegal(self.lastteam - 1) )
- {
- sprint(self, "You cannot change teams.\n");
- stuffcmd(self, "color ");
- n = self.lastteam - 1;
- s = ftos(n);
- stuffcmd(self, s);
- stuffcmd(self, "\n");
- return;
- }
- else
- self.lastteam = -50;
- // If we're on an illegal team, force a change.
- }
-
- // If teamlock is turned off, don't do anything more.
- if ( !(teamplay & TEAM_LOCK_COLORS) )
- {
- if ( teamplay & TEAM_STATIC_TEAMS )
- self.lastteam = self.team;
- return;
- }
-
- if(self.lastteam > 0)
- {
- s = ftos(self.lastteam);
- T_Damage(self,self,self,1000); // Kill the player
- }
- self.frags = 0; // Zero out frags
- if(TeamCheckTeam())
- self.lastteam = self.team;
- }
- };
-
- /*
- =======================
- TossBackPack
-
- Original idea by Vhold
- Rewritten by John Spickes
-
- Toss out a backpack containing some ammo from your current weapon,
- and any weapons you don't have.
- =======================
- */
- void() TossBackpack =
- {
- local entity item;
-
- // If we don't have any ammo, return
- if(self.currentammo <= 0)
- return;
-
- item = spawn();
-
- // See if you have the Shotgun or Super Shotgun on
- if ( (self.weapon == IT_SHOTGUN) || (self.weapon == IT_SUPER_SHOTGUN) )
- {
- if( self.ammo_shells >= 20 ) {
- item.ammo_shells = 20;
- self.ammo_shells = self.ammo_shells - 20;
- }
- else
- {
- item.ammo_shells = self.ammo_shells;
- self.ammo_shells = 0;
- }
- }
-
- // See if you have neither the Shotgun or Super Shotgun
- if ( !(self.items & IT_SHOTGUN) && !(self.items & IT_SUPER_SHOTGUN) )
- {
- if( self.ammo_shells >= 20 ) {
- item.ammo_shells = 20;
- self.ammo_shells = self.ammo_shells - 20;
- }
- else
- {
- item.ammo_shells = self.ammo_shells;
- self.ammo_shells = 0;
- }
- }
-
- // See if we are using a nailgun
- if ( (self.weapon == IT_NAILGUN) || (self.weapon == IT_SUPER_NAILGUN) )
- {
- if( self.ammo_nails >= 20 )
- {
- item.ammo_nails = 20;
- self.ammo_nails = self.ammo_nails - 20;
- }
- else
- {
- item.ammo_nails = self.ammo_nails;
- self.ammo_nails = 0;
- }
- }
- // Check to see if we have neither nailgun
- if ( !(self.items & IT_NAILGUN) && !(self.items & IT_SUPER_NAILGUN) )
- {
- if( self.ammo_nails >= 20 )
- {
- item.ammo_nails = 20;
- self.ammo_nails = self.ammo_nails - 20;
- }
- else
- {
- item.ammo_nails = self.ammo_nails;
- self.ammo_nails = 0;
- }
- }
-
- // See if we are using a grenade or rocket launcher
- if ( (self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_ROCKET_LAUNCHER) )
- {
- if( self.ammo_rockets >= 10 )
- {
- item.ammo_rockets = 10;
- self.ammo_rockets = self.ammo_rockets - 10;
- }
- else
- {
- item.ammo_rockets = self.ammo_rockets;
- self.ammo_rockets = 0;
- }
- }
- // See if we have neither the Grenade or rocket launcher
- if ( !(self.items & IT_GRENADE_LAUNCHER) && !(self.items & IT_ROCKET_LAUNCHER) )
- {
- if( self.ammo_rockets >= 10 )
- {
- item.ammo_rockets = 10;
- self.ammo_rockets = self.ammo_rockets - 10;
- }
- else
- {
- item.ammo_rockets = self.ammo_rockets;
- self.ammo_rockets = 0;
- }
- }
-
- // See if we're using the lightning gun
- if ( self.weapon == IT_LIGHTNING )
- {
- if( self.ammo_cells >= 20 )
- {
- item.ammo_cells = 20;
- self.ammo_cells = self.ammo_cells - 20;
- }
- else
- {
- item.ammo_cells = self.ammo_cells;
- self.ammo_cells = 0;
- }
- }
- // see if we don't have the lightning gun
- if ( !(self.items & IT_LIGHTNING) )
- {
- if( self.ammo_cells >= 20 )
- {
- item.ammo_cells = 20;
- self.ammo_cells = self.ammo_cells - 20;
- }
- else
- {
- item.ammo_cells = self.ammo_cells;
- self.ammo_cells = 0;
- }
- }
-
- item.owner = self;
- makevectors(self.v_angle);
-
- setorigin(item, self.origin + '0 0 16');
- item.velocity = aim(self, 1000);
- item.velocity = item.velocity * 500;
- item.flags = FL_ITEM;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_BOUNCE;
-
- setmodel (item, "progs/backpack.mdl");
- setsize(item, '-16 -16 0', '16 16 56');
- item.touch = BackpackTouch;
- item.nextthink = time + 120; // remove after 2 minutes
- item.think = SUB_Remove;
-
- W_SetCurrentAmmo();
-
- };
-
- void() Team_weapon_touch =
- {
- local float hadammo, best, new, old;
- local entity stemp;
-
- if (!(other.flags & FL_CLIENT))
- return;
- // Don't let the owner pick up his own weapon for a second.
- if ( (other == self.owner) && ( (self.nextthink - time) > 119 ) )
- return;
-
- // if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
- if (self.classname == "weapon_nailgun")
- {
- hadammo = other.ammo_nails;
- new = IT_NAILGUN;
- }
- else if (self.classname == "weapon_supernailgun")
- {
- hadammo = other.ammo_rockets;
- new = IT_SUPER_NAILGUN;
- }
- else if (self.classname == "weapon_supershotgun")
- {
- hadammo = other.ammo_rockets;
- new = IT_SUPER_SHOTGUN;
- }
- else if (self.classname == "weapon_rocketlauncher")
- {
- hadammo = other.ammo_rockets;
- new = IT_ROCKET_LAUNCHER;
- }
- else if (self.classname == "weapon_grenadelauncher")
- {
- hadammo = other.ammo_rockets;
- new = IT_GRENADE_LAUNCHER;
- }
- else if (self.classname == "weapon_lightning")
- {
- hadammo = other.ammo_rockets;
- new = IT_LIGHTNING;
- }
- else
- objerror ("Team_weapon_touch: unknown classname");
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other, "\n");
- // weapon touch sound
- sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
- bound_other_ammo ();
-
- // change to the weapon
- old = other.items;
- other.items = other.items | new;
-
- stemp = self;
- self = other;
-
- if (!deathmatch)
- self.weapon = new;
- else
- Deathmatch_Weapon (old, new);
-
- W_SetCurrentAmmo();
-
- self = stemp;
-
- self.model = string_null;
- self.solid = SOLID_NOT;
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
- };
-
- void() TossWeapon =
- {
- local entity item;
-
- if((self.weapon == IT_AXE) || (self.weapon == IT_SHOTGUN))
- return;
-
- item = spawn();
- item.owner = self;
- makevectors(self.v_angle);
-
- setorigin(item, self.origin + '0 0 16');
- item.velocity = aim(self, 1000);
- item.velocity = item.velocity * 500;
- item.flags = FL_ITEM;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_BOUNCE;
-
- if(self.weapon == IT_SUPER_SHOTGUN)
- {
- setmodel (item, "progs/g_shot.mdl");
- item.weapon = IT_SUPER_SHOTGUN;
- item.netname = "Double-barrelled Shotgun";
- item.classname = "weapon_supershotgun";
- self.items = self.items - IT_SUPER_SHOTGUN;
- }
-
- if( self.weapon == IT_NAILGUN )
- {
- setmodel (item, "progs/g_nail.mdl");
- item.weapon = IT_NAILGUN;
- item.netname = "nailgun";
- item.classname = "weapon_nailgun";
- self.items = self.items - IT_NAILGUN;
- }
-
- if( self.weapon == IT_SUPER_NAILGUN )
- {
- setmodel (item, "progs/g_nail2.mdl");
- item.weapon = IT_SUPER_NAILGUN;
- item.netname = "Super Nailgun";
- item.classname = "weapon_supernailgun";
- self.items = self.items - IT_SUPER_NAILGUN;
- }
-
- if( self.weapon == IT_GRENADE_LAUNCHER )
- {
- setmodel (item, "progs/g_rock.mdl");
- item.weapon = 3;
- item.netname = "Grenade Launcher";
- item.classname = "weapon_grenadelauncher";
- self.items = self.items - IT_GRENADE_LAUNCHER;
- }
-
- if( self.weapon == IT_ROCKET_LAUNCHER )
- {
- setmodel (item, "progs/g_rock2.mdl");
- item.weapon = 3;
- item.netname = "Rocket Launcher";
- item.classname = "weapon_rocketlauncher";
- self.items = self.items - IT_ROCKET_LAUNCHER;
- }
-
- if( self.weapon == IT_LIGHTNING )
- {
- setmodel (item, "progs/g_light.mdl");
- item.weapon = 3;
- item.netname = "Thunderbolt";
- item.classname = "weapon_lightning";
- self.items = self.items - IT_LIGHTNING;
- }
- setsize(item, '-16 -16 0', '16 16 56');
- item.touch = Team_weapon_touch;
- item.think = SUB_Null;
- item.nextthink = time + 120;
-
- self.weapon = W_BestWeapon();
- W_SetCurrentAmmo();
- };
-