home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 28.9 KB | 1,256 lines |
- /*
- TeamFortress 1.21 - 7/9/96
-
- Robin Walker, John Cook, Ian Caughley.
-
- Functions handling TeamFortress Map Goal Entities
- */
- // Prototypes
- // Team Functions
- void(float tno, float scoretoadd) TeamFortress_TeamIncreaseScore;
- void(float all) TeamFortress_TeamShowScores;
- float() TeamFortress_TeamGetWinner;
-
- // AutoDetect entity
- void() info_tfdetect;
-
- // Functions to handle spawning
- void() TF_PlaceItem;
- void() TF_StartItem;
-
- // TeamSpawnpoint Functions
- void() info_player_teamspawn;
-
- // Goal Functions
- void() info_tfgoal;
- void() tfgoal_touch;
- void() tfgoal_activate;
- void(entity Goal, entity AP, float addb) tfgoal_result;
- void(entity Goal, entity AP, float addb) tfgoal_normal_result;
- void(entity Goal, entity AP, float addb) tfgoal_timer_result;
- void() tfgoal_respawn;
- void() tfgoal_timer_tick;
- void(entity Goal, entity AP) tfgoal_goal_group;
- void() TeamFortress_CheckClassStats;
- entity(float gno) tfgoal_findgoal;
-
- // GoalItem Functions
- void() item_tfgoal;
- void() item_tfgoal_touch;
- void(entity Item) tfgoalitem_drop;
- void() tfgoalitem_remove;
- void() tfgoalitem_checkgoalreturn;
- void(entity Item, entity AP) tfgoalitem_GiveToAP;
- void(entity Item, entity AP, float method) tfgoalitem_RemoveFromAP;
- entity(float ino) tfgoal_finditem;
-
- //=========================================================================
- // AUTODETECT ENTITY FUNCTIONS
- //=========================================================================
- //=========================================================================
- // Spawn the detection entity
- void() info_tfdetect =
- {
- self.solid = SOLID_NOT;
- setsize (self, '-16 -16 -24', '16 16 32');
- };
-
- //=========================================================================
- // SPAWNING FUNCTIONS
- //=========================================================================
- //=========================================================================
- // Place the Goal Item
- void() TF_PlaceItem =
- {
- local float oldz;
-
- self.flags = FL_ITEM; // make extra wide
- self.movetype = MOVETYPE_TOSS;
- self.velocity = '0 0 0';
- self.oldorigin = self.origin; // So we can return it later
- };
-
- //=========================================================================
- // Start the Goal Item
- void() TF_StartItem =
- {
- self.nextthink = time + 0.2; // items start after other solids
- self.think = TF_PlaceItem;
- };
-
- //=========================================================================
- // Place the Goal
- void() TF_PlaceGoal =
- {
- local float oldz;
-
- if (!(self.goal_activation & TFGA_TIMER_GOAL))
- {
- self.touch = tfgoal_touch;
- }
- else
- {
- if (self.search_time <= 0)
- {
- dprint("Timer Goal with no search_time specified.\n");
- remove(self);
- }
- // Set up the next Timer Tick
- self.think = tfgoal_timer_tick;
- self.nextthink = time + self.search_time;
- }
-
- self.flags = FL_ITEM; // make extra wide
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
- self.oldorigin = self.origin; // So we can return it later
- };
-
- //=========================================================================
- // Start the Goal
- void() TF_StartGoal =
- {
- self.nextthink = time + 0.2; // items start after other solids
- self.think = TF_PlaceGoal;
- };
-
- //=========================================================================
- // Spawnpoints for team games with FortressMap
- void() info_player_teamspawn =
- {
- if ((self.spawnflags) && (self.team_no == 0))
- self.team_no = self.spawnflags;
-
- // find the highest team number
- if (number_of_teams < self.team_no)
- number_of_teams = self.team_no;
-
- // Team spawnpoints must have a team associated with them
- if (self.team_no <= 0)
- {
- dprint("no team_no associated with info_player_teamspawn\n");
- remove(self);
- }
- };
-
- //=========================================================================
- // GOAL FUNCTIONS
- //=========================================================================
- //=========================================================================
- // Spawn the goal entity
- void() info_tfgoal =
- {
- self.solid = SOLID_TRIGGER;
- self.goal_state = TFGS_INACTIVE;
- setsize (self, '-16 -16 -24', '16 16 32');
- TF_StartGoal ();
- };
-
- //=========================================================================
- // Touch function for the goal entity
- void() tfgoal_touch =
- {
- local string st;
-
- if (other.classname != "player")
- return;
-
- // Fortressmap is off?
- if (!(toggleflags & TFLAG_FORTRESSMAP))
- return;
-
- // If it's a Timer Goal, return
- if (self.goal_activation & TFGA_TIMER_GOAL)
- return;
-
- // If it is not activated in by the player's touch, return
- if (!(self.goal_activation & TFGA_TOUCH))
- return;
-
- // Attempt to activate it
- tfgoal_activate();
- };
-
- //=========================================================================
- // Last check before activation. self = goal, other = player who activated it
- void() tfgoal_activate =
- {
- local entity te;
- local string db;
-
- // If a player of a specific team can only activate this
- if (self.goal_activation & TFGA_TEAM)
- {
- if (self.team_no != other.team_no)
- return;
- }
-
- // If a player of a specific class can only activate this
- if (self.goal_activation & TFGA_CLASS)
- {
- if (self.playerclass != other.playerclass)
- return;
- }
-
- // If this activation needs a GoalItem, make sure the player has it
- if (self.goal_activation & TFGA_ITEM)
- {
- te = tfgoal_finditem(self.items_allowed);
- if (te.owner != other)
- return;
- }
-
-
- // It's all ok.
- // Do the results, adding the bonuses
- tfgoal_result(self, other, 1);
- };
-
- //=========================================================================
- // Goal has been activated.
- // addb : >0 if you want to add bonuses of the goal to the AP
- void(entity Goal, entity AP, float addb) tfgoal_result =
- {
- // If it's a Timer Goal, call the Timer Goal activation
- if (Goal.goal_activation & TFGA_TIMER_GOAL)
- {
- tfgoal_timer_result(Goal, AP, addb);
- return;
- }
-
- // Otherwise, call the Normal Goal activation
- tfgoal_normal_result(Goal, AP, addb);
- };
-
- //=========================================================================
- // Normal Goal has been activated.
- // addb : >0 if you want to add bonuses of the goal to the AP
- void(entity Goal, entity AP, float addb) tfgoal_normal_result =
- {
- local entity te, oldself;
- local string st;
- local float winners;
-
- // Is the goal already activated?
- // This check is needed for goals which are being activated by other goals
- if (Goal.goal_state == TFGS_ACTIVE)
- return;
-
- // Goal is now active
- Goal.goal_state = TFGS_ACTIVE;
- stuffcmd (AP, "bf\n");
-
- // Display the message and increase the team score
- if (Goal.netname)
- bprint(Goal.netname);
- if (Goal.message)
- sprint(AP, Goal.message);
- if (Goal.count > 0)
- {
- if (AP.team_no > 0)
- {
- TeamFortress_TeamIncreaseScore(AP.team_no, Goal.count);
- // Display short team scores
- TeamFortress_TeamShowScores(2);
- }
- }
-
- // Apply Stats, only if told to
- if (addb)
- {
- if (Goal.health > 0)
- T_Heal(AP, Goal.health, 0);
- if (Goal.health < 0)
- T_Damage(AP, Goal, Goal, (0 - Goal.health));
- AP.armortype = AP.armortype + Goal.armortype;
- AP.armorvalue = AP.armorvalue + Goal.armorvalue;
- AP.frags = AP.frags + Goal.frags;
- AP.ammo_shells = AP.ammo_shells + Goal.ammo_shells;
- AP.ammo_nails = AP.ammo_nails + Goal.ammo_nails;
- AP.ammo_rockets = AP.ammo_rockets + Goal.ammo_rockets;
- AP.ammo_cells = AP.ammo_cells + Goal.ammo_cells;
- AP.ammo_medikit = AP.ammo_medikit + Goal.ammo_medikit;
- AP.ammo_detpack = AP.ammo_detpack + Goal.ammo_detpack;
- AP.no_grenades_1 = AP.no_grenades_1 + Goal.no_grenades_1;
- AP.no_grenades_2 = AP.no_grenades_2 + Goal.no_grenades_2;
-
- // Apply any powerups
- if (Goal.invincible_finished > 0)
- {
- AP.items = AP.items | IT_INVULNERABILITY;
- AP.invincible_time = 1;
- AP.invincible_finished = time + Goal.invincible_finished;
- }
- if (Goal.invisible_finished > 0)
- {
- AP.items = AP.items | IT_INVISIBILITY;
- AP.invisible_time = 1;
- AP.invisible_finished = time + Goal.invisible_finished;
- }
- if (Goal.super_damage_finished > 0)
- {
- AP.items = AP.items | IT_QUAD;
- AP.super_time = 1;
- AP.super_damage_finished = time + Goal.super_damage_finished;
- }
- if (Goal.radsuit_finished > 0)
- {
- AP.items = AP.items | IT_SUIT;
- AP.rad_time = 1;
- AP.radsuit_finished = time + Goal.radsuit_finished;
- }
-
- // Now apply the Playerclass limitations & Redisplay Ammo counts
- oldself = self;
- self = AP;
- TeamFortress_CheckClassStats();
- W_SetCurrentAmmo ();
- self = oldself;
- }
-
- // If there's a GoalItem for this goal, give it to the player
- if (Goal.goal_result & TFGR_ITEM)
- {
- if (Goal.items != 0)
- {
- // Find the item
- te = tfgoal_finditem(Goal.items);
- if (te)
- {
- // Give it to the player
- tfgoalitem_GiveToAP(te, AP);
- }
- }
- else
- {
- // No item specified in .items. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_ITEM);
- bprint(st);
- bprint(" set, but no .items specified.\n");
- }
- }
-
- // If this goal removes an item from the player, remove it
- if (Goal.goal_result & TFGR_ITEM_REMOVE)
- {
- if (Goal.axhitme != 0)
- {
- te = find (world, classname, "item_tfgoal");
- while (te)
- {
- if ((te.owner == AP) && (te.goal_no == Goal.axhitme))
- {
- // Remove it from the player
- tfgoalitem_RemoveFromAP(te, AP, 1);
- }
- te = find(te, classname, "item_tfgoal");
- }
- }
- else
- {
- // No item specified in .items. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_ITEM_REMOVE);
- bprint(st);
- bprint(" set, but no .axhitme specified.\n");
- }
- }
-
- // Does this goal end the level?
- if (Goal.goal_result & TFGR_ENDGAME)
- {
- // Display Long TeamScores to everyone
- TeamFortress_TeamShowScores(1);
- winners = TeamFortress_TeamGetWinner();
-
- // Stop everyone
- te = find (world, classname, "player");
- while (te)
- {
- te.takedamage = 0;
- te.movetype = MOVETYPE_NONE;
-
- // Can't append strings for centerprint :(
- if (winners == 1)
- centerprint(te, "Team 1 wins!\n");
- if (winners == 2)
- centerprint(te, "Team 2 wins!\n");
- if (winners == 3)
- centerprint(te, "Team 3 wins!\n");
- if (winners == 4)
- centerprint(te, "Team 4 wins!\n");
-
- te = find(te, classname, "player");
- }
-
- te = spawn();
- te.nextthink = time + 5; // Allow 3 secs to read the scores
- te.think = execute_changelevel;
-
- remove(Goal);
- return;
- }
-
- // Do Goal Group checking
- tfgoal_goal_group(Goal, AP);
-
- // If another goal should be activated, activate it
- if (Goal.goal_result & TFGR_GOAL_ACTIVATE)
- {
- if (Goal.impulse != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.impulse);
- if (te)
- {
- tfgoal_result(te, AP, (!(AP.goal_result & TFGR_NO_ACT_BONUS)));
- }
- }
- else
- {
- // No goal specified in .impulse. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_ACTIVATE);
- bprint(st);
- bprint(" set, but no .impulse specified.\n");
- }
- }
-
- // If another goal should be removed, remove it
- if (Goal.goal_result & TFGR_GOAL_REMOVE)
- {
- if (Goal.waitmin != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.waitmin);
- if (te)
- {
- te.solid = SOLID_NOT;
- te.goal_state = TFGS_REMOVED;
- }
- }
- else
- {
- // No goal specified in .waitmin. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_REMOVE);
- bprint(st);
- bprint(" set, but no .waitmin specified.\n");
- }
- }
-
- // If another goal should be restored, restore it
- if (Goal.goal_result & TFGR_GOAL_RESTORE)
- {
- if (Goal.waitmax != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.waitmax);
- if (te)
- {
- if (te.goal_state == TFGS_REMOVED)
- {
- te.solid = SOLID_TRIGGER;
- te.goal_state = TFGS_INACTIVE;
- }
- }
- }
- else
- {
- // No goal specified in .waitmax. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_RESTORE);
- bprint(st);
- bprint(" set, but no .waitmax specified.\n");
- }
- }
-
- // If another goal should be inactivated, inactivate it
- if (Goal.goal_result & TFGR_GOAL_INACTIVATE)
- {
- if (Goal.distance != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.distance);
- if (te)
- {
- if (te.goal_state == TFGS_ACTIVE)
- {
- te.solid = SOLID_TRIGGER;
- te.goal_state = TFGS_INACTIVE;
- }
- }
- }
- else
- {
- // No goal specified in .waitmax. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_INACTIVATE);
- bprint(st);
- bprint(" set, but no .distance specified.\n");
- }
- }
-
- // Check status of respawn for this goal
- // Single Activation, do nothing
- if (Goal.goal_result & TFGR_SINGLE)
- {
- Goal.solid = SOLID_NOT;
- return;
- }
- // Respawn Activation, set up respawn
- if (Goal.goal_result & TFGR_RESPAWN)
- {
- Goal.solid = SOLID_NOT;
- Goal.nextthink = time + Goal.wait;
- Goal.think = tfgoal_respawn;
- return;
- }
- // Otherwise, it's a Multiple Goal
- Goal.goal_state = TFGS_INACTIVE;
- };
-
- //=========================================================================
- // Timer Goal has been activated.
- // addb : >0 if you want to add bonuses of the goal to the AP
- // AP and addb are still passed in, since I'll add in the ability to
- // use an AP shortly.
- void(entity Goal, entity AP, float addb) tfgoal_timer_result =
- {
- local entity te, oldself;
- local string st;
- local float winners;
-
- // Is the goal already activated?
- // This check is needed for goals which are being activated by other goals
- if (Goal.goal_state == TFGS_ACTIVE)
- return;
-
- // Goal is now active
- Goal.goal_state = TFGS_ACTIVE;
-
- // Display the message and increase the team score
- if (Goal.netname)
- bprint(Goal.netname);
-
- // Does this goal end the level?
- if (Goal.goal_result & TFGR_ENDGAME)
- {
- // Display Long TeamScores to everyone
- TeamFortress_TeamShowScores(1);
- winners = TeamFortress_TeamGetWinner();
-
- // Stop everyone
- te = find (world, classname, "player");
- while (te)
- {
- te.takedamage = 0;
- te.movetype = MOVETYPE_NONE;
-
- // Can't append strings for centerprint :(
- if (winners == 1)
- centerprint(te, "Team 1 wins!\n");
- if (winners == 2)
- centerprint(te, "Team 2 wins!\n");
- if (winners == 3)
- centerprint(te, "Team 3 wins!\n");
- if (winners == 4)
- centerprint(te, "Team 4 wins!\n");
-
- te = find(te, classname, "player");
- }
-
- te = spawn();
- te.nextthink = time + 5; // Allow 3 secs to read the scores
- te.think = execute_changelevel;
-
- remove(Goal);
- return;
- }
-
- // Do Goal Group checking
- // No activations!
- if (!(Goal.goal_group & TFGG_ACTIVATE))
- tfgoal_goal_group(Goal, AP);
- else
- bprint("Timer Goal attempting to do Goal Group actions!\n");
-
- // If another goal should be removed, remove it
- if (Goal.goal_result & TFGR_GOAL_REMOVE)
- {
- if (Goal.waitmin != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.waitmin);
- if (te)
- {
- te.solid = SOLID_NOT;
- te.goal_state = TFGS_REMOVED;
- }
- }
- else
- {
- // No goal specified in .waitmin. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_REMOVE);
- bprint(st);
- bprint(" set, but no .waitmin specified.\n");
- }
- }
-
- // If another goal should be restored, restore it
- if (Goal.goal_result & TFGR_GOAL_RESTORE)
- {
- if (Goal.waitmax != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.waitmax);
- if (te)
- {
- if (te.goal_state == TFGS_REMOVED)
- {
- te.solid = SOLID_TRIGGER;
- te.goal_state = TFGS_INACTIVE;
- }
- }
- }
- else
- {
- // No goal specified in .waitmax. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_RESTORE);
- bprint(st);
- bprint(" set, but no .waitmax specified.\n");
- }
- }
-
- // If another goal should be inactivated, inactivate it
- if (Goal.goal_result & TFGR_GOAL_INACTIVATE)
- {
- if (Goal.distance != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(Goal.distance);
- if (te)
- {
- if (te.goal_state == TFGS_ACTIVE)
- {
- te.solid = SOLID_TRIGGER;
- te.goal_state = TFGS_INACTIVE;
- }
- }
- }
- else
- {
- // No goal specified in .waitmax. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_result bit ");
- st = ftos(TFGR_GOAL_INACTIVATE);
- bprint(st);
- bprint(" set, but no .distance specified.\n");
- }
- }
-
- // Set up the next Timer Tick
- Goal.goal_state = TFGS_INACTIVE;
- Goal.think = tfgoal_timer_tick;
- Goal.nextthink = time + Goal.search_time;
- };
-
- //=========================================================================
- // Respawn the goal
- void() tfgoal_respawn =
- {
- if (self.goal_state != TFGS_REMOVED)
- {
- self.goal_state = TFGS_INACTIVE;
- self.solid = SOLID_TRIGGER; // allow it to be touched again
- }
- };
-
- //=========================================================================
- // Activate the Timer goal
- void() tfgoal_timer_tick =
- {
- if (self.goal_state != TFGS_REMOVED)
- {
- tfgoal_result(self, world, 0); // Do Timer Tick again
- }
- };
-
- //=========================================================================
- // Check and do any behaviour for the goal's group
- void(entity Goal, entity AP) tfgoal_goal_group =
- {
- local string st;
- local entity tg;
- local float allset;
-
- // Check all goals activated flag
- if (Goal.goal_group & TFGG_ACTIVATE)
- {
- // Make sure a valid group no is specified
- if (Goal.height == 0)
- {
- // No goal specified in .height. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE);
- bprint(st);
- bprint(" set, but no .height specified.\n");
- }
- else if (Goal.last_impulse == 0)
- {
- // No goal specified in .lastimpulse. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE);
- bprint(st);
- bprint(" set, but no .last_impulse specified.\n");
- }
- else
- {
- allset = 1;
- // Find all goals
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.group_no == Goal.height)
- {
- if (tg.goal_state != TFGS_ACTIVE)
- allset = 0;
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
-
- // If all goals in this group are activated, do it
- if (allset)
- {
- // Find the goal
- tg = tfgoal_findgoal(Goal.last_impulse);
- if (tg)
- {
- tfgoal_result(tg, AP, 0); // Don't apply bonuses
- }
- }
- }
- }
-
- // Check Activate all in the group flag
- if (Goal.goal_group & TFGG_ACTIVATE_ALL)
- {
- // Make sure a valid group no is specified
- if (Goal.aflag == 0)
- {
- // No goal specified in .aflag. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE_ALL);
- bprint(st);
- bprint(" set, but no .aflag specified.\n");
- }
- else
- {
- // Find all goals
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.group_no == Goal.aflag)
- {
- tfgoal_result(tg, AP, 0); // Don't apply bonuses
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
- }
- }
-
- // Check Inactivate all in the group flag
- if (Goal.goal_group & TFGG_INACTIVATE_ALL)
- {
- // Make sure a valid group no is specified
- if (Goal.dmg == 0)
- {
- // No goal specified in .dmg. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE_ALL);
- bprint(st);
- bprint(" set, but no .dmg specified.\n");
- }
- else
- {
- // Find all goals
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.group_no == Goal.dmg)
- {
- if (tg.goal_state == TFGS_ACTIVE)
- {
- tg.goal_state = TFGS_INACTIVE;
- tg.solid = SOLID_TRIGGER;
- }
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
- }
- }
-
- // Check Remove all in the group flag
- if (Goal.goal_group & TFGG_REMOVE_ALL)
- {
- // Make sure a valid group no is specified
- if (Goal.cnt == 0)
- {
- // No goal specified in .cnt. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE_ALL);
- bprint(st);
- bprint(" set, but no .cnt specified.\n");
- }
- else
- {
- // Find all goals
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.group_no == Goal.cnt)
- {
- tg.goal_state = TFGS_REMOVED;
- tg.solid = SOLID_NOT;
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
- }
- }
-
- // Check Restore all in the group flag
- if (Goal.goal_group & TFGG_RESTORE_ALL)
- {
- // Make sure a valid group no is specified
- if (Goal.pausetime == 0)
- {
- // No goal specified in .pausetime. Print error.
- bprint("Goal ");
- st = ftos(Goal.goal_no);
- bprint(st);
- bprint(" has goal_group bit ");
- st = ftos(TFGG_ACTIVATE_ALL);
- bprint(st);
- bprint(" set, but no .pausetime specified.\n");
- }
- else
- {
- // Find all goals
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.group_no == Goal.pausetime)
- {
- if (tg.goal_state == TFGS_REMOVED)
- {
- tg.goal_state = TFGS_INACTIVE;
- tg.solid = SOLID_TRIGGER;
- }
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
- }
- }
- };
-
- //=========================================================================
- // Return the goal with a goal_no equal to gno
- entity(float gno) tfgoal_findgoal =
- {
- local entity tg;
- local string st;
-
- // Look for the goal
- tg = find (world, classname, "info_tfgoal");
- while (tg)
- {
- if (tg.goal_no == gno)
- {
- return tg;
- }
-
- tg = find(tg, classname, "info_tfgoal");
- }
-
- // Goal does not exist
- bprint("Could not find a goal with a goal_no of ");
- st = ftos(gno);
- bprint(st);
- bprint(".\n");
- };
-
-
-
- //=========================================================================
- // GOALITEM FUNCTIONS
- //=========================================================================
- // Spawn the goalitem entity
- void() item_tfgoal =
- {
- // Graphic
- if (self.mdl)
- {
- precache_model2(self.mdl);
- setmodel(self, self.mdl);
- }
- else
- {
- // Default mdl for a GoalItem that shouldn't be seen
- self.mdl = "progs/w_s_key.mdl";
- precache_model("progs/w_s_key.mdl");
- setmodel(self, "progs/w_s_key.mdl");
- }
-
- // Respawn sound
- precache_sound2("items/itembk2.wav");
-
- // Collection sound
- if (self.noise)
- {
- precache_sound2(self.noise);
- }
- else
- {
- // Default wav sound for a GoalItem collection
- self.noise = "misc/basekey.wav";
- precache_sound2("misc/basekey.wav");
- }
-
- self.touch = item_tfgoal_touch;
- self.goal_state = TFGS_INACTIVE;
-
- // Should this be placed on the map?
- if (self.goal_activation & TFGI_NOEXIST)
- {
- self.solid = SOLID_NOT;
- }
- else
- {
- self.solid = SOLID_TRIGGER;
- setmodel(self, self.mdl);
- setorigin(self, self.origin);
- }
-
- if (!(self.netname))
- self.netname = "goalitem";
-
- if (self.delay <= 0)
- self.delay = 120;
- setsize (self, '-16 -16 -24', '16 16 32');
- TF_StartItem ();
- };
-
- //=========================================================================
- // Touch function for the goalitem entity
- void() item_tfgoal_touch =
- {
- local string st;
- local entity te;
-
- if (other.classname != "player")
- return;
-
- // Fortressmap is off?
- if (!(toggleflags & TFLAG_FORTRESSMAP))
- return;
-
- // If a player of a specific team can get this one
- if (self.goal_activation & TFGI_TEAM)
- {
- if (self.team_no != other.team_no)
- return;
- }
-
- // If a player must be of a particular class to get this one
- if (self.goal_activation & TFGI_CLASS)
- {
- if (self.playerclass != other.playerclass)
- return;
- }
-
- // If a player needs a GoalItem to be able to get this one
- if (self.goal_activation & TFGI_ITEM)
- {
- te = tfgoal_finditem(self.items_allowed);
- if (te.owner != other)
- return;
- }
-
- // Give it to the player
- tfgoalitem_GiveToAP(self, other);
- };
-
- //=========================================================================
- // Return the item with a goal_no equal to ino
- entity(float ino) tfgoal_finditem =
- {
- local entity tg;
- local string st;
-
- // Look for the goal
- tg = find (world, classname, "item_tfgoal");
- while (tg)
- {
- if (tg.goal_no == ino)
- {
- return tg;
- }
-
- tg = find(tg, classname, "item_tfgoal");
- }
-
- // Goal does not exist
- bprint("Could not find an item with a goal_no of ");
- st = ftos(ino);
- bprint(st);
- bprint(".\n");
- };
-
- //=========================================================================
- // Give the GoalItem to a Player.
- void(entity Item, entity AP) tfgoalitem_GiveToAP =
- {
- local string sp;
-
- // Display the message
- if (Item.message)
- bprint(Item.message);
- if (Item.deathtype)
- sprint(AP, Item.deathtype);
-
- // Make the sound
- sound (other, CHAN_ITEM, Item.noise, 1, ATTN_NORM);
-
- Item.owner = AP;
- // Remove it from the map
- Item.model = string_null;
- Item.solid = SOLID_NOT;
-
- // Don't let it return
- Item.goal_state = TFGS_INACTIVE;
-
- // Do the deeds on the player
- if (Item.goal_activation & TFGI_GLOW)
- AP.effects = AP.effects | EF_BRIGHTLIGHT;
- if (Item.goal_activation & TFGI_SLOW)
- {
- AP.maxfbspeed = (AP.maxfbspeed / 2);
- AP.maxstrafespeed = (AP.maxstrafespeed / 2);
- sp = ftos(AP.maxfbspeed);
- stuffcmd(AP,"cl_backspeed ");
- stuffcmd(AP,sp);
- stuffcmd(AP,"\n");
- stuffcmd(AP,"cl_forwardspeed ");
- stuffcmd(AP,sp);
- stuffcmd(AP,"\n");
- sp = ftos(AP.maxstrafespeed);
- stuffcmd(AP,"cl_sidespeed ");
- stuffcmd(AP,sp);
- stuffcmd(AP,"\n");
- }
- };
-
- //=========================================================================
- // Remove the GoalItem from a Player. self = item, other = player
- void(entity Item, entity AP, float method) tfgoalitem_RemoveFromAP =
- {
- local entity oldself;
-
- // Remove the deeds from the player
- AP.effects = AP.effects - (AP.effects & EF_BRIGHTLIGHT);
- if (Item.goal_activation & TFGI_SLOW)
- {
- oldself = self;
- self = AP;
- TeamFortress_SetSpeed();
- self = oldself;
- }
-
- // Return it to the starting point if the flag is set
- if (method == 0) // Dropped by a dying player
- {
- // Drop it if the flag is set
- if (Item.goal_activation & TFGI_DROP)
- {
- tfgoalitem_drop(Item);
- }
- else if (Item.goal_activation & TFGI_RETURN_DROP)
- {
- Item.solid = SOLID_TRIGGER;
- Item.touch = item_tfgoal_touch;
- Item.origin = Item.oldorigin;
- setmodel(Item, Item.mdl);
- setorigin(Item, Item.origin);
- sound (Item, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
-
- // Restore a goal if needed
- tfgoalitem_checkgoalreturn();
- }
- else
- {
- // Remove the Item
- remove(Item);
- }
- Item.owner = world;
- return;
- }
-
- // Return it to the starting point if the flag is set
- if (method == 1) // Removed by a goal activation
- {
- if (Item.goal_activation & TFGI_RETURN_GOAL)
- {
- Item.solid = SOLID_TRIGGER;
- Item.touch = item_tfgoal_touch;
- Item.origin = Item.oldorigin;
- setmodel(Item, Item.mdl);
- setorigin(Item, Item.origin);
- sound (Item, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
-
- // Restore a goal if needed
- tfgoalitem_checkgoalreturn();
- }
-
- // Don't remove it anyway, since it may be given away again later
- self.solid = SOLID_NOT;
- Item.owner = world;
- return;
- }
- };
-
- //=========================================================================
- // Drop the item just like a backpack
- void(entity Item) tfgoalitem_drop =
- {
- Item.origin = Item.owner.origin - '0 0 24';
-
- Item.velocity_z = 300;
- Item.velocity_x = -100 + (random() * 200);
- Item.velocity_y = -100 + (random() * 200);
-
- Item.movetype = MOVETYPE_TOSS;
- Item.solid = SOLID_TRIGGER;
- Item.touch = item_tfgoal_touch;
- setorigin(Item, Item.origin);
- setmodel(Item, Item.mdl);
-
- // If the flag is set, remove it after 2 minutes
- if (Item.goal_activation & TFGI_REMOVE)
- {
- Item.goal_state = TFGS_ACTIVE;
- Item.nextthink = time + Item.delay;
- Item.think = tfgoalitem_remove;
- }
- };
-
- //=========================================================================
- // Remove the item, or Return it if needed
- void() tfgoalitem_remove =
- {
- // Has someone picked it up?
- if (self.goal_state != TFGS_ACTIVE)
- return;
-
- // Should it be returned?
- if (self.goal_activation & TFGI_RETURN_REMOVE)
- {
- self.solid = SOLID_TRIGGER;
- self.touch = item_tfgoal_touch;
- self.origin = self.oldorigin;
- setmodel(self, self.mdl);
- setorigin (self, self.origin);
- sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
-
- // Restore a goal if needed
- tfgoalitem_checkgoalreturn();
-
- return;
- }
-
- remove(self);
- };
-
- //=========================================================================
- // Restore a goal when this item is removed, if needed
- void() tfgoalitem_checkgoalreturn =
- {
- local string st;
- local entity te;
-
- // Do we need to restore a goal somewhere?
- if (self.goal_activation & TFGI_RESTORE_GOAL)
- {
- if (self.impulse != 0)
- {
- // Find the goal
- te = tfgoal_findgoal(self.impulse);
- if (te)
- {
- // Restore it
- te.solid = SOLID_TRIGGER;
- if (te.goal_state == TFGS_REMOVED)
- te.goal_state = TFGS_INACTIVE;
- }
- }
- else
- {
- // No goal specified in .impulse. Print error.
- bprint("GoalItem ");
- st = ftos(self.goal_no);
- bprint(st);
- bprint(" has goal_activation bit ");
- st = ftos(TFGI_RESTORE_GOAL);
- bprint(st);
- bprint(" set, but no .impulse specified.\n");
- }
- }
- };