/* ============= 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; } };