rendered paste body/*
=============
XavioR's Q3F/ETF Entity recognition
==============
*/
// q3f_forts seems to work almost perfectly --
//any other map will probably need a small to large amount of entity editing;
//still, this code does do a lot of work for you so give it a look :)
.string groupname;
.float ammo_charge; // there's no real use for this in mega, but it helps with the parsing..
float TRUE = 1;
string(string s, float start, float length) substring = #116; // returns a section of a string as a tempstring
float FALSE = 0;
// The following are just there to bring down the "not a field" errors
.string allowclasses;
.string activetarget;
.string failtarget;
.string active_message;
.string clientstats;
.string carried_all_message;
.string carried_team_sound;
.string carried_all_message;
.string inactive_all_sound;
.string inactive_all_message;
.string inactive_team_sound;
.string inactive_flaginfo;
.string inactive_shader;
.string inactivetarget;
.string active_message;
.string active_sound;
.string active_nonteam_sound;
.string active_team_sound;
.string watch;
.string watchrange;
.string checkstate;
.string victimholding;
.string notholding;
.string width;
.string victimallowteams;
.string slot;
.string sparkle;
.string carriedtarget;
.string inactive_model;
.string initialstate;
.string initialvalue;
.string mapcoordsmins;
.string mapcoordsmaxs;
.string target_1;
.string target_2;
.string target_3;
.string target_4;
.string target_5;
.string radius;
.string give;
.string active_all_sound;
.string carried_message;
.string active_all_message;
.string carried_sound;
.string holding;
.string team_owner;
.float gameindex;
.float teamscore;
.vector orig_origin;
float RED_GOAL = 200;
float BLUE_GOAL = 100;
float ANY_GOAL = 50;
string(string s) strzone = #118;
// Parse the sounds correctly (only applies for QW?)
void () ParseSounds =
{
strzone(self.active_all_sound);
self.active_all_sound = strzone(substring(self.active_all_sound, 7, -1));
strzone(self.carried_sound);
self.carried_sound = strzone(substring(self.carried_sound, 7, -1));
};
// Parse ETF/Q3F's "give" property (substrings ftw!)
.float stleng;
float (string give_string, float st_len1, float st_len2) grabval =
{
local float posneg;
// local float maxstl;
local string st;
posneg = 1;
st = substring(give_string, st_len1, 1);
if (st == "-")
posneg = -1;
st = substring(give_string, st_len1 + st_len2 - 1, 1);
if (st == ",")
// self.stleng = 2;
self.stleng = st_len2 - 2;
else
// self.stleng = 3;
self.stleng = st_len2 - 1;
st = substring(give_string, st_len1 + 1, self.stleng);
return(stof(st) * posneg);
};
void () ParseGive =
{
local string give_string;
local string st;
local string chargeorcell;
local float st_len;
local float en_len;
st_len = 0;
en_len = 5;
give_string = self.give;
st = substring(give_string, st_len, 6);
while (st != "")
{
if (st == "health" )
{
st_len = st_len + 7;
self.health = grabval (give_string, st_len, 4);
}
else if (st == "armor=" )
{
st_len = st_len + 6;
self.armorvalue = grabval (give_string, st_len, 4);
}
else if (st == "ammo_s" )
{
st_len = st_len + 12;
self.ammo_shells = grabval (give_string, st_len, 4);
}
else if (st == "ammo_b" )
{
st_len = st_len + 13;
self.ammo_shells = grabval (give_string, st_len, 4);
}
else if (st == "ammo_c" )
{
chargeorcell = substring(give_string, st_len, 7);
// bprint(2,chargeorcell);
// bprint(2,"\n");
if (chargeorcell == "ammo_ch" ) // if it's ammo_charge, we really dont care much
{
st_len = st_len + 12;
self.ammo_charge = self.ammo_charge = grabval (give_string, st_len, 3);
}
else
{
st_len = st_len + 11;
self.ammo_cells = grabval (give_string, st_len, 4);
}
}
else if (st == "ammo_r" )
{
st_len = st_len + 13;
self.ammo_rockets = grabval (give_string, st_len, 4);
}
else if (st == "ammo_n" )
{
st_len = st_len + 11;
self.ammo_nails = grabval (give_string, st_len, 4);
}
else if (st == "ammo_m" )
{
st_len = st_len + 13;
self.ammo_medikit = grabval (give_string, st_len, 4);
}
else if (st == "score=" )
{
st_len = st_len + 6;
self.frags = grabval (give_string, st_len, 3);
}
else if (st == "gren1=" )
{
st_len = st_len + 6;
self.no_grenades_1 = grabval (give_string, st_len, 3);
}
else if (st == "gren2=" )
{
st_len = st_len + 6;
self.no_grenades_2 = grabval (give_string, st_len, 3);
}
st_len = st_len + self.stleng + 2;
st = substring(give_string, st_len, 6);
}
};
// Q3F/ETF Maps dont have info_tfdetects, so this calls it.
void () DoTFDetect =
{
if (q3fdetect == 1)
return;
self.display_item_status1 = 1;
self.n_s_c = "ÅÎÅÍÙ flag: carried by";
self.display_item_status2 = 2;
self.impulse = 64;
//self.classname = "info_tfdetect";
self.b_n = "\n";
self.t_s_h = "ÙÏÕÒ flag: base.";
//self.origin = '-80 -60 108';
self.t_s_c = "ÙÏÕÒ flag: carried by";
self.n_s_h = "ÅÎÅÍÙ flag: base.";
self.b_t = "Amnesia\nžŸ CHOOSE YOUR TEAM žŸ\n\n..… BLUE TEAM\n..… ÒÅÄ TEAM \n\n—.… AUTO TEAM\n";
self.b_b = "TeamFortress";
self.n_s_m = "ÅÎÅÍÙ flag: down.";
self.t_s_m = "ÙÏÕÒ flag: down.";
q3fdetect = 1;
info_tfdetect();
};
void () PossiblyDoTFDetect =
{
if (q3fdetect != 1)
{
newmis = spawn();
newmis.classname = "info_tfdetect";
newmis.nextthink = time;
newmis.think = DoTFDetect;
}
}
// Converts item to FLAG
void (float tno) ConvertToFlag =
{
PossiblyDoTFDetect();
ParseSounds();
local string droppedmsg;
if (self.allowteams == "red")
{
// if (redflagexists == 1)
// return;
self.team_no = 2;
self.owned_by = 1;
if (!self.n_b)
self.n_b = " took the Blue Æìáç!\n";
droppedmsg = " Dropped the Blue flag\n";
self.netname = "Blue Flag";
redflagexists = 1;
if (!self.goal_no)
self.goal_no = RED_GOAL; // Temp Goal Number, can be overridden by a "goal" def in the entity
number_of_teams = 2; //temp?
}
if (self.allowteams == "blue")
{
// if (blueflagexists == 1)
// return;
self.team_no = 1;
self.owned_by = 2;
if (!self.n_b)
self.n_b = " took the Red Æìáç!\n";
droppedmsg = " Dropped the Red flag\n";
self.netname = "Red Flag";
blueflagexists = 1;
if (!self.goal_no)
self.goal_no = BLUE_GOAL; // Temp Goal Number, can be overridden by a "goal" def in the entity
}
if (self.allowteams == "all" || tno == 0)
{
self.owned_by = 0;
self.goal_no = ANY_GOAL;
}
self.classname = "item_tfgoal";
if (self.carried_message)
{
// self.message = ReplaceString(self.carried_message, "^*", "");
// self.message = strzone(ReplaceString(self.message, "~You", "You"));
self.message = self.carried_message;
// bprint(2,strcat(self.message,"\n"));
}
self.d_t = "the ÅÎÅÍÙ ìïóô your flag!\n"; // The enemy stole your flag msg
self.b_o = "Your flag has been stolen!\n";
self.noise = self.carried_sound;
// self.noise3 = self.inactive_all_message;
self.noise3 = "Your flag has returned to base!\n";
// self.noise4 = self.inactive_all_message;
self.noise4 = "The enemy flag has returned to base!\n";
// self.impulse = 9;
self.items = 133701;
if (self.model)
self.mdl = self.model;
// self.mdl = "models/flag.md3";
if (!self.delay)
self.delay = self.wait;
self.d_n_n = droppedmsg;
self.d_n_t = droppedmsg;
self.g_a = 2741;
self.g_e = 17;
item_tfgoal();
};
// This is the function that will convert an item to a backpack
//(happens with any item that has a "give" value).
void () ConvertToBackPack =
{
PossiblyDoTFDetect();
self.active_all_sound = substring(self.active_all_sound, 6, -1);
// ParseGive();
if (self.give == "")
return;
// self.classname = "i_t_g";
if (self.allowteams == "red")
{
self.team_no = 2;
self.owned_by = 2;
}
if (self.allowteams == "blue")
{
self.team_no = 1;
self.owned_by = 1;
}
self.message = "Resupplied!\n";
if (self.carried_message != "")
self.message = self.carried_message;
if (self.active_all_message != "")
self.message = self.active_all_message;
self.mdl = self.model;
self.noise = self.active_all_sound;
self.g_e = 1;
self.g_a = 1;
self.flags = self.flags & FL_ITEM & FL_WEAPON; // makes it turn around -- much more bandwidth efficient
/* self.orig_origin = self.origin; // old pack float code
newmis = spawn(); // thx savagex for making me aware of cl_itembobheight
newmis.floating = -17;
newmis.owner = self;
newmis.think = PackFloat;
newmis.nextthink = (time + 1.000000);*/
// If no ammo amount is specified in the entity, it will default to these values.
// The reason for this is because q3f/etf uses "give" commands to add ammo, and I can't
//convert those easily :(
if (!(self.ammo_nails || self.ammo_cells || self.ammo_rockets || self.health || self.no_grenades_1))
{
self.health = 50;
self.ammo_shells = 20;
self.ammo_nails = 100;
self.ammo_rockets = 15;
self.a_c = 25;
self.armorvalue = 100;
self.armorclass = 3;
self.armortype = 3;
self.no_grenades_1 = 2;
self.no_grenades_2 = 1;
}
i_t_g ();
};
// Converts Q3F/ETF Team Spawn points to tf-recognized ones.
/*void () info_player_start =
{
if (self.allowteams == "blue")
self.team_no = 1;
if (self.allowteams == "red")
self.team_no = 2;
i_p_t();
};*/
void() info_notnull =
{
if (self.give != "")
{
ConvertToBackPack ();
}
if (self.groupname == "anyflag")
ConvertToFlag(0);
if (self.groupname == "blueflag")
ConvertToFlag(1);
if (self.groupname == "redflag")
ConvertToFlag(2);
};
void() func_goalinfo =
{
if (self.give != "")
{
ConvertToBackPack ();
}
if (self.groupname == "anyflag")
ConvertToFlag(0);
if (self.groupname == "blueflag")
ConvertToFlag(1);
if (self.groupname == "redflag")
ConvertToFlag(2);
};
void() func_goalitem =
{
if (self.give != "")
{
ConvertToBackPack ();
}
if (self.groupname == "anyflag" && self.gameindex != 3) {
ConvertToFlag(0);
}
if (self.groupname == "blueflag" && self.gameindex != 3 || self.groupname == "blueflag,flag" && self.gameindex != 3) {
ConvertToFlag(1);
}
if (self.groupname == "redflag" && self.gameindex != 3 || self.groupname == "redflag,flag" && self.gameindex != 3) {
ConvertToFlag(2);
}
};
// Converts trigger_multiples to Flag Goals (the point(s) where the flag is capped).
//This works for q3f_forts and machse and a couple other ones.
void(float tno) ConvertToGoal =
{
if (!self.holding)
return;
if (self.gameindex == 3) // gameindex 3 goals are where the flags are located
return;
ParseSounds();
if (tno == 1)
{
self.team_no = 2;
self.axhitme = 200;
self.items_allowed = 200;
}
if (tno == 2)
{
self.team_no = 1;
self.axhitme = 100;
self.items_allowed = 100;
}
if (tno == 0)
{
self.axhitme = ANY_GOAL;
self.items_allowed = ANY_GOAL;
if (self.team_owner == "blue" || self.owned_by == 1)
self.team_no = 1;
else if (self.team_owner == "red" || self.owned_by == 2)
self.team_no = 2;
}
self.is_converted_goal = "yes"; // used with spawn point finder, no connnection with the actual conversion
self.goal_result = 2;
self.noise = self.active_all_sound;
self.frags = self.teamscore;
self.count = self.teamscore;
self.classname = "i_t_g";
self.g_a = 1;
self.g_e = 3;
// ParseGive();
i_t_g();
};
float() CheckIfQ3FTrigger = // Handles trigger_multiples from Q3F/ETF -- called from trigger_multiple
{
if (self.holding == "blueflag") {
ConvertToGoal (1);return 1; }
if (self.holding == "redflag") {
ConvertToGoal (2);return 1; }
if (self.holding == "anyflag") {
ConvertToGoal (0);return 1; }
if (self.holding == "oneflag" && self.allowteams == "blue") {
ConvertToGoal (1);return 1; }
if (self.holding == "oneflag" && self.allowteams == "red") {
ConvertToGoal (2);return 1; }
else
return 0;
};
// func_hud is not valid in Team:Nexuiz (dont know if it will ever be)
void () func_hud =
{
dremove(self);
};
void () target_location =
{
dremove(self);
};
/*void () target_speaker =
{
dremove(self);
};*/
void () target_respawn =
{
dremove(self);
};
void () misc_onkill =
{
dremove(self);
};
void () misc_flare =
{
dremove(self);
};
void () panel_scoresummary =
{
dremove(self);
};
void () info_player_intermission =
{
self.classname = "info_player_intermission";
if (!self.angles)
self.angles_y = self.angles_y - 90;
};
void() speaker_sound =
{
// sound(self, TF_FLARE_OFF, self.noise, TF_FLARE_OFF, TF_FLARE_OFF);
// sound(self, 2, self.noise, TRUE, FALSE);
local vector o;
o = ((self.mins + self.maxs) * 0.5);
ambientsound (o,self.noise, 0.5, 3);
self.nextthink = time + 1;
};
void () speaker_think =
{
// ambientsound (self.origin, self.noise, self.volume, 1.000000);
sound (self, 1, self.noise, 1, 1);
self.nextthink = time + 1.5;
};
void () target_speaker =
{
if (infokey(world,"etf_ambience") != "on")
dremove(self);
if ((CheckExistence () == 0.000000))
{
dremove (self);
return;
}
strzone(self.noise);
self.noise = strzone(substring(self.noise, 6, -1));
if (!self.volume)
{
self.volume = 1.000000;
}
precache_sound (self.noise);
// ambientsound (self.origin, self.noise, self.volume, 1.000000);
sound (self, 1, self.noise, 1, 1);
self.think = speaker_think;
self.nextthink = time + 2;
};
// XavioR's QuakeC String Tools
// Copyright Team:Nexuiz (2006)
float(string s) strlen;/* = #114;*/ // returns how many characters are in a string
float (string st, string findme) SearchString =
{
local float stleng; // string length
local float stpos; // start part of the string to check
local string srcstr; // search string
stleng = strlen(findme);
stpos = 0;
srcstr = substring(st, stpos, stleng);
while (srcstr != "")
{
srcstr = substring(st, stpos, stleng);
if (srcstr == findme)
return (stpos);
else
stpos = stpos + 1;
}
return (-1); // -1 being "NOT FOUND"
};
// Returns the value of a string after the "=" of properties such as "health" or "ammo_cells" etc
float (string st, string valueof, float stpos) ValueString =
{
local float posneg; // is it positive or negative
local float stleng; // string length
local float stpos2;
local string fdigit; // finds the digits
local string totalstring; // total value
stleng = strlen(valueof);
stpos2 = stpos + stleng + 1; // this puts us at "property="
fdigit = substring(st, stpos2, 1); // now we look for a "+" or a "-" (IE health=+2 etc)
if (fdigit = "-")
posneg = -1;
else
posneg = 1;
stpos2 = stpos2 + 1; // this puts us at "property=+" or "property=-"
fdigit = substring(st, stpos2, 1); // find the first digit..
while (fdigit != "" || fdigit != ",")
{
totalstring = strcat(totalstring, fdigit); //combine the digits..
stpos2 = stpos2 + 1;
fdigit = substring(st, stpos2, 1);
if (fdigit == "" || fdigit == ",")
return (stof(totalstring) * posneg);
}
return (stof(totalstring) * posneg);
};
// Replace String - Replaces a part of a string value
string (string st, string findme, string replacewith) ReplaceString =
{
local float stleng; // string length
local float stpos; // starting position of the string to replace
local string st1; // first half of the string
local string st2; // last half of the string
local string resultstring; // result of the combination
stleng = strlen(findme); // find the length of the string
stpos = SearchString(st, findme); // find where the string begins
if (stpos == -1)
{
bprint(2,strcat("Warning: Value not found in string: ",findme,"\n"));
return (st);
}
bprint(2,strcat(ftos(stpos),"\n"));
st1 = substring(st, 0, stpos);
st2 = substring(st, stpos + stleng, -1);
resultstring = strcat(st1, replacewith, st2);
bprint(2,strcat(resultstring,"\n"));
return(resultstring);
};
// Check if this entity harms the player
float () CheckIfKiller =
{
// ParseGive();
local float p;
// p = SearchString(self.give, "health");
// self.health = ValueString(self.give,"health",p);
if (SearchString(self.give, "health=-") >= 0)
{
self.classname = "trigger_hurt";
self.goal_effects = 1;
self.goal_activation = 1;
self.deathtype = strzone(strcat(substring(self.active_all_message,2,-1),"\n"));
// self.dmg = self.health * -1;
trigger_hurt();
return 1;
}
else
{
return 0;
}
};