prozac-qfcc/custom.qc
Adam Olsen 55500b87d6 - change all usages of MSG_BROADCAST to MSG_MULTICAST, since that's
what quakeworld uses anyway
- when changing a player's team with the admin commands, change the
  player's color, not the admin's color :)
2001-10-13 23:02:22 +00:00

1428 lines
39 KiB
C++
Raw Blame History

/*======================================================
CUSTOM.QC Custom TeamFortress v3.2
(c) William Kerney 5/21/00
========================================================
All the functions pertaining to custom class generation and
the miscellanious new features of Custom TF
======================================================*/
#include "defs.qh"
#include "menu.qh"
float(float t1, float t2) Teammate; //KK: are team_no's current teammates
void() DropToCustomClassGen; //Called when starting class generation
void() DropFromCustomClassGen; //Called when finished class generation
void() PrintMoney;
void(float in) PrintRefund;
void(float in) PrintNotEnoughMoney;
void(float cost, float type) BuyWeapon;
void(float cost, float type) BuyCuTF;
void(float cost, float type) BuyItem;
void(float cost, float type) BuyJob;
/*void(float cost, float type) BuyGren1;
void(float cost, float type) BuyGren2;*/
void(entity tif, float pain) RevealThief;
void() FragGrenadeTouch;
void() FragGrenadeExplode;
void() KracGrenadeTouch;
void() KracGrenadeExplode;
void(entity bastard,float threshold) createBastard;
void(entity immuner,float timer) makeImmune;
void() UseJobSkill; //Function for handling professions
void() DetonateAllGuns;
void (string temp) DebugSprint;
void (float temp) DebugSprintFloat;
float(entity tester) IsBuilding;
void() autoteam_think;
//Extern
void (vector org, entity death_owner) spawn_tdeath;
void (string gib, float health) ThrowGib;
void() TeamFortress_SetHealth;
void() TeamFortress_SetEquipment;
float() W_BestWeapon;
void() W_SetCurrentAmmo;
void(entity p) TeamFortress_SetSpeed;
void(entity p) TeamFortress_SetSkin;
void(entity Viewer, float pc) TeamFortress_PrintJobName;
void () BecomeExplosion;
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void() SUB_regen;
float modelindex_eyes, modelindex_player, modelindex_null;
void(float inAuto) W_FireMedikit;
void(float inAuto) TeamFortress_ID;
void(float range,float inAuto) TeamFortress_Scan;
void() kill_my_demon;
void() player_assaultcannondown1;
void (entity rhook) Reset_Grapple;
void() GuerillaExplode;
void(float krac) TeamFortress_DetpackStop;
void (float all) TeamFortress_TeamShowScores;
void () execute_changelevel;
void(entity Item, entity AP, float method) tfgoalitem_RemoveFromPlayer;
//- OfN
void(entity mine_owner) DetonateMines; //external, job.qc
float (float tno) TeamGetNiceColor;
void() SetArmyTimer;
void() RemoveArmyTimer;
entity() SelectSpawnPoint;
void(entity tfield, vector where, entity thing) FieldExplosion;
//KK: are team_no's current teammates
float(float targteam, float attackteam) Teammate =
{
local float teammask;
if (!teamplay) return FALSE;
if (!targteam) return FALSE;
if (targteam == attackteam) return TRUE;
if (number_of_teams < 3) return FALSE;
teammask = 1 << (targteam - 1);
if (attackteam == 1 && (friends1_mask & teammask)) return TRUE;
else if (attackteam == 2 && (friends2_mask & teammask)) return TRUE;
else if (attackteam == 3 && (friends3_mask & teammask)) return TRUE;
else if (attackteam == 4 && (friends4_mask & teammask)) return TRUE;
return FALSE;
};
void (string temp) DebugSprint =
{
sprint(self,PRINT_HIGH,temp);
sprint(self,PRINT_HIGH,"\n");
};
void (float foo) DebugSprintFloat =
{
local string temp;
temp = ftos(foo);
sprint(self,PRINT_HIGH,temp);
sprint(self,PRINT_HIGH,"\n");
};
void() DropToCustomClassGen =
{
local float sell_no;
sell_no = 0;
self.gravity = 1;
//st = infokey(world, "no_grapple");
kill_my_demon();//FIXED?
DetonateMines(self);
RemoveArmyTimer();
self.aura = 0;
//Remove everything he's carrying
self.job = 0;
self.is_malfunctioning = 0;
//self.is_cameraviewing = 0;
self.tf_items = 0;
self.cutf_items = 0;
self.tf_items_flags = 0;
self.items = 0;
self.ammo_rockets = 0;
self.ammo_nails = 0;
self.ammo_shells = 0;
self.ammo_cells = 0;
self.maxammo_rockets = 10; //Give em a minimal carrying capacity
self.maxammo_nails = 10;
self.maxammo_shells = 10;
self.maxammo_cells = 10;
self.maxammo_medikit = 0;
self.maxammo_detpack = 0;
self.ammo_c4det = 0;
self.demon_one = world; //SB - this tells us who our demon is for easy reference
self.demon_two = world; //- OfN- Used for hacker job, target building and for timer (% on sbar)
self.demon_blood = 0;
//self.demon_points = 5;
self.num_mines = 0; // OfN Number of mines set by the player
self.no_grenades_1 = 0;
self.no_grenades_2 = 0;
self.tp_grenades_1 = 0;
self.tp_grenades_2 = 0;
self.armor_allowed = 0.3; //Red yellow or green
self.armorclass = 0; //Red yellow or green
self.armorvalue = 0; //200 etc
self.maxarmor = 0; //200 etc
self.weapon = 0; // WEAP_HOOK & WEAP_SHOTGUN etc
self.current_weapon = 0; // No current weapon
if ((allow_hook) && (no_grapple != 1)) //If map allows it...
self.weapons_carried = WEAP_HOOK; // Start with grapple
else
self.weapons_carried = 0; // Or remove everything
self.weaponmodel = ""; //Remove the model of a weapon in front
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
self.takedamage = DAMAGE_NO;
//Ready to buy
self.maxspeed = 0; //Can't move while buying
self.max_health = 50;
self.health = 50;
#define PRICE_PER_FRAG 100
#define MAX_FRAGS_TO_SELL 50
//Calculate starting money
//This means the most someone can get is 50*100 = $5000
if (self.done_custom & CUSTOM_SELLING)
{
if (self.real_frags >= MAX_FRAGS_TO_SELL)
sell_no = MAX_FRAGS_TO_SELL;
else if (self.real_frags > 0)
sell_no = self.real_frags;
else {
sell_no = 0;
self.done_custom = self.done_custom - (self.done_custom & CUSTOM_SELLING);
}
self.real_frags = self.real_frags - sell_no;
self.frags = self.real_frags; //TODO: Make this work with TEAMFRAGS on
self.money = custom_money + sell_no * PRICE_PER_FRAG;
}
else
self.money = custom_money;
self.custom_speed = 250; //HWGUY Speed
//Overrides the menu handler to always display my menu
//Hack alert! This preserves the selling flag. :p
if (self.done_custom & CUSTOM_SELLING)
self.done_custom = CUSTOM_BUILDING | CUSTOM_SELLING;
else
self.done_custom = CUSTOM_BUILDING;
//Destroy Buildings... again. :p
DetonateAllGuns();
//And then kill all demons I own
//kill_my_demon();
//DetonateMines(self);
//RemoveArmyTimer();
self.current_menu = MENU_PRIMARY_WEAPON;
Menu_PrimaryWeapon();
return;
};
void(vector org) spawn_tfog;
void() DropFromCustomClassGen =
{
//
self.is_killed = FALSE;
//
self.summon_one = world;
self.summon_two = world;
self.done_custom = CUSTOM_FINISHED;
self.maxspeed = self.custom_speed;
self.gravity = 1;
if (self.cutf_items & CUTF_TOSSABLEDET)
self.maxammo_detpack = 1;
//Make sure they have at least one axe-like weapon
if (!(self.weapons_carried & (WEAP_MEDIKIT | WEAP_SPANNER)) || (self.cutf_items & CUTF_KNIFE))
self.weapons_carried = self.weapons_carried | WEAP_AXE;
//CH if you bought Guerilla, you get 20 rockets :)
if (self.job & JOB_GUERILLA)
self.maxammo_rockets = self.maxammo_rockets + 20;
//OfN if we got the holo we get extra cells ammo space
if (self.cutf_items & CUTF_HOLO)
self.maxammo_cells = self.maxammo_cells + 40;
//If they bought weapons, remove their basic ammo allotment
if (self.maxammo_rockets > 10)
self.maxammo_rockets = self.maxammo_rockets - 10;
if (self.maxammo_nails > 10)
self.maxammo_nails = self.maxammo_nails - 10;
if (self.maxammo_shells > 10)
self.maxammo_shells = self.maxammo_shells - 10;
if (self.maxammo_cells > 10)
self.maxammo_cells = self.maxammo_cells - 10;
//Increase their supply if they bought a backpack or bandolier
if (self.tf_items & NIT_AMMO_BACKPACK) {
self.maxammo_rockets = self.maxammo_rockets + 30;
self.maxammo_nails = self.maxammo_nails + 100;
self.maxammo_shells = self.maxammo_shells + 100;
if (self.weapons_carried & WEAP_SPANNER)
self.maxammo_cells = self.maxammo_cells + 170;
else
self.maxammo_cells = self.maxammo_cells + 50;
if (self.maxammo_medikit > 0) //Only increase their medical supplies when...
self.maxammo_medikit = self.maxammo_medikit + 70;
if (self.maxammo_detpack > 0)
self.maxammo_detpack = self.maxammo_detpack + 0.5;
}
if (self.tf_items & NIT_AMMO_BANDOLIER) {
self.maxammo_rockets = self.maxammo_rockets + 10;
self.maxammo_nails = self.maxammo_nails + 50;
self.maxammo_shells = self.maxammo_shells + 50;
self.maxammo_cells = self.maxammo_cells + 30;
if (self.maxammo_medikit > 0)
self.maxammo_medikit = self.maxammo_medikit + 50;
if (self.maxammo_detpack > 1) //Only give extra det if they bought both
self.maxammo_detpack = 2;
}
//Clean up detpack fraction
if (self.maxammo_detpack > 1 && self.maxammo_detpack < 2)
self.maxammo_detpack = 1;
if (self.cutf_items & CUTF_SENSOR) // SB
self.maxammo_cells = self.maxammo_cells + 70;
if (self.cutf_items & CUTF_DISPENSER) // SB
self.maxammo_cells = self.maxammo_cells + 100;
if (self.cutf_items & CUTF_FIELDGEN) // SB
self.maxammo_cells = self.maxammo_cells + 140;
//- OfN
if (self.weapons_carried & WEAP_LASERCANNON) self.maxammo_cells = self.maxammo_cells + 70;
if (self.weapons_carried & WEAP_SNG) self.maxammo_nails = self.maxammo_nails + 70;
//Now cap the max ammo
if (self.maxammo_rockets > 100)
self.maxammo_rockets = 100;
if (self.maxammo_nails > 350)
self.maxammo_nails = 350;
if (self.maxammo_shells > 300)
self.maxammo_shells = 300;
//- ofn
if (self.tf_items & NIT_AMMO_BANDOLIER && self.tf_items & NIT_AMMO_BACKPACK)
{
if (self.maxammo_cells > 400)
self.maxammo_cells = 400;
}
else if (self.tf_items & NIT_AMMO_BACKPACK)
{
if (self.maxammo_cells > 360) // was 400
self.maxammo_cells = 360;
}
else
{
if (self.maxammo_cells > 320) // was 400
self.maxammo_cells = 320;
}
//- OFN HERE FRONTLIN HELI BUG FIX ---//
local entity spot;
spot = SelectSpawnPoint ();
// if (self.playerclass != PC_UNDEFINED)
//spawn_tdeath (spot.origin, self);
self.observer_list = spot;
setorigin (self, spot.origin + '0 0 1');
self.angles = spot.angles;
self.fixangle = TRUE; // turn this way immediately
makevectors(self.angles);
spawn_tfog (self.origin + v_forward*20);
//------------------------------------//
//Telefrag anyone sitting on top of us
spawn_tdeath(self.origin,self);
//Remove observer-like mode
self.takedamage = DAMAGE_AIM;
//Prevent bad movetype errors, or something
if (self.classname != "player") {
RPrint("BUG BUG BUG BUG BUG BUG BUG BUG BUG\n");
RPrint("Non-player was in custom class generation!\n");
return;
}
self.movetype = MOVETYPE_WALK;
self.flags = FL_CLIENT | FL_ONGROUND;
self.waterlevel = 0;
self.air_finished = time + 12;
self.solid = SOLID_SLIDEBOX;
self.pausetime = 0;
//Remove invisibility
//setmodel (self, "progs/eyes.mdl");
//setmodel (self, "progs/player.mdl");
self.modelindex = modelindex_player;
// Stock him up
// Display the Player's Class
TeamFortress_PrintJobName(self,self.job);
// Set the weapons and ammo for the player based on class
TeamFortress_SetEquipment();
// Set the health for the player based on class
TeamFortress_SetHealth();
// Set the speed for the player based on class
TeamFortress_SetSpeed(self);
// Set the skin for the player based on class
TeamFortress_SetSkin(self);
stuffcmd(self, "v_idlescale 0\n");
stuffcmd(self, "v_cshift 0 0 0 0\n");
stuffcmd(self, "bf\n");
ResetMenu();
self.impulse = 0;
//Make them invincible if they bought respawn protection
if (self.tf_items & NIT_RESPAWN_GUARD) {
self.items = self.items & IT_INVULNERABILITY;
self.invincible_time = 1;
self.invincible_finished = time + RESPAWN_GUARD_TIME;
if (self.custom_speed > 300)
self.invincible_finished = self.invincible_finished - 1;
if (self.custom_speed > 400)
self.invincible_finished = self.invincible_finished - 1;
}
//Come again!
sprint(self,PRINT_HIGH,"Type 'custom' at the console to build a new class.\n");
//- OfN - Set army timer //
if (self.job & JOB_ARMY)
{
SetArmyTimer();
}
return;
};
void() PrintMoney =
{
if (pay_msgs != 1)
return;
local string as;
sprint(self,PRINT_HIGH,"You have ");
as = ftos(self.money);
sprint(self,PRINT_HIGH,as);
sprint(self,PRINT_HIGH," dollars left.\n");
return;
};
void(float in) PrintRefund=
{
local string as;
if (pay_msgs == 1)
{
sprint(self,PRINT_HIGH,"You sell it back for ");
as = ftos(in);
sprint(self,PRINT_HIGH,as);
sprint(self,PRINT_HIGH," dollars.\n");
}
self.money = self.money + in; //Give em a refund
if (pay_msgs == 1)
{
sprint(self,PRINT_HIGH,"You now have ");
as = ftos(self.money);
sprint(self,PRINT_HIGH,as);
sprint(self,PRINT_HIGH," dollars available.\n");
}
return;
};
void(float in) PrintNotEnoughMoney =
{
if (pay_msgs != 1)
{
sprint(self,PRINT_HIGH,"Not enough money!\n");
return;
}
local string as;
sprint(self,PRINT_HIGH,"Sorry, that costs ");
as = ftos(in);
sprint(self,PRINT_HIGH,as);
sprint(self,PRINT_HIGH," dollars.\n");
sprint(self,PRINT_HIGH,"You only have ");
as = ftos(self.money);
sprint(self,PRINT_HIGH,as);
sprint(self,PRINT_HIGH," dollars left.\n");
return;
};
//Functions for determining ammo carrying capacity
float (float item) countshells =
{
/* if (chris)
{
if (item == WEAP_SHOTGUN) return 16;
if (item == WEAP_SPANNER) return 20;
if (item == WEAP_SUPER_SHOTGUN) return 32;
if (item == WEAP_ASSAULT_CANNON) return 75;
}
else
{*/
if (item == WEAP_SHOTGUN) return 25;
if (item == WEAP_SPANNER) return 40;
if (item == WEAP_SUPER_SHOTGUN) return 50;
if (item == WEAP_ASSAULT_CANNON) return 100;
//}
return 0;
};
float (float item) countnails =
{
/*if (chris)
{
if (item == WEAP_MAUSER) return 10;
if (item == WEAP_TRANQ) return 20;
if (item == WEAP_LASER) return 10;
if (item == WEAP_NAILGUN) return 75;
if (item == WEAP_LIGHT_ASSAULT) return 100;
}
else
{*/
if (item == WEAP_MAUSER) return 30;
if (item == WEAP_TRANQ) return 30;
if (item == WEAP_LASER) return 50;
if (item == WEAP_NAILGUN) return 100;
if (item == WEAP_LIGHT_ASSAULT) return 150;
//}
return 0;
};
float (float item) countrockets =
{
/*if (chris)
{
if (item == WEAP_SPANNER) return 2;
if (item == WEAP_ROCKET_LAUNCHER) return 3;
if (item == WEAP_GRENADE_LAUNCHER) return 7;
}
else
{*/
if (item == WEAP_SPANNER) return 30;
if (item == WEAP_ROCKET_LAUNCHER) return 30;
if (item == WEAP_GRENADE_LAUNCHER) return 50;
//}
return 0;
};
float (float item) countcells =
{
/*if (chris)
{
if (item == WEAP_ASSAULT_CANNON) return 16;
if (item == WEAP_DAEDALUS) return 50;
if (item == WEAP_LIGHTNING) return 75;
if (item == WEAP_SPANNER) return 150;
}
else
{*/
if (item == WEAP_ASSAULT_CANNON) return 50;
if (item == WEAP_DAEDALUS) return 100;
if (item == WEAP_LIGHTNING) return 100;
if (item == WEAP_SPANNER) return 150;
//}
return 0;
};
void(float cost, float item) BuyWeapon =
{
if (item == 0) //Make sure we don't buy a null weapon
return;
if (self.weapons_carried & item) //We are selling
{
if (item == WEAP_ROCKET_LAUNCHER && self.tf_items & NIT_RL_LASER_SIGHT)
{
self.money = self.money + 1000;
self.tf_items = self.tf_items & ~NIT_RL_LASER_SIGHT;
}
if (item == WEAP_ROCKET_LAUNCHER && self.tf_items & NIT_CLUSTER_ROCKETS)
{
self.money = self.money + 3250;
self.tf_items = self.tf_items & ~NIT_CLUSTER_ROCKETS;
}
self.maxammo_shells = self.maxammo_shells - countshells(item);
self.maxammo_nails = self.maxammo_nails - countnails(item);
self.maxammo_rockets = self.maxammo_rockets - countrockets(item);
self.maxammo_cells = self.maxammo_cells - countcells(item);
PrintRefund(cost);
self.weapons_carried = self.weapons_carried - item;
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
//Add to max ammo
self.maxammo_shells = self.maxammo_shells + countshells(item);
self.maxammo_nails = self.maxammo_nails + countnails(item);
self.maxammo_rockets = self.maxammo_rockets + countrockets(item);
self.maxammo_cells = self.maxammo_cells + countcells(item);
self.weapons_carried = self.weapons_carried | item;
self.money = self.money - cost;
PrintMoney();
};
void(float cost, float item) BuyCuTF =
{
if (item == 0) //Make sure we don't buy a null weapon
return;
if (item == CUTF_OTR && !(self.weapons_carried & WEAP_SNIPER_RIFLE)) {
sprint(self,PRINT_HIGH,"These are special bullets for the sniper rifle, buy one first\n");
return;
}
if (self.cutf_items & item) //We are selling
{
if (item == CUTF_SENTRYGUN) {
self.maxammo_shells = self.maxammo_shells - 130;
self.maxammo_cells = self.maxammo_cells - 130;
}
PrintRefund(cost);
self.cutf_items = self.cutf_items - item;
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
//Add to max ammo if sentrygun purchase
if (item == CUTF_SENTRYGUN) {
self.maxammo_shells = self.maxammo_shells + 130;
self.maxammo_cells = self.maxammo_cells + 130;
}
self.cutf_items = self.cutf_items | item;
self.money = self.money - cost;
PrintMoney();
};
//CH gives ammo for items
void(float item) Apply_Item_Ammo =
{
local float cellsfoo,rocketsfoo;
cellsfoo = rocketsfoo = 0;
if (item == NIT_TESLA)
cellsfoo = 150;
if (item == NIT_SECURITY_CAMERA)
cellsfoo = 60;
if (item == NIT_TELEPORTER)
cellsfoo = 100;
if (item == NIT_RL_LASER_SIGHT)
rocketsfoo = 10;
if (item == NIT_CLUSTER_ROCKETS)
rocketsfoo = 20;
if (self.tf_items & item) { //we selling
self.maxammo_cells = self.maxammo_cells - cellsfoo;
self.maxammo_rockets = self.maxammo_rockets - rocketsfoo;
}
else {
self.maxammo_cells = self.maxammo_cells + cellsfoo;
self.maxammo_rockets = self.maxammo_rockets + rocketsfoo;
}
};
void(float cost, float item) BuyItem =
{
if (item == 0) //Make sure we don't buy a null item
return;
Apply_Item_Ammo(item); //CH
if (self.tf_items & item) //We are selling
{
if (item == NIT_HOVER_BOOTS && self.tf_items & NIT_HOVER_BOOTS_UPGRADE) {
// self.money = self.money + 350; //sync with buying of upgrade
// item &= ~NIT_HOVER_BOOTS_UPGRADE;
BuyItem (350, NIT_HOVER_BOOTS_UPGRADE); // sync with buying of upgrade
}
PrintRefund(cost);
self.tf_items -= item;
return;
}
//Special rules
if (item == NIT_AUTOSCANNER && !(self.tf_items & NIT_SCANNER)) {
sprint(self,PRINT_HIGH,"Sorry, you have to have the scanner first\n");
return;
}
if ((item == NIT_RL_LASER_SIGHT || item == NIT_CLUSTER_ROCKETS) && !(self.weapons_carried & WEAP_ROCKET_LAUNCHER)) {
sprint(self,PRINT_HIGH,"Sorry, you have to have the rocket launcher first\n");
return;
}
if (item == NIT_HOVER_BOOTS)
sprint(self,PRINT_HIGH,"Hold down jump to use the boots\n");
if (item == NIT_HOVER_BOOTS_UPGRADE && !(self.tf_items & NIT_HOVER_BOOTS)) {
sprint(self,PRINT_HIGH,"Sorry, you have to have the hover boots first\n");
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
self.tf_items = self.tf_items | item;
self.money = self.money - cost;
PrintMoney();
};
void(float cost, float type) BuyJob =
{
if (type == 0) //Make sure we don't buy a null grenade
return;
if (type == self.job) //We are selling
{
if (self.job & JOB_WARLOCK)
{
if (!(self.cutf_items & CUTF_DEMONLORE))
cost = cost - 300; // sync with demonlore cost
else
self.cutf_items = self.cutf_items - (self.cutf_items & CUTF_DEMONLORE);
}
if (self.job & JOB_RUNNER)
{
if (!(self.cutf_items & CUTF_HIGHJUMP))
cost = cost - 200; // sync with highjump cost
else
self.cutf_items = self.cutf_items - (self.cutf_items & CUTF_HIGHJUMP);
}
if (self.job & JOB_JUDOKA)
{
if (!(self.cutf_items & CUTF_STEALTH))
cost = cost - 400; // sync with stealth cost
else
self.cutf_items = self.cutf_items - (self.cutf_items & CUTF_STEALTH);
}
PrintRefund(cost);
self.job = 0;
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
if (self.job) { //Make sure we haven't bought another kind already
sprint(self,PRINT_HIGH,"You already have a job. Leave your other one first.\n");
return;
}
//Special rules for buying jobs
if (type == JOB_WARLOCK && !(self.cutf_items & CUTF_KNIFE)) {
sprint(self,PRINT_HIGH,"Every Warlock needs a good bloody knife. Buy one.\n");
return;
}
if (type == JOB_WARLOCK)
if (self.cutf_items & CUTF_DEMONLORE)
self.money = self.money + 300; // sync this with demonlore cost
else
self.cutf_items = self.cutf_items | CUTF_DEMONLORE; // warlocks see demon health
if (type == JOB_RUNNER)
if (self.cutf_items & CUTF_HIGHJUMP)
self.money = self.money + 200; // sync with highjump cost
else
self.cutf_items = self.cutf_items | CUTF_HIGHJUMP; // runner jumps high
if (type == JOB_JUDOKA)
if (self.cutf_items & CUTF_STEALTH)
self.money = self.money + 400; // sync with stealth price
else
self.cutf_items = self.cutf_items | CUTF_STEALTH; // Judo is a master of stealth by default
//Ok we buy it
self.job = type;
self.money = self.money - cost;
PrintMoney();
};
void (float cost, float type) BuyGren =
{
///local float level; // This is the level of legs we have.
if (type == 0) // if type is 0 we are buying the NULL GRENADE(tm)
{
sprint(self, PRINT_HIGH, "Congratulations. You have just attempted to buy a null grenade.\n");
dprint("WARNING: Attempted purchase of NULL GRENADE. BUG BUG BUG BUG BUG BUG BUG\n");
return;
}
// Check whether we're allowing gren purchase.
/*level = ReturnLegLevel(self.custom_speed);
if (level == 1) // grens are a no-no
{
sprint(self, PRINT_HIGH, "Sorry, you are not allowed any grenades at that speed. It is very dangerous.\n");
return;
}
else if (level == 2)
{
local float acc; // Acceptable.
acc = FALSE;
if (type == GR_TYPE_CALTROP)
acc = TRUE;
else if (type == GR_TYPE_CONCUSSION)
acc = TRUE;
else if (type == GR_TYPE_STASIS)
acc = TRUE;
else if (type == GR_TYPE_ANTIGRAV)
acc = TRUE;
else if (type == GR_TYPE_FLARE)
acc = TRUE;
if (!acc)
{
sprint(self, PRINT_HIGH, "Sorry, using those grenades at your speed could be dangerous.\n");
return;
}
}
else if (level == 3)
{
if (type == GR_TYPE_MIRV)
{
sprint(self, PRINT_HIGH, "Sorry, you aren't allowed MIRVs at that speed.\n");
return;
}
}*/
// Grenade and speed is fine.
if (!self.tp_grenades_1 && cost <= self.money) // if we don't have gren1s, make it a gren1
{
/* if (self.money_misc + cost > self.money_spent - self.money_misc)
{
PrintTooHighProportion();
return;
} */
self.tp_grenades_1 = type;
//sprint(self, PRINT_HIGH, "You buy the grenades and add them to your first grenade slot for ");
}
else if (!self.tp_grenades_2 && cost <= self.money) // We already have gren1s, can we buy gren2s?
{
/*if (self.money_misc + cost > self.money_spent - self.money_misc)
{
PrintTooHighProportion();
return;
}*/
self.tp_grenades_2 = type;
//sprint(self, PRINT_HIGH, "You buy the grenades and add them to your second grenade slot for ");
}
else // We have both gren1s and gren2s so now we need to try to sell some
{ // If our type matches gren1 AND gren2s we want to sell both
if (self.tp_grenades_1 == type && self.tp_grenades_2 == type)
{
PrintRefund(cost * 2);
//self.money_misc = self.money_misc - cost * 2;
//self.money = self.money + cost * 2; //*2
self.tp_grenades_1 = 0;
self.tp_grenades_2 = 0;
}
else if (self.tp_grenades_1 == type) // otherwise if our gren1s are the type
{
PrintRefund(cost);
//self.money_misc = self.money_misc - cost;
//self.money = self.money + cost;
self.tp_grenades_1 = 0;
}
else if (self.tp_grenades_2 == type) // otherwise if we have gren2s as the type..
{
PrintRefund(cost);
//self.money_misc = self.money_misc - cost;
//self.money = self.money + cost;
self.tp_grenades_2 = 0;
}
else if (cost <= self.money)
sprint(self,PRINT_HIGH,"You already have a full set of grenades. Sell some back first.\n");
else
PrintNotEnoughMoney(cost);
return;
}
self.money = self.money - cost;
//self.money_misc = self.money_misc + cost;
//self.money_spent = self.money_spent + cost;
/*talk = ftos(cost);
sprint(self, PRINT_HIGH, talk);
sprint(self, PRINT_HIGH, " dollars. You have ");
talk = ftos(self.money);
sprint(self, PRINT_HIGH, talk);
sprint(self, PRINT_HIGH, " dollars left.\n");*/
};
/*
void(float cost, float type) BuyGren1 =
{
if (type == 0) //Make sure we don't buy a null grenade
return;
if (type == self.tp_grenades_1) //We are selling
{
PrintRefund(cost);
self.tp_grenades_1 = 0;
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
if (self.tp_grenades_1) { //Make sure we haven't bought another kind already
sprint(self,PRINT_HIGH,"You already have grenades. Sell back the ones you bought first.\n");
return;
}
//Ok we buy it
self.tp_grenades_1 = type;
self.money = self.money - cost;
PrintMoney();
};
void(float cost, float type) BuyGren2 =
{
if (type == 0) //Make sure we don't buy a null grenade
return;
if (type == self.tp_grenades_2) //We are selling
{
PrintRefund(cost);
self.tp_grenades_2 = 0;
return;
}
if (cost > self.money)
{
PrintNotEnoughMoney(cost);
return;
}
if (self.tp_grenades_2) { //Make sure we haven't bought another kind already
sprint(self,PRINT_HIGH,"You already have grenades. Sell back the ones you bought first.\n");
return;
}
//Ok we buy it
self.tp_grenades_2 = type;
self.money = self.money - cost;
PrintMoney();
};
*/
//Functions for our new grenades
void() fragspike_touch =
{
//if (pointcontents(self.origin) == CONTENTS_SKY)
if (pointcontents(self.origin) != CONTENTS_EMPTY)
{
dremove(self);
return;
}
// hit something that bleeds
if (other.takedamage)
{
deathmsg = DMSG_GREN_FRAG;
TF_T_Damage (other, self, self.real_owner, 150, TF_TD_NOTTEAM, TF_TD_NAIL);
dremove(self);
}
else
{
//We bounce off world since we are fragments
if (self.heat > 0) {
// self.heat = self.heat - 1;
// if (self.velocity = '0 0 0') { //Skip around
if (1) { //Skip around
self.velocity_x = (random() - 0.5) * 200;
self.velocity_y = (random() - 0.5) * 200;
self.velocity_z = random() * 200;
}
}
else {
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
else
{
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_SUPERSPIKE);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast (self.origin, MULTICAST_PHS);
}
dremove(self);
}
}
};
void() FragSpikeThink =
{
if (self.heat > 0) {
self.heat = self.heat - 1;
self.angles_y = random() * 360;
self.angles_x = 0;
self.angles_z = 0;
makevectors(self.angles);
if (self.velocity = '0 0 0')
self.origin_z = self.origin_z + 50;
self.velocity = v_forward * 1000;
self.velocity_z = (random() + 0.25) * 1000;
self.nextthink = time + 0.5 + random();
}
else {
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_SUPERSPIKE);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast (self.origin, MULTICAST_PHS);
dremove(self);
}
};
void() FragGrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
// Thrown grenades don't detonate when hitting an enemy
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
void() FragGrenadeExplode =
{
local float shraps;
local entity newmis;
//Small explosive radius
deathmsg = DMSG_GREN_HAND;
T_RadiusDamage (self, self.owner, 80, world);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast (self.origin, MULTICAST_PHS);
shraps = rint(6 * random()) + 6; //Pieces of shrapmetal;
while (shraps > 0) {
self.angles_y = random() * 360;
self.angles_x = 0;
self.angles_z = 0;
makevectors(self.angles);
deathmsg = DMSG_GREN_NAIL;
newmis = spawn ();
//WK Make shraps hit owner newmis.owner = self.owner;
newmis.real_owner = self.owner;
newmis.movetype = MOVETYPE_BOUNCE;
newmis.solid = SOLID_BBOX;
newmis.angles = '0 0 0';
newmis.classname = "spike";
newmis.think = FragSpikeThink;
// newmis.think = SUB_Remove;
newmis.nextthink = time + 1;
setmodel (newmis, "progs/spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
setorigin (newmis, self.origin);
//Start it over the ground
newmis.origin_z = newmis.origin_z + 10;
newmis.velocity = v_forward * 1000;
if (random() < 0.5)
newmis.velocity_z = 20;
else
newmis.velocity_z = random() * 1000;
newmis.avelocity = '100 100 100';
newmis.touch = fragspike_touch;
newmis.weapon = DMSG_GREN_NAIL;
//Make it bounce six times.
newmis.heat = 5;
shraps = shraps - 1;
}
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast (self.origin, MULTICAST_PHS);
dremove(self);
};
void() KracGrenadeTouch =
{
//WK Have it detonate on impact
if (other == self.owner)
return; // don't explode on owner
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
KracGrenadeExplode();
};
void() KracGrenadeExplode =
{
local entity te;
local entity oldself;
te = findradius(self.origin, 150);
while (te)
{
// Player?
if (te.classname == "player")
{
//WW: Kracs disable detpack
oldself = self;
self = te;
TeamFortress_DetpackStop(TRUE);
self = oldself;
//Gel armor makes kracs do less damage
if (te.armorclass & AT_SAVEMELEE) {
if (te.armorvalue > 75)
te.armorvalue = 75;
} else {
if (te.armorvalue > 10)
te.armorvalue = 10;
}
te.ammo_cells = 0; //Kill their metal supply too
}
else if (te.classname == "pipebomb")
te.nextthink = time + 0.1 + random();
else if (te.classname == "grenade" && te.netname == "land_mine")
{
te.think = GuerillaExplode;
te.nextthink = time + 0.1;
}
else if (te.classname == "building_sentrygun")
TF_T_Damage(te, self, self.owner, 200, 0, 0);
else if (te.classname == "building_tesla")
TF_T_Damage(te, self, self.owner, 200, 0, 0);
else if (te.classname == "building_dispenser")
TF_T_Damage(te, self, self.owner, 500, 0, 0);
else if (te.classname == "building_camera")
TF_T_Damage(te, self, self.owner, 400, 0, 0);
else if (te.classname == "building_teleporter")
TF_T_Damage(te, self, self.owner, 200, 0, 0);
else if (te.classname == "building_sensor") //- Often - needed?
TF_T_Damage(te, self, self.owner, 200, 0, 0);
else if (te.classname == "item_armor1" || te.classname == "item_armor2" || te.classname == "item_armorInv") {
te.solid = SOLID_NOT;
te.model = "";
te.nextthink = time + 45; //WK 20
te.think = SUB_regen;
//SUB_UseTargets();
}
else if (te.classname == "detpack") {
if (te.owner.netname != self.owner.netname) {
bprint (PRINT_MEDIUM, te.owner.netname);
bprint (PRINT_MEDIUM, "'s detpack was Kraced by ");
bprint (PRINT_MEDIUM, self.owner.netname);
bprint (PRINT_MEDIUM, "\n");
} else {
sprint (te.owner, PRINT_MEDIUM, "You Kraced your own detpack!\n");
}
// This code handles disarming a detpack
if (te.weaponmode == 1) // Detpack was being disarmed
{
te.enemy.tfstate = te.enemy.tfstate - (te.enemy.tfstate & TFSTATE_CANT_MOVE);
TeamFortress_SetSpeed(te.enemy);
dremove(te.oldenemy); // CountDown
dremove(te.observer_list); // Disarm timer
}
else { //Not being disarmed
dremove(te.oldenemy); // CountDown
}
te.think = BecomeExplosion;
te.nextthink = time + 0.1;
}
te = te.chain;
}
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
WriteCoord (MSG_MULTICAST, self.origin_x);
WriteCoord (MSG_MULTICAST, self.origin_y);
WriteCoord (MSG_MULTICAST, self.origin_z);
multicast (self.origin, MULTICAST_PHS);
dremove(self);
};
//Stops us from lowering the time immunity
void(entity immuner,float timeimmune) makeImmune =
{
if (immuner == world) return;
if (immuner.immune_to_chec > timeimmune) return;
immuner.immune_to_chec = timeimmune;
};
void() BastardTimer =
{
local entity te;
local float tc, tc2;
te = self.owner;
//makeImmune(te,time+5);
if (te.penance_time < time)
{
stuffcmd(te, "cl_yawspeed 140;-right;-left\n");
//stuffcmd(te, "name \"");
//stuffcmd(te, te.old_netname);
//stuffcmd(te, "\"\n");
// Reset their color
tc = TeamGetColor (te.team_no) - 1;
tc2 = TeamGetNiceColor (te.team_no);
SetPlayerColor (te, tc, tc2);
bprint (PRINT_MEDIUM, te.netname);
bprint (PRINT_MEDIUM, " has his teamkill curse removed\n");
//Don't let up on them. Two more teamkills and its back into the tarpit for them
te.ff_count = self.frags - 1.9;
if (te.ff_count < 0) te.ff_count = 0;
TF_T_Damage(te, world, world, te.health + 300, TF_TD_IGNOREARMOUR, TF_TD_OTHER);
remove(self);
return;
}
if (random() > 0.5)
{
stuffcmd(te, "cl_yawspeed 500;-left;+right\n");
SetPlayerColor (te, 8, 8);
}
else
{
stuffcmd(te, "cl_yawspeed 500;-right;+left\n");
SetPlayerColor (te, 9, 9);
}
//te.immune_to_check = time + 5;
te.ammo_rockets = 0;
te.ammo_cells = 0;
te.ammo_nails = 0;
te.ammo_shells = 0;
te.ammo_detpack = 0;
te.ammo_c4det = 0;
te.no_grenades_1 = 0;
te.no_grenades_2 = 0;
if (te.health > 50) te.health = 50;
if (te.armorvalue > 10) te.armorvalue = 10;
self.nextthink = time + 2;
};
void(entity bastard,float threshold) createBastard =
{
local entity te;
if (bastard == world) return;
if (bastard.penance_time > time) {
bastard.ff_count = bastard.ff_count - 1; //Dont count it
bastard.penance_time = time + 60; //Just reset the clock
makeImmune(bastard,time+65);
return;
}
//---------------------------------------------------------------------------//
// Why do I not like MegaTF? ------------------------------------------------//
// Look at http://www.planetfortress.com/history/people/shaka.html ----------//
if (bastard.ff_count == threshold + 0.1 || bastard.ff_count == threshold + 0.6) {
//- OfN - lol
//bprint(PRINT_HIGH,"<22><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>M\n");
bprint(PRINT_HIGH,"ok, lets send ");
bprint(PRINT_HIGH,bastard.netname);
bprint(PRINT_HIGH," to a nice megaTF server...\n");
stuffcmd(bastard, "name \"CustomTF reject-wanna play Mega\"\n");
//stuffcmd(bastard, "name \"im gay, wanna make new friends\"\n");
local string st;
st = infokey(world,"curseserver");
//if (!st) st = "207.171.0.74";
if (!st) st = "209.39.192.74:27500";
stuffcmd(bastard, "connect ");
stuffcmd(bastard, st);
stuffcmd(bastard, "\n");
return; //- OfN - (missing) OLD BUG?
} //---------------------------------------------------------------------------//
newmis = spawn();
newmis.classname = "timer";
newmis.netname = "bastardtimer";
newmis.owner = bastard;
newmis.think = BastardTimer;
newmis.nextthink = time + 1;
newmis.frags = threshold; //Let the timer know what the thresh is
makeImmune(bastard,time+65);
//bastard.immune_to_check = time + 65; //Make him immune while purple
//bastard.old_netname = bastard.netname;
bprint (PRINT_MEDIUM, bastard.netname);
bprint (PRINT_MEDIUM, " has been struck down by the wrath of the admin.\n");
bprint (PRINT_MEDIUM, "Feel free to frag him at will.\n");
bastard.penance_time = time + 60;
stuffcmd(bastard, "name \"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (");
// stuffcmd(bartard, "name \"\<TeamKiller\> (");
stuffcmd(bastard, bastard.netname);
stuffcmd(bastard, ")\"\n");
// Drop any GoalItems
te = find (world, classname, "item_tfgoal");
while (te)
{
if (te.owner == bastard)
{
// Remove it from the player, if it is supposed to be
if (!(te.goal_activation & TFGI_KEEP))
{
tfgoalitem_RemoveFromPlayer(te, bastard, 0);
}
// CTF support
if (CTF_Map == TRUE && te.goal_no == CTF_FLAG1)
{
bprint(PRINT_HIGH, bastard.netname);
bprint(PRINT_HIGH, " <20><><EFBFBD><EFBFBD> the <20><><EFBFBD><EFBFBD> flag!\n");
}
else if (CTF_Map == TRUE && te.goal_no == CTF_FLAG2)
{
bprint(PRINT_HIGH, bastard.netname);
bprint(PRINT_HIGH, " <20><><EFBFBD><EFBFBD> the <20><><EFBFBD> flag!\n");
}
}
te = find(te, classname, "item_tfgoal");
}
return;
};
void() Autoitem_think =
{
local entity oself;
local float happy;
if (self.heat == TRUE)
self.heat = FALSE;
else
self.heat = TRUE;
happy = self.heat;
oself = self;
self = self.owner;
if (self.tf_items & NIT_AUTOID) {
//Do an id
TeamFortress_ID(TRUE); //TRUE means we are in autoitemthink
}
if (self.weapons_carried & WEAP_MEDIKIT) {
//Do a heal, passing it TRUE tells it not to "tink"
//Don't automedic whack while fully invisible
if (!(self.job & JOB_THIEF && (self.job & JOB_ACTIVE || self.job & JOB_FULL_HIDE)))
W_FireMedikit(TRUE);
}
if (happy) { //Only do this every two seconds
if (self.tf_items & NIT_AUTOSCANNER) {
//Do a scan15
TeamFortress_Scan(15,TRUE);
}
}
self = oself;
self.nextthink = time + 0.5;
};
void() custom_lay =
{
if (self.last_saveme_sound < time) {
bprint(PRINT_HIGH,self.netname);
bprint(PRINT_HIGH,"'s legs were broken when he tried to 'lay'\n");
sound(self,CHAN_VOICE,"player/pain1.wav",1,ATTN_NONE);
self.last_saveme_sound = time + 60;
}
self.suicide_time = time + 60;
self.leg_damage = 9;
TeamFortress_SetSpeed(self);
if (self.health > 50) self.health = 50;
if (self.armorvalue > 10) self.armorvalue = 10;
};
//Blow up all sentries, dispensers and teslas if we can no longer build them
void() DetonateAllGuns =
{
if (!(self.cutf_items & CUTF_DISPENSER))
Find_And_Dmg("building_dispenser", self, 1);
if (!(self.cutf_items & CUTF_SENTRYGUN))
Find_And_Dmg("building_sentrygun", self, 1);
if (!(self.tf_items & NIT_TESLA)) //WK
Find_And_Dmg("building_tesla", self, 1);
if (!(self.tf_items & NIT_SECURITY_CAMERA)) //CH
Find_And_Dmg("building_camera", self, 1);
if (!(self.tf_items & NIT_TELEPORTER)) //CH
Find_And_Dmg("building_teleporter", self, 1);
if (!(self.cutf_items & CUTF_SENSOR)) //SB
Find_And_Dmg("building_sensor", self, 1);
if (!(self.cutf_items & CUTF_FIELDGEN)) //OfN
Find_And_Dmg("building_fieldgen", self, 1);
};
//Blow up all sentries, dispensers and teslas if we can no longer build them
void() DetonateAllGunsForced =
{
Find_And_Dmg("building_dispenser", self, 1);
Find_And_Dmg("building_sentrygun", self, 1);
Find_And_Dmg("building_tesla", self, 1);
Find_And_Dmg("building_camera", self, 1);
Find_And_Dmg("building_teleporter", self, 1);
Find_And_Dmg("building_sensor", self, 1);
Find_And_Dmg("building_fieldgen", self, 1);
};
//Returns true if the entity is a building -- UPDATE THIS WHEN A NEW ONE IS ADDED
float(entity tester) IsBuilding =
{
if (
tester.classname == "building_sentrygun" ||
tester.classname == "building_sentrygun_base" ||
tester.classname == "building_tesla" ||
tester.classname == "building_dispenser" ||
tester.classname == "building_camera" ||
tester.classname == "building_arawana" ||
tester.classname == "building_teleporter"||
tester.classname == "building_fieldgen"||
tester.classname == "building_sensor"
)
return TRUE;
return FALSE;
};