From 065e2edffee8fc5869a5b65f1129b632f461085c Mon Sep 17 00:00:00 2001 From: Aaron Dean <8dino2@gmail.com> Date: Tue, 5 Sep 2023 13:37:00 -0400 Subject: [PATCH] I think scope creep has set in, re-branching from here --- actionlite/CMakeLists.txt | 12 +- actionlite/a_game.cpp | 1108 ------------ actionlite/a_game.h | 60 - actionlite/a_match.cpp | 608 ------- actionlite/a_match.h | 17 - actionlite/a_radio.cpp | 817 --------- actionlite/a_radio.h | 55 - actionlite/a_team.cpp | 3064 ---------------------------------- actionlite/a_team.h | 112 -- actionlite/bg_local.h | 34 +- actionlite/cgf_sfx_glass.cpp | 741 -------- actionlite/cgf_sfx_glass.h | 83 - actionlite/ctf/g_ctf.cpp | 45 +- actionlite/ctf/g_ctf.h | 44 + actionlite/g_cmds.cpp | 85 + actionlite/g_local.h | 39 +- actionlite/g_main.cpp | 2 + actionlite/g_spawn.cpp | 6 +- actionlite/p_hud.cpp | 8 +- 19 files changed, 196 insertions(+), 6744 deletions(-) delete mode 100644 actionlite/a_game.cpp delete mode 100644 actionlite/a_game.h delete mode 100644 actionlite/a_match.cpp delete mode 100644 actionlite/a_match.h delete mode 100644 actionlite/a_radio.cpp delete mode 100644 actionlite/a_radio.h delete mode 100644 actionlite/a_team.cpp delete mode 100644 actionlite/a_team.h delete mode 100644 actionlite/cgf_sfx_glass.cpp delete mode 100644 actionlite/cgf_sfx_glass.h diff --git a/actionlite/CMakeLists.txt b/actionlite/CMakeLists.txt index db9d617..d6fcdde 100644 --- a/actionlite/CMakeLists.txt +++ b/actionlite/CMakeLists.txt @@ -7,6 +7,12 @@ set(CMAKE_C_COMPILER "gcc") set(CMAKE_CXX_COMPILER "g++") set(GAME_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/action/a_team.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/action/a_game.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/action/a_match.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/action/a_radio.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/action/cgf_sfx_glass.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/bots/bot_debug.cpp ${CMAKE_CURRENT_SOURCE_DIR}/bots/bot_exports.cpp ${CMAKE_CURRENT_SOURCE_DIR}/bots/bot_think.cpp @@ -45,10 +51,6 @@ set(GAME_SRC ${CMAKE_CURRENT_SOURCE_DIR}/p_weapon.cpp ${CMAKE_CURRENT_SOURCE_DIR}/q_std.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/a_team.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/a_game.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cgf_sfx_glass.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rogue/g_rogue_combat.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rogue/g_rogue_func.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rogue/g_rogue_items.cpp @@ -94,7 +96,7 @@ set_target_properties(game PROPERTIES POSITION_INDEPENDENT_CODE ON ) set_target_properties(game PROPERTIES PREFIX "") -set_target_properties(game PROPERTIES OUTPUT_NAME "gamex86") +set_target_properties(game PROPERTIES OUTPUT_NAME "game") # Fetch fmt locally find_package(fmt CONFIG REQUIRED) diff --git a/actionlite/a_game.cpp b/actionlite/a_game.cpp deleted file mode 100644 index 1bbbb81..0000000 --- a/actionlite/a_game.cpp +++ /dev/null @@ -1,1108 +0,0 @@ -#include "g_local.h" -#include "cgf_sfx_glass.h" - -#define MAX_MAP_ROTATION 1000 // just in case... -#define MAX_STR_LEN 1000 -#define MAX_TOTAL_MOTD_LINES 30 - -char *map_rotation[MAX_MAP_ROTATION]; -int num_maps, cur_map, rand_map, num_allvotes; // num_allvotes added by Igor[Rock] - -char motd_lines[MAX_TOTAL_MOTD_LINES][40]; -int motd_num_lines; - -/* - * ReadConfigFile() - * Config file format is backwards compatible with Action's, but doesn't need - * the "###" designator at end of sections. - * -Fireblade - */ -void ReadConfigFile() -{ - FILE *config_file; - char buf[MAX_STR_LEN], reading_section[MAX_STR_LEN], inipath[MAX_STR_LEN]; - int lines_into_section = -1; - cvar_t *ininame; - - ininame = gi.cvar("ininame", "action.ini", CVAR_NOFLAGS); - if (ininame->string && *(ininame->string)) - sprintf(inipath, "%s/%s", GAMEVERSION, ininame->string); - else - sprintf(inipath, "%s/%s", GAMEVERSION, "action.ini"); - - config_file = fopen(inipath, "r"); - if (config_file == NULL) { - gi.Com_PrintFmt("Unable to read %s\n", inipath); - return; - } - - while (fgets(buf, MAX_STR_LEN - 10, config_file) != NULL) { - int bs; - - bs = strlen(buf); - while (buf[bs - 1] == '\r' || buf[bs - 1] == '\n') { - buf[bs - 1] = 0; - bs--; - } - - if ((buf[0] == '/' && buf[1] == '/') || buf[0] == 0) { - continue; - } - - if (buf[0] == '[') { - char *p; - - p = strchr(buf, ']'); - if (p == NULL) - continue; - *p = 0; - strcpy(reading_section, buf + 1); - lines_into_section = 0; - continue; - } - if (buf[0] == '#' && buf[1] == '#' && buf[2] == '#') { - lines_into_section = -1; - continue; - } - if (lines_into_section > -1) { - if (!strcmp(reading_section, "team1")) { - if (lines_into_section == 0) { - Q_strlcpy(teams[TEAM1].name, buf, sizeof(teams[TEAM1].name)); - } else if (lines_into_section == 1) { - Q_strlcpy(teams[TEAM1].skin, buf, sizeof(teams[TEAM1].skin)); - } - } else if (!strcmp(reading_section, "team2")) { - if (lines_into_section == 0) { - Q_strlcpy(teams[TEAM2].name, buf, sizeof(teams[TEAM2].name)); - } else if (lines_into_section == 1) { - Q_strlcpy(teams[TEAM2].skin, buf, sizeof(teams[TEAM2].skin)); - } - } else if (!strcmp(reading_section, "team3")) { - if (lines_into_section == 0) { - Q_strlcpy(teams[TEAM3].name, buf, sizeof(teams[TEAM3].name)); - } else if (lines_into_section == 1) { - Q_strlcpy(teams[TEAM3].skin, buf, sizeof(teams[TEAM3].skin)); - } - } else if (!strcmp(reading_section, "maplist")) { - map_rotation[num_maps] = (char *) gi.TagMalloc(strlen(buf) + 1, TAG_GAME); - strcpy(map_rotation[num_maps], buf); - num_maps++; - } - lines_into_section++; - } - } - - snprintf(teams[TEAM1].skin_index, sizeof(teams[TEAM1].skin_index), "../players/%s_i", teams[TEAM1].skin); - snprintf(teams[TEAM2].skin_index, sizeof(teams[TEAM2].skin_index), "../players/%s_i", teams[TEAM2].skin); - snprintf(teams[TEAM3].skin_index, sizeof(teams[TEAM3].skin_index), "../players/%s_i", teams[TEAM3].skin); - - cur_map = 0; - srand(time(NULL)); - rand_map = (num_maps > 1) ? (rand() % (num_maps - 1) + 1) : 1; - - fclose(config_file); -} - -void ReadMOTDFile() -{ - FILE *motd_file; - char buf[1000]; - char motdpath[MAX_STR_LEN]; - int lbuf; - cvar_t *motdname; - - motdname = gi.cvar("motdname", "motd.txt", 0); - if (motdname->string && *(motdname->string)) - sprintf(motdpath, "%s/%s", GAMEVERSION, motdname->string); - else - sprintf(motdpath, "%s/%s", GAMEVERSION, "motd.txt"); - - motd_file = fopen(motdpath, "r"); - if (motd_file == NULL) - return; - - motd_num_lines = 0; - while (fgets(buf, 900, motd_file) != NULL) { - lbuf = strlen(buf); - while (lbuf > 0 && (buf[lbuf - 1] == '\r' || buf[lbuf - 1] == '\n')) { - buf[lbuf - 1] = 0; - lbuf--; - } - - if(!lbuf) - continue; - - if (lbuf > 39) - buf[39] = 0; - - strcpy(motd_lines[motd_num_lines++], buf); - - if (motd_num_lines >= MAX_TOTAL_MOTD_LINES) - break; - } - - fclose(motd_file); -} - -// AQ2:TNG Deathwatch - Ohh, lovely MOTD - edited it -void PrintMOTD(edict_t * ent) -{ - int mapnum, i, lines = 0; - int max_lines = MAX_TOTAL_MOTD_LINES; - char msg_buf[1024], *server_type; - - - //Welcome Message. This shows the Version Number and website URL, followed by an empty line - strcpy(msg_buf, TNG_TITLE " v" VERSION "\n" "https://github.com/actionquake/quake2-rerelease-dll" "\n\n"); - lines = 3; - - /* - As long as we don't skip the MOTD, we want to print all information - */ - if (!skipmotd->value) { - // This line will show the hostname. If not set, the default name will be "Unnamed TNG Server" (used to be "unnamed") - if (hostname->string[0] && strcmp(hostname->string, "Unnamed TNG Server")) - { - Q_strncatz(msg_buf, hostname->string, strlen(msg_buf)+40); - strcat(msg_buf, "\n"); - lines++; - } - - /* - Now all the settings - */ - - // Check what game type it is - if (teamplay->value) - { - if (teamdm->value) // Is it TeamDM? - { - if (teamCount == 3) - server_type = "3 Team Deathmatch"; - else - server_type = "Team Deathmatch"; - } - } - else // So it's not Teamplay? - { - server_type = "Deathmatch (Free For All)"; - sprintf(msg_buf + strlen(msg_buf), "Game Type: %s\n", server_type); - } - lines++; - - // Adding an empty line - strcat(msg_buf, "\n"); - lines++; - - /* - Now for the map rules, such as Timelimit, Roundlimit, etc - */ - if (fraglimit->integer) // What is the fraglimit? - sprintf(msg_buf + strlen(msg_buf), "Fraglimit: %d", fraglimit->integer); - else - strcat(msg_buf, "Fraglimit: none"); - - if (timelimit->integer) // What is the timelimit? - sprintf(msg_buf + strlen(msg_buf), " Timelimit: %d\n", timelimit->integer); - else - strcat(msg_buf, " Timelimit: none\n"); - lines++; - - // If we're in Teamplay, and not CTF, we want to see what the roundlimit and roundtimelimit is - if (gameSettings & GS_ROUNDBASED) - { - if ((int)roundlimit->value) // What is the roundlimit? - sprintf(msg_buf + strlen(msg_buf), "Roundlimit: %d", (int)roundlimit->value); - else - strcat(msg_buf, "Roundlimit: none"); - lines++; - } - - /* - Check for the number of weapons and items people can carry - */ - if ((int)unique_weapons->value != 1 || (int)unique_items->value != 1) { - sprintf(msg_buf + strlen(msg_buf), "Max number of spec weapons: %d items: %d\n", - (int) unique_weapons->value, (int) unique_items->value); - lines++; - } - - /* - What can we use with the Bandolier? - */ - if (tgren->value > 0 || !(ir->value)) { - char grenade_num[32]; - - // Show the number of grenades with the Bandolier - if (tgren->value > 0) - sprintf(grenade_num, "%d grenade%s", (int)tgren->value, (int)tgren->value == 1 ? "" : "s"); - - sprintf(msg_buf + strlen(msg_buf), "Bandolier w/ %s%s%s\n", - !(ir->value) ? "no IR" : "", - (tgren->value > 0 && !(ir->value)) ? " & " : "", - tgren->value > 0 ? grenade_num : ""); - lines++; - } - - /* - Is allitem and/or allweapon enabled? - */ - if (allitem->value || allweapon->value) { - sprintf(msg_buf + strlen(msg_buf), "Players receive %s%s%s\n", - allweapon->value ? "all weapons" : "", - (allweapon->value && allitem->value) ? " & " : "", - allitem->value ? "all items" : ""); - lines++; - } - - /* - * Are we using limchasecam? - */ - if (limchasecam->value) { - if ((int) limchasecam->value == 2) - sprintf(msg_buf + strlen(msg_buf), "Chase Cam Disallowed\n"); - else - sprintf(msg_buf + strlen(msg_buf), "Chase Cam Restricted\n"); - lines++; - } - - /* - * Are the dmflags set to disallow Friendly Fire? - */ - if (teamplay->value && !g_friendly_fire->integer) { - sprintf(msg_buf + strlen(msg_buf), "Friendly Fire Enabled\n"); - lines++; - } - - /* - Are we using any types of voting? - */ - if (use_mapvote->value || use_cvote->value || use_kickvote->value) { - sprintf(msg_buf + strlen(msg_buf), "Vote Types: %s%s%s%s%s\n", - use_mapvote->value ? "Map" : "", (use_mapvote->value - && use_cvote->value) ? " & " : "", - use_cvote->value ? "Config" : "", ((use_mapvote->value && use_kickvote->value) - || (use_cvote->value - && use_kickvote->value)) ? " & " : "", - use_kickvote->value ? "Kick" : ""); - lines++; // lines+=3; - } - - /* - Map Locations - */ - if (ml_count != 0) { - sprintf(msg_buf + strlen(msg_buf), "\n%d Locations, by: %s\n", ml_count, ml_creator); - lines++; - } - /* - If actionmaps, put a blank line then the maps list - */ - if (actionmaps->value && num_maps > 0) - { - int chars_on_line = 0, len_mr; - - if (vrot->value) // Using Vote Rotation? - strcat(msg_buf, "\nRunning these maps in vote order:\n"); - else if (rrot->value) // Using Random Rotation? - strcat(msg_buf, "\nRunning the following maps randomly:\n"); - else - strcat(msg_buf, "\nRunning the following maps in order:\n"); - - lines += 2; - - for (mapnum = 0; mapnum < num_maps; mapnum++) - { - len_mr = strlen(*(map_rotation + mapnum)); - if ((chars_on_line + len_mr + 2) > 39) { - Q_strncatz(msg_buf, "\n", sizeof(msg_buf)); - lines++; - if (lines >= max_lines) - break; - chars_on_line = 0; - } - Q_strncatz(msg_buf, *(map_rotation + mapnum), sizeof(msg_buf)); - chars_on_line += len_mr; - if (mapnum < (num_maps - 1)) { - Q_strncatz(msg_buf, ", ", sizeof(msg_buf)); - chars_on_line += 2; - } - } - - if (lines < max_lines) { - Q_strncatz(msg_buf, "\n", sizeof(msg_buf)); - lines++; - } - } - - //If we're in teamplay, we want to inform people that they can open the menu with TAB - if (teamplay->value && lines < max_lines && !auto_menu->value) { - Q_strncatz(msg_buf, "\nHit TAB to open the Team selection menu", sizeof(msg_buf)); - lines++; - } - } - - /* - Insert action/motd.txt contents (whole MOTD gets truncated after 30 lines) - */ - - if (motd_num_lines && lines < max_lines-1) - { - Q_strncatz(msg_buf, "\n", sizeof(msg_buf)); - lines++; - for (i = 0; i < motd_num_lines; i++) { - Q_strncatz(msg_buf, motd_lines[i], sizeof(msg_buf)); - lines++; - if (lines >= max_lines) - break; - Q_strncatz(msg_buf, "\n", sizeof(msg_buf)); - } - } - - if (!auto_menu->value || ent->client->pers.menu_shown) { - gi.LocCenter_Print(ent, "%s", msg_buf); - } else { - gi.LocClient_Print(ent, PRINT_LOW, "%s", msg_buf); - } -} - -// stuffcmd: forces a player to execute a command. -void stuffcmd(edict_t * ent, char *c) -{ - gi.WriteByte(svc_stufftext); - gi.WriteString(c); - gi.unicast(ent, true); -} - - -void unicastSound(edict_t *ent, int soundIndex, float volume) -{ - int mask = MASK_ENTITY_CHANNEL; - - if (volume != 1.0) - mask |= MASK_VOLUME; - - gi.WriteByte(svc_sound); - gi.WriteByte((byte)mask); - gi.WriteByte((byte)soundIndex); - if (mask & MASK_VOLUME) - gi.WriteByte((byte)(volume * 255)); - - // hack when first person spectating, the sound source must be the spectated player - if (ent->client->chase_mode == 2 && ent->client->chase_target) { - gi.WriteShort(((ent->client->chase_target - g_edicts - 1) << 3) + CHAN_NO_PHS_ADD); - } else { - gi.WriteShort(((ent - g_edicts - 1) << 3) + CHAN_NO_PHS_ADD); - } - - gi.unicast (ent, true); -} -// AQ2:TNG END - -/******************************************************************************** -* -* zucc: following are EjectBlooder, EjectShell, AddSplat, and AddDecal -* code. All from actionquake, some had to be modified to fit Axshun or fix -* bugs. -* -*/ - -int decals = 0; -int shells = 0; -int splats = 0; - -//blooder used for bleeding - -void BlooderTouch(edict_t * self, edict_t * other, cplane_t * plane, csurface_t * surf) -{ - if( (other == self->owner) || other->client ) // Don't stop on players. - return; - self->think = G_FreeEdict; - self->nextthink = level.time + 1_ms; -} - -void EjectBlooder(edict_t * self, vec3_t start, vec3_t veloc) -{ - edict_t *blooder; - vec3_t forward; - int spd = 0; - - blooder = G_Spawn(); - VectorCopy(veloc, forward); - VectorCopy(start, blooder->s.origin); - VectorCopy(start, blooder->old_origin); - spd = 0; - VectorScale(forward, spd, blooder->velocity); - blooder->solid = SOLID_NOT; - blooder->movetype = MOVETYPE_BLOOD; // Allow dripping blood to make a splat. - blooder->s.modelindex = level.model_null; - blooder->s.effects |= EF_GIB; - blooder->owner = self; - blooder->touch = BlooderTouch; - blooder->nextthink = level.time + 32_ms; - blooder->think = G_FreeEdict; - blooder->classname = "blooder"; - - gi.linkentity(blooder); -} - -// zucc - Adding EjectShell code from action quake, modified for Axshun. -/********* SHELL EJECTION **************/ - -void PlaceHolder( edict_t * ent ); // p_weapon.c - -void ShellTouch(edict_t * self, edict_t * other, cplane_t * plane, csurface_t * surf) -{ - if (self->owner->client->curr_weap == IT_WEAPON_M3) - gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/shellhit1.wav"), 1, ATTN_STATIC, 0); - else if (random() < 0.5) - gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/tink1.wav"), 0.2, ATTN_STATIC, 0); - else - gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/tink2.wav"), 0.2, ATTN_STATIC, 0); -} - -void ShellDie(edict_t * self) -{ - G_FreeEdict(self); - --shells; -} - -static void RemoveOldestShell( void ) -{ - int i = 0; - edict_t *it = NULL, *found = NULL; - - for( i = 0; i < globals.num_edicts; i ++ ) - { - it = &g_edicts[i]; - if( it->inuse && it->classname && (Q_stricmp( it->classname, "shell" ) == 0) ) - { - if( (! found) || (it->freetime < found->freetime) ) - found = it; - } - } - - if( found ) - ShellDie( found ); -} - -// zucc fixed this so it works with the sniper rifle and checks handedness -// had to add the toggle feature to handle the akimbos correctly, if 1 -// it sets up for ejecting the shell from the left akimbo weapon, if 2 -// it fires right handed akimbo - -void EjectShell(edict_t * self, vec3_t start, int toggle) -{ - edict_t *shell; - vec3_t forward, right, up; - float r; - float fix = 1.0; - int left = 0; - - if (sv_shelloff->value) - return; - - if( (shelllimit->value > 0) && (shells >= shelllimit->value) ) - RemoveOldestShell(); - - shell = G_Spawn(); - ++shells; - - AngleVectors(self->client->v_angle, forward, right, up); - - if (self->client->pers.hand == LEFT_HANDED) { - left = 1; - fix = -1.0; - } else if (self->client->pers.hand == CENTER_HANDED) - fix = 0; - - // zucc spent a fair amount of time hacking these until they look ok, - // several of them could be improved however. - - if (self->client->curr_weap == IT_WEAPON_MK23) { - VectorMA(start, left ? -7 : .4, right, start); - VectorMA(start, left ? 5 : 2, forward, start); - VectorMA(start, left ? -10 : -8, up, start); - } else if (self->client->curr_weap == IT_WEAPON_M4) { - VectorMA(start, left ? -10 : 5, right, start); - VectorMA(start, left ? 6 : 12, forward, start); - VectorMA(start, left ? -9 : -11, up, start); - } else if (self->client->curr_weap == IT_WEAPON_MP5) { - VectorMA(start, left ? -10 : 6, right, start); - VectorMA(start, left ? 6 : 8, forward, start); - VectorMA(start, left ? -9 : -10, up, start); - } else if (self->client->curr_weap == IT_WEAPON_SNIPER) { - VectorMA(start, fix * 11, right, start); - VectorMA(start, 2, forward, start); - VectorMA(start, -11, up, start); - - } else if (self->client->curr_weap == IT_WEAPON_M3) { - VectorMA(start, left ? -9 : 3, right, start); - VectorMA(start, left ? 4 : 4, forward, start); - VectorMA(start, left ? -1 : -1, up, start); - } - - else if (self->client->curr_weap == IT_WEAPON_DUALMK23) { - if (self->client->pers.hand == LEFT_HANDED) - VectorMA(start, ((toggle == 1) ? 8 : -8), right, start); - else - VectorMA(start, ((toggle == 1) ? -4 : 4), right, start); - VectorMA(start, 6, forward, start); - VectorMA(start, -9, up, start); - - } - - if ((forward[2] >= -1) && (forward[2] < -0.99)) { - VectorMA(start, 5, forward, start); - VectorMA(start, -0.5, up, start); - } else if ((forward[2] >= -0.99) && (forward[2] < -0.98)) { - VectorMA(start, 5, forward, start); - VectorMA(start, -.1, up, start); - } else if ((forward[2] >= -0.98) && (forward[2] < -0.97)) { - VectorMA(start, 5.1, forward, start); - VectorMA(start, 0.3, up, start); - } else if ((forward[2] >= -0.97) && (forward[2] < -0.96)) { - VectorMA(start, 5.2, forward, start); - VectorMA(start, 0.7, up, start); - } else if ((forward[2] >= -0.96) && (forward[2] < -0.95)) { - VectorMA(start, 5.2, forward, start); - VectorMA(start, 1.1, up, start); - } else if ((forward[2] >= -0.95) && (forward[2] < -0.94)) { - VectorMA(start, 5.3, forward, start); - VectorMA(start, 1.5, up, start); - } else if ((forward[2] >= -0.94) && (forward[2] < -0.93)) { - VectorMA(start, 5.4, forward, start); - VectorMA(start, 1.9, up, start); - } else if ((forward[2] >= -0.93) && (forward[2] < -0.92)) { - VectorMA(start, 5.5, forward, start); - VectorMA(start, 2.3, up, start); - } else if ((forward[2] >= -0.92) && (forward[2] < -0.91)) { - VectorMA(start, 5.6, forward, start); - VectorMA(start, 2.7, up, start); - } else if ((forward[2] >= -0.91) && (forward[2] < -0.9)) { - VectorMA(start, 5.7, forward, start); - VectorMA(start, 3.1, up, start); - } else if ((forward[2] >= -0.9) && (forward[2] < -0.85)) { - VectorMA(start, 5.8, forward, start); - VectorMA(start, 3.5, up, start); - } else if ((forward[2] >= -0.85) && (forward[2] < -0.8)) { - VectorMA(start, 6, forward, start); - VectorMA(start, 4, up, start); - } else if ((forward[2] >= -0.8) && (forward[2] < -0.6)) { - VectorMA(start, 6.5, forward, start); - VectorMA(start, 4.5, up, start); - } else if ((forward[2] >= -0.6) && (forward[2] < -0.4)) { - VectorMA(start, 8, forward, start); - VectorMA(start, 5.5, up, start); - } else if ((forward[2] >= -0.4) && (forward[2] < -0.2)) { - VectorMA(start, 9.5, forward, start); - VectorMA(start, 6, up, start); - } else if ((forward[2] >= -0.2) && (forward[2] < 0)) { - VectorMA(start, 11, forward, start); - VectorMA(start, 6.5, up, start); - } else if ((forward[2] >= 0) && (forward[2] < 0.2)) { - VectorMA(start, 12, forward, start); - VectorMA(start, 7, up, start); - } else if ((forward[2] >= 0.2) && (forward[2] < 0.4)) { - VectorMA(start, 14, forward, start); - VectorMA(start, 6.5, up, start); - } else if ((forward[2] >= 0.4) && (forward[2] < 0.6)) { - VectorMA(start, 16, forward, start); - VectorMA(start, 6, up, start); - } else if ((forward[2] >= 0.6) && (forward[2] < 0.8)) { - VectorMA(start, 18, forward, start); - VectorMA(start, 5, up, start); - } else if ((forward[2] >= 0.8) && (forward[2] < 0.85)) { - VectorMA(start, 18, forward, start); - VectorMA(start, 4, up, start); - } else if ((forward[2] >= 0.85) && (forward[2] < 0.9)) { - VectorMA(start, 18, forward, start); - VectorMA(start, 2.5, up, start); - } else if ((forward[2] >= 0.9) && (forward[2] < 0.91)) { - VectorMA(start, 18.2, forward, start); - VectorMA(start, 2.2, up, start); - } else if ((forward[2] >= 0.91) && (forward[2] < 0.92)) { - VectorMA(start, 18.4, forward, start); - VectorMA(start, 1.9, up, start); - } else if ((forward[2] >= 0.92) && (forward[2] < 0.93)) { - VectorMA(start, 18.6, forward, start); - VectorMA(start, 1.6, up, start); - } else if ((forward[2] >= 0.93) && (forward[2] < 0.94)) { - VectorMA(start, 18.8, forward, start); - VectorMA(start, 1.3, up, start); - } else if ((forward[2] >= 0.94) && (forward[2] < 0.95)) { - VectorMA(start, 19, forward, start); - VectorMA(start, 1, up, start); - } else if ((forward[2] >= 0.95) && (forward[2] < 0.96)) { - VectorMA(start, 19.2, forward, start); - VectorMA(start, 0.7, up, start); - } else if ((forward[2] >= 0.96) && (forward[2] < 0.97)) { - VectorMA(start, 19.4, forward, start); - VectorMA(start, 0.4, up, start); - } else if ((forward[2] >= 0.97) && (forward[2] < 0.98)) { - VectorMA(start, 19.6, forward, start); - VectorMA(start, -0.2, up, start); - } else if ((forward[2] >= 0.98) && (forward[2] < 0.99)) { - VectorMA(start, 19.8, forward, start); - VectorMA(start, -0.6, up, start); - } else if ((forward[2] >= 0.99) && (forward[2] <= 1)) { - VectorMA(start, 20, forward, start); - VectorMA(start, -1, up, start); - } - - VectorCopy(start, shell->s.origin); - VectorCopy(start, shell->old_origin); - if (fix == 0) // we want some velocity on those center handed ones - fix = 1; - if (self->client->curr_weap == IT_WEAPON_SNIPER) - VectorMA(shell->velocity, fix * (-35 + random() * -60), right, shell->velocity); - else if (self->client->curr_weap == IT_WEAPON_DUALMK23) { - if (self->client->pers.hand == LEFT_HANDED) - VectorMA(shell->velocity, - (toggle == 1 ? 1 : -1) * (35 + random() * 60), right, shell->velocity); - else - VectorMA(shell->velocity, - (toggle == 1 ? -1 : 1) * (35 + random() * 60), right, shell->velocity); - } else - VectorMA(shell->velocity, fix * (35 + random() * 60), right, shell->velocity); - VectorMA(shell->avelocity, 500, right, shell->avelocity); - if (self->client->curr_weap == IT_WEAPON_SNIPER) - VectorMA(shell->velocity, 60 + 40, up, shell->velocity); - else - VectorMA(shell->velocity, 60 + random() * 90, up, shell->velocity); - - shell->movetype = MOVETYPE_BOUNCE; - shell->solid = SOLID_BBOX; - - if( (self->client->curr_weap == IT_WEAPON_M3) || (self->client->curr_weap == IT_WEAPON_HANDCANNON) ) - shell->s.modelindex = gi.modelindex("models/weapons/shell/tris2.md2"); - else if( (self->client->curr_weap == IT_WEAPON_SNIPER) || (self->client->curr_weap == IT_WEAPON_M4) ) - shell->s.modelindex = gi.modelindex("models/weapons/shell/tris3.md2"); - else - shell->s.modelindex = gi.modelindex("models/weapons/shell/tris.md2"); - - r = random(); - if (r < 0.1) - shell->s.frame = 0; - else if (r < 0.2) - shell->s.frame = 1; - else if (r < 0.3) - shell->s.frame = 2; - else if (r < 0.5) - shell->s.frame = 3; - else if (r < 0.6) - shell->s.frame = 4; - else if (r < 0.7) - shell->s.frame = 5; - else if (r < 0.8) - shell->s.frame = 6; - else if (r < 0.9) - shell->s.frame = 7; - else - shell->s.frame = 8; - - shell->owner = self; - shell->touch = ShellTouch; - shell->nextthink = level.framenum + (shelllife->value - (shells * 0.05)) * HZ; - shell->think = shelllife->value ? ShellDie : PlaceHolder; - shell->classname = "shell"; - shell->freetime = level.time; // Used to determine oldest spawned shell. - - gi.linkentity(shell); -} - -/* - ================== - FindEdictByClassnum - ================== - */ -edict_t *FindEdictByClassnum(char *classname, int classnum) -{ - int i; - edict_t *it; - - for (i = 0; i < globals.num_edicts; i++) - { - it = &g_edicts[i]; - if (it->classname && (it->classnum == classnum) && (Q_stricmp(it->classname, classname) == 0)) - return it; - } - - return NULL; - -} - -/********* Bulletholes/wall stuff ***********/ - -void UpdateAttachedPos( edict_t *self ) -{ - vec3_t fwd, right, up; - - if( (self->wait && (level.framenum >= self->wait)) || ! self->movetarget->inuse ) - { - G_FreeEdict(self); - return; - } - - self->nextthink = level.framenum + 1; - - if( self < self->movetarget ) - { - // If the object we're attached to hasn't been updated yet this frame, - // we need to move ahead one frame's worth so we stay aligned with it. - VectorScale( self->movetarget->velocity, FRAMETIME, self->s.origin ); - VectorAdd( self->movetarget->s.origin, self->s.origin, self->s.origin ); - VectorScale( self->movetarget->avelocity, FRAMETIME, self->s.angles ); - VectorAdd( self->movetarget->s.angles, self->s.angles, self->s.angles ); - } - else - { - VectorCopy( self->movetarget->s.origin, self->s.origin ); - VectorCopy( self->movetarget->s.angles, self->s.angles ); - } - - AngleVectors( self->s.angles, fwd, right, up ); // At this point, this is the angles of the entity we attached to. - self->s.origin[0] += fwd[0] * self->move_origin[0] + right[0] * self->move_origin[1] + up[0] * self->move_origin[2]; - self->s.origin[1] += fwd[1] * self->move_origin[0] + right[1] * self->move_origin[1] + up[1] * self->move_origin[2]; - self->s.origin[2] += fwd[2] * self->move_origin[0] + right[2] * self->move_origin[1] + up[2] * self->move_origin[2]; - VectorAdd( self->s.angles, self->move_angles, self->s.angles ); - VectorCopy( self->movetarget->velocity, self->velocity ); - VectorCopy( self->movetarget->avelocity, self->avelocity ); -} - -// Decal/splat/knife attached to some moving entity. -void AttachedThink( edict_t *self ) -{ - UpdateAttachedPos( self ); - gi.linkentity( self ); -} - -// Attach a splat/decal/knife to a moving entity. -void AttachToEntity( edict_t *self, edict_t *onto ) -{ - vec3_t fwd, right, up, offset; - - self->wait = self->nextthink; // Use old nextthink as despawn framenum (0 is never). - self->movetype = MOVETYPE_NONE; - - self->movetarget = onto; - AngleVectors( onto->s.angles, fwd, right, up ); - VectorSubtract( self->s.origin, onto->s.origin, offset ); - self->move_origin[0] = DotProduct( offset, fwd ); - self->move_origin[1] = DotProduct( offset, right ); - self->move_origin[2] = DotProduct( offset, up ); - VectorSubtract( self->s.angles, onto->s.angles, self->move_angles ); - - self->think = AttachedThink; - - UpdateAttachedPos( self ); -} - -bool CanBeAttachedTo( const edict_t *ent ) -{ - return (ent && ( (Q_strnicmp( ent->classname, "func_door", 9 ) == 0) - || (Q_stricmp( ent->classname, "func_plat" ) == 0) - || (Q_stricmp( ent->classname, "func_rotating" ) == 0) - || (Q_stricmp( ent->classname, "func_train" ) == 0) - || (Q_stricmp( ent->classname, "func_button" ) == 0) )); -} - -void AddDecal(edict_t * self, trace_t * tr) -{ - edict_t *decal, *dec; - bool attached; - - if (bholelimit->value < 1) - return; - - attached = CanBeAttachedTo(tr->ent); - - decal = bholelife->value ? G_Spawn() : G_Spawn_Decal(); - if( ! decal ) - return; - - ++decals; - - if (decals > bholelimit->value) - decals = 1; - - dec = FindEdictByClassnum("decal", decals); - - if( dec ) - { - dec->think = G_FreeEdict; - dec->nextthink = level.framenum + FRAMEDIV; - } - - decal->solid = SOLID_NOT; - decal->movetype = MOVETYPE_NONE; - decal->s.modelindex = gi.modelindex("models/objects/holes/hole1/hole.md2"); - VectorCopy(tr->endpos, decal->s.origin); - VectorCopy(tr->endpos, decal->old_origin); - vectoangles(tr->plane.normal, decal->s.angles); - decal->s.angles[ROLL] = crandom() * 180.f; - - decal->owner = self; - decal->touch = NULL; - decal->nextthink = bholelife->value ? (level.framenum + bholelife->value * HZ) : 0; - decal->think = bholelife->value ? G_FreeEdict : PlaceHolder; - decal->classname = "decal"; - decal->classnum = decals; - - if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname))) { - CGF_SFX_AttachDecalToGlass(tr->ent, decal); - } - else if( attached ) - AttachToEntity( decal, tr->ent ); - - gi.linkentity(decal); -} - -void AddSplat(edict_t * self, vec3_t point, trace_t * tr) -{ - edict_t *splat, *spt; - float r; - bool attached; - - if (splatlimit->value < 1) - return; - - attached = CanBeAttachedTo(tr->ent); - - splat = splatlife->value ? G_Spawn() : G_Spawn_Decal(); - if( ! splat ) - return; - - ++splats; - - if (splats > splatlimit->value) - splats = 1; - - spt = FindEdictByClassnum("splat", splats); - - if( spt ) - { - spt->think = G_FreeEdict; - spt->nextthink = level.framenum + FRAMEDIV; - } - - splat->solid = SOLID_NOT; - splat->movetype = MOVETYPE_NONE; - - r = random(); - if (r > .67) - splat->s.modelindex = gi.modelindex("models/objects/splats/splat1/splat.md2"); - else if (r > .33) - splat->s.modelindex = gi.modelindex("models/objects/splats/splat2/splat.md2"); - else - splat->s.modelindex = gi.modelindex("models/objects/splats/splat3/splat.md2"); - - VectorCopy(point, splat->s.origin); - VectorCopy(point, splat->old_origin); - - vectoangles(tr->plane.normal, splat->s.angles); - splat->s.angles[ROLL] = crandom() * 180.f; - - splat->owner = self; - splat->touch = NULL; - splat->nextthink = level.framenum + splatlife->value * HZ; - splat->think = splatlife->value ? G_FreeEdict : PlaceHolder; - splat->classname = "splat"; - splat->classnum = splats; - - if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname))) { - CGF_SFX_AttachDecalToGlass(tr->ent, splat); - } - else if( attached ) - AttachToEntity( splat, tr->ent ); - - gi.linkentity(splat); -} - -/* %-variables for chat msgs */ - -void GetWeaponName( edict_t *ent, char *buf ) -{ - if( IS_ALIVE(ent) && ent->client->weapon ) - { - strcpy( buf, ent->client->weapon->pickup_name ); - return; - } - - strcpy( buf, "no weapon" ); -} - -void GetItemName( edict_t *ent, char *buf ) -{ - int i, itemNum; - - if( IS_ALIVE(ent) ) - { - for( i = 0; i < ITEM_COUNT; i ++ ) - { - itemNum = ITEM_FIRST + i; - if( INV_AMMO( ent, itemNum ) ) - { - strcpy( buf, GET_ITEM(itemNum)->pickup_name ); - return; - } - } - } - - strcpy( buf, "no item" ); -} - -void GetHealth( edict_t *ent, char *buf ) -{ - if( IS_ALIVE(ent) ) - sprintf( buf, "%d", ent->health ); - else - sprintf( buf, "0" ); -} - -void GetAmmo( edict_t *ent, char *buf ) -{ - int ammo; - - if( IS_ALIVE(ent) && ent->client->pers.weapon ) - { - switch( ent->client->pers.weapon->id ) - { - case IT_WEAPON_MK23: - sprintf( buf, "%d round%s (%d extra mag%s)", - ent->client->mk23_rds, ent->client->mk23_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_MP5: - sprintf( buf, "%d round%s (%d extra mag%s)", - ent->client->mp5_rds, ent->client->mp5_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_M4: - sprintf( buf, "%d round%s (%d extra mag%s)", - ent->client->m4_rds, ent->client->m4_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_M3: - sprintf( buf, "%d shell%s (%d extra shell%s)", - ent->client->shot_rds, ent->client->shot_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_HANDCANNON: - sprintf( buf, "%d shell%s (%d extra shell%s)", - ent->client->cannon_rds, ent->client->cannon_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_SNIPER: - sprintf( buf, "%d round%s (%d extra round%s)", - ent->client->sniper_rds, ent->client->sniper_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_DUALMK23: - sprintf( buf, "%d round%s (%d extra mag%s)", - ent->client->dual_rds, ent->client->dual_rds == 1 ? "" : "s", - ent->client->inventory[ent->client->ammo_index], - ent->client->inventory[ent->client->ammo_index] == 1 ? "" : "s"); - return; - case IT_WEAPON_KNIFE: - ammo = INV_AMMO( ent, IT_WEAPON_KNIFE ); - sprintf( buf, "%d kni%s", ammo, (ammo == 1) ? "fe" : "ves" ); - return; - case IT_WEAPON_GRENADES: - ammo = INV_AMMO( ent, IT_WEAPON_GRENADES ); - sprintf( buf, "%d grenade%s", ammo, (ammo == 1) ? "" : "s" ); - return; - } - } - - strcpy( buf, "no ammo" ); -} - -void GetNearbyTeammates( edict_t *self, char *buf ) -{ - edict_t *nearby_teammates[8]; - size_t nearby_teammates_num = 0, l; - edict_t *ent = NULL; - - while ((ent = findradius(ent, self->s.origin, 1500)) != NULL) { - if (ent == self || !ent->client || !CanDamage(ent, self) || !OnSameTeam(ent, self)) - continue; - - nearby_teammates[nearby_teammates_num++] = ent; - if (nearby_teammates_num >= 8) - break; - } - - if (nearby_teammates_num == 0) { - strcpy(buf, "nobody"); - return; - } - - strcpy(buf, nearby_teammates[0]->client->pers.netname); - for (l = 1; l < nearby_teammates_num; l++) - { - if (l == nearby_teammates_num - 1) - Q_strncatz(buf, " and ", PARSE_BUFSIZE); - else - Q_strncatz(buf, ", ", PARSE_BUFSIZE); - - Q_strncatz( buf, nearby_teammates[l]->client->pers.netname, PARSE_BUFSIZE ); - } -} - -// Messaging adjectives/pronouns -// Borrowed from https://github.com/VortexQuake2/Vortex, thank you! - -char *GetPossesiveAdjectiveSingular(edict_t *ent) { - int gender = ent->client->pers.gender; - char *info; - - switch( gender ) { - case GENDER_MALE: - return "his"; - case GENDER_FEMALE: - return "her"; - case GENDER_NEUTRAL: - return "it"; - default: - return "their"; - } -} - -char *GetPossesiveAdjective(edict_t *ent) { - int gender = ent->client->pers.gender; - char *info; - - switch( gender ) { - case GENDER_MALE: - return "his"; - case GENDER_FEMALE: - return "her"; - case GENDER_NEUTRAL: - return "its"; - default: - return "their"; - } -} - -char *GetReflexivePronoun(edict_t *ent) { - int gender = ent->client->pers.gender; - char *info; - - switch( gender ) { - case GENDER_MALE: - return "himself"; - case GENDER_FEMALE: - return "herself"; - case GENDER_NEUTRAL: - return "itself"; - default: - return "themselves"; - } -} \ No newline at end of file diff --git a/actionlite/a_game.h b/actionlite/a_game.h deleted file mode 100644 index 74240a1..0000000 --- a/actionlite/a_game.h +++ /dev/null @@ -1,60 +0,0 @@ -// AQ2:TNG Deathwatch - Updated the Version variables to show TNG Stuff -#ifndef VERSION -#define VERSION "0.1" -#endif -#define TNG_TITLE "AQ2: The Next Generation Plus" -// AQ2:TNG Deathwatch End -//AQ2:TNG Slicer This is the max players writen on last killed target -//SLIC2 -#define MAX_LAST_KILLED 8 -//AQ2:TNG END - -extern char *map_rotation[]; -extern int num_maps, cur_map, rand_map, num_allvotes; // num_allvotes added by Igor[Rock] - -void ReadConfigFile (); -void ReadMOTDFile (); -void PrintMOTD (edict_t *ent); -void stuffcmd (edict_t *ent, char *s); -void unicastSound(edict_t *ent, int soundIndex, float volume); - -int KickDoor (trace_t * tr_old, edict_t * ent, vec3_t forward); - -// Prototypes of base Q2 functions that weren't included in any Q2 header -//bool loc_CanSee (edict_t *, edict_t *); -void ParseSayText (edict_t *, char *, size_t size); - -void AttachToEntity( edict_t *self, edict_t *onto ); -bool CanBeAttachedTo( const edict_t *ent ); - -//PG BUND - BEGIN -//void ParseSayText(edict_t *, char *); -void GetWeaponName (edict_t * ent, char *buf); -void GetItemName (edict_t * ent, char *buf); -void GetHealth (edict_t * ent, char *buf); -void GetAmmo (edict_t * ent, char *buf); -void GetNearbyTeammates (edict_t * self, char *buf); - -void ResetScores (bool playerScores); -void AddKilledPlayer (edict_t * self, edict_t * ent); -void VideoCheckClient (edict_t * ent); -//AQ2:TNG END -//TempFile -void GetLastLoss (edict_t * self, char *buf, char team); - -// Firing styles (where shots originate from) -#define ACTION_FIRING_CENTER 0 -#define ACTION_FIRING_CLASSIC 1 -#define ACTION_FIRING_CLASSIC_HIGH 2 - -// maxs[2] of a player when crouching (we modify it from the normal 4) -// ...also the modified viewheight -FB 7/18/99 -#define CROUCHING_MAXS2 16 -#define CROUCHING_VIEWHEIGHT 8 -#define STANDING_VIEWHEIGHT 22 - -//a_team.c -void MakeAllLivePlayersObservers( void ); - -//a_cmds.c -void Cmd_NextMap_f( edict_t * ent ); diff --git a/actionlite/a_match.cpp b/actionlite/a_match.cpp deleted file mode 100644 index 3980e2e..0000000 --- a/actionlite/a_match.cpp +++ /dev/null @@ -1,608 +0,0 @@ -#include "g_local.h" -#include "a_match.h" - -void SendScores(void) -{ - unsigned int mins, secs, gametime = level.matchTime; - - mins = gametime / 60; - secs = gametime % 60; - if(teamCount == 3) { - gi.bprintf(PRINT_HIGH, "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F\n"); - gi.bprintf(PRINT_HIGH, " Team 1 Score - Team 2 Score - Team 3 Score\n"); - gi.bprintf(PRINT_HIGH, " [%d] [%d] [%d]\n", teams[TEAM1].score, teams[TEAM2].score, teams[TEAM3].score); - gi.bprintf(PRINT_HIGH, " Total Played Time: %d:%02d\n", mins, secs); - gi.bprintf(PRINT_HIGH, "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F\n"); - } else { - int team1score = 0, team2score = 0; - - if(ctf->value) { - GetCTFScores(&team1score, &team2score); - } else { - team1score = teams[TEAM1].score; - team2score = teams[TEAM2].score; - } - gi.bprintf(PRINT_HIGH, "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F\n"); - gi.bprintf(PRINT_HIGH, " Team 1 Score - Team 2 Score\n"); - gi.bprintf(PRINT_HIGH, " [%d] [%d]\n", team1score, team2score); - gi.bprintf(PRINT_HIGH, " Total Played Time: %d:%02d\n", mins, secs); - gi.bprintf(PRINT_HIGH, "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F\n"); - } - gi.bprintf(PRINT_HIGH, "Match is over, waiting for next map, please vote a new one..\n"); - - #if USE_AQTION - // Needed to add this here because Matchmode does not call BeginIntermission, but other teamplay modes do call it - if (stat_logs->value) { - LogMatch(); // Generates end of game stats - LogEndMatchStats(); // Generates end of match stats - } - #endif - // Stats: Reset roundNum - game.roundNum = 0; - // Stats end - - #ifndef NO_BOTS - // Clear LTK bot names - LTKClearBotNames(); - #endif -} - -void Cmd_Sub_f(edict_t * ent) -{ - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - if (ent->client->resp.team == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n"); - return; - } - if (!ent->client->resp.subteam) { - killPlayer(ent, true); // lets kill em. - gi.bprintf(PRINT_HIGH, "%s is now a substitute for %s\n", ent->client->pers.netname, teams[ent->client->resp.team].name); - ent->client->resp.subteam = ent->client->resp.team; - return; - } - - gi.bprintf(PRINT_HIGH, "%s is no longer a substitute for %s\n", ent->client->pers.netname, teams[ent->client->resp.team].name); - ent->client->resp.subteam = 0; - if (team_round_going && !(gameSettings & GS_ROUNDBASED)) - { - PutClientInServer (ent); - AddToTransparentList (ent); - } -} - - -/* -============== -MM_SetCaptain -============== -Set ent to be a captain of team, ent can be NULL to remove captain -*/ -void MM_SetCaptain( int teamNum, edict_t *ent ) -{ - int i; - edict_t *oldCaptain = teams[teamNum].captain; - - if (teamNum == NOTEAM) - ent = NULL; - - teams[teamNum].captain = ent; - if (esp->value) { - EspSetLeader(teamNum, ent); - } - if (!ent) { - if (!team_round_going || (gameSettings & GS_ROUNDBASED)) { - if (teams[teamNum].ready) { - char temp[128]; - Com_sprintf( temp, sizeof( temp ), "%s is no longer ready to play!", teams[teamNum].name ); - CenterPrintAll( temp ); - } - teams[teamNum].ready = 0; - } - if (oldCaptain) { - gi.bprintf( PRINT_HIGH, "%s is no longer %s's captain\n", oldCaptain->client->pers.netname, teams[teamNum].name ); - } - teams[teamNum].locked = 0; - return; - } - - if (ent != oldCaptain) { - gi.bprintf( PRINT_HIGH, "%s is now %s's captain\n", ent->client->pers.netname, teams[teamNum].name ); - gi.cprintf( ent, PRINT_CHAT, "You are the captain of '%s'\n", teams[teamNum].name ); - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex( "misc/comp_up.wav" ), 1.0, ATTN_NONE, 0.0 ); - - for (i = TEAM1; i <= teamCount; i++) { - if (i != teamNum && teams[i].wantReset) - gi.cprintf( ent, PRINT_HIGH, "Team %i wants to reset scores, type 'resetscores' to accept\n", i ); - } - } -} - -void MM_LeftTeam( edict_t *ent ) -{ - int teamNum = ent->client->resp.team; - - if (teams[teamNum].captain == ent) { - MM_SetCaptain( teamNum, NULL ); - } - ent->client->resp.subteam = 0; -} - -qboolean TeamsReady( void ) -{ - int i, ready = 0; - - for( i = TEAM1; i <= teamCount; i++ ) - { - if( teams[i].ready ) - ready ++; - else if( TeamHasPlayers(i) ) - return false; - } - return (ready >= 2); -} - -void Cmd_Captain_f(edict_t * ent) -{ - int teamNum; - edict_t *oldCaptain; - - // Aliases `captain` command to `volunteer` if Espionage is enabled - if (esp->value && !matchmode->value) { - Cmd_Volunteer_f(ent); - return; - } - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n"); - return; - } - - oldCaptain = teams[teamNum].captain; - if (oldCaptain == ent) { - MM_SetCaptain( teamNum, NULL ); - if (esp->value) { - EspSetLeader(teamNum, NULL); - } - return; - } - - if (oldCaptain) { - gi.cprintf( ent, PRINT_HIGH, "Your team already has a captain\n" ); - return; - } - - MM_SetCaptain( teamNum, ent ); - if (esp->value) { - EspSetLeader( teamNum, ent ); - } -} - -//extern int started; // AQ2:M - Matchmode - Used for ready command -void Cmd_Ready_f(edict_t * ent) -{ - char temp[128]; - int teamNum; - team_t *team; - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf( ent, PRINT_HIGH, "You need to be on a team for that...\n" ); - return; - } - - team = &teams[teamNum]; - if (team->captain != ent) { - gi.cprintf( ent, PRINT_HIGH, "You need to be a captain for that\n" ); - return; - } - - if (!(gameSettings & GS_ROUNDBASED) && team_round_going) { - if(teamdm->value) - gi.cprintf(ent, PRINT_HIGH, "You can't unready in teamdm, use 'pausegame' instead\n"); - else - gi.cprintf(ent, PRINT_HIGH, "You can't unready in ctf, use 'pausegame' instead\n"); - return; - } - - team->ready = !team->ready; - Com_sprintf( temp, sizeof( temp ), "%s %s ready to play!", team->name, (team->ready) ? "is" : "is no longer" ); - CenterPrintAll( temp ); -} - -void Cmd_Teamname_f(edict_t * ent) -{ - int i, argc, teamNum; - char temp[32]; - team_t *team; - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - if(ctf->value) { - gi.cprintf(ent, PRINT_HIGH, "You can't change teamnames in CTF mode\n"); - return; - } - - if(esp->value) { - gi.cprintf(ent, PRINT_HIGH, "You can't change teamnames in Espionage mode\n"); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf( ent, PRINT_HIGH, "You need to be on a team for that...\n" ); - return; - } - - team = &teams[teamNum]; - if (team->captain != ent) { - gi.cprintf( ent, PRINT_HIGH, "You need to be a captain for that\n" ); - return; - } - - if (team->ready) { - gi.cprintf( ent, PRINT_HIGH, "You can't use this while 'ready'\n" ); - return; - } - - if (team_round_going || team_game_going) { - gi.cprintf(ent, PRINT_HIGH, "You can't use this while playing\n"); - return; - } - - argc = gi.argc(); - if (argc < 2) { - gi.cprintf( ent, PRINT_HIGH, "Your team name is %s\n", team->name ); - return; - } - - Q_strncpyz(temp, gi.argv(1), sizeof(temp)); - for (i = 2; i < argc; i++) { - Q_strncatz(temp, " ", sizeof(temp)); - Q_strncatz(temp, gi.argv(i), sizeof(temp)); - } - temp[18] = 0; - - if (!temp[0]) - strcpy( temp, "noname" ); - - gi.dprintf("%s (team %i) is now known as %s\n", team->name, teamNum, temp); - IRC_printf(IRC_T_GAME, "%n (team %k) is now known as %n", team->name, teamNum, temp); - strcpy(team->name, temp); - gi.cprintf(ent, PRINT_HIGH, "New team name: %s\n", team->name); - -} - -void Cmd_Teamskin_f(edict_t * ent) -{ - char *s, newskin[32]; - int i, teamNum; - team_t *team; - edict_t *e; - - if (!esp->value) { - gi.cprintf(ent, PRINT_HIGH, "Espionage skins are set in the .esp file\n"); - return; - } - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n"); - return; - } - - team = &teams[teamNum]; - if (team->captain != ent) { - gi.cprintf(ent, PRINT_HIGH, "You need to be a captain for that\n"); - return; - } - if (team->ready) { - gi.cprintf(ent, PRINT_HIGH, "You can't use this while 'Ready'\n"); - return; - } - if (team_round_going || team_game_going) { - gi.cprintf(ent, PRINT_HIGH, "You can't use this while playing\n"); - return; - } - if (gi.argc() < 2) { - gi.cprintf(ent, PRINT_HIGH, "Your team skin is %s\n", team->skin); - return; - } - - s = gi.argv(1); - Q_strncpyz(newskin, s, sizeof(newskin)); - if(ctf->value) { - s = strchr(newskin, '/'); - if(s) - s[1] = 0; - else - strcpy(newskin, "male/"); - Q_strncatz(newskin, teamNum == 1 ? CTF_TEAM1_SKIN : CTF_TEAM2_SKIN, sizeof(newskin)); - } - - if (!strcmp(newskin, team->skin)) { - gi.cprintf(ent, PRINT_HIGH, "Your team skin is already %s\n", newskin); - return; - } - - Q_strncpyz(team->skin, newskin, sizeof(team->skin)); - - Com_sprintf(team->skin_index, sizeof(team->skin_index), "../players/%s_i", team->skin ); - level.pic_teamskin[teamNum] = gi.imageindex(team->skin_index); - for (i = 0, e = &g_edicts[1]; i < game.maxclients; i++, e++) { //lets update players skin - if (!e->inuse || !e->client) - continue; - - if (e->client->resp.team == teamNum) - AssignSkin(e, team->skin, false); - } - gi.cprintf(ent, PRINT_HIGH, "New team skin: %s\n", team->skin); -} - -void Cmd_TeamLock_f(edict_t *ent, int a_switch) -{ - char msg[128], *s; - int teamNum, i; - team_t *team; - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - if (!mm_allowlock->value) { - gi.cprintf(ent, PRINT_HIGH, "Team locking is disabled on this server\n"); - return; - } - - //Admin can lock teams - if (ent->client->pers.admin && gi.argc() > 1) - { - s = gi.argv(1); - teamNum = TP_GetTeamFromArg(s); - if (teamNum < 1) { - gi.cprintf(ent, PRINT_HIGH, "Unknown team '%s'.\n", s); - return; - } - team = &teams[teamNum]; - if (a_switch == team->locked) { - gi.cprintf(ent, PRINT_HIGH, "Team %s locked\n", (a_switch) ? "is already" : "isn't"); - return; - } - if (a_switch) { - gclient_t *client; - - for (i = 0, client = game.clients; i < game.maxclients; i++, client++) { - if (client->pers.connected && client->resp.team == teamNum) - break; - } - if (i == game.maxclients) { - gi.cprintf(ent, PRINT_HIGH, "You can't lock teams without players\n"); - return; - } - } - } - else - { - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You are not on a team\n"); - return; - } - - team = &teams[teamNum]; - if (team->captain != ent) { - gi.cprintf(ent, PRINT_HIGH, "You are not the captain of your team\n"); - return; - } - - if (a_switch == team->locked) { - gi.cprintf(ent, PRINT_HIGH, "Your team %s locked\n", (a_switch) ? "is already" : "isn't"); - return; - } - } - - team->locked = a_switch; - Com_sprintf( msg, sizeof( msg ), "%s is now %s", team->name, (a_switch) ? "locked" : "unlocked" ); - CenterPrintAll(msg); -} - -void Cmd_SetAdmin_f (edict_t * ent) -{ - if (ent->client->pers.admin) { - gi.cprintf( ent, PRINT_HIGH, "You are no longer a match admin.\n" ); - gi.dprintf( "%s is no longer a match admin\n", ent->client->pers.netname ); - ent->client->pers.admin = 0; - } - - if(!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "Matchmode is not enabled on this server.\n"); - return; - } - - if (strcmp( mm_adminpwd->string, "0" ) == 0) { - gi.cprintf( ent, PRINT_HIGH, "Match admin mode is not enabled on this server..\n" ); - return; - } - - if (gi.argc() < 2) { - gi.cprintf (ent, PRINT_HIGH, "Usage: matchadmin \n"); - return; - } - - if (strcmp( mm_adminpwd->string, gi.argv(1) )) { - gi.cprintf( ent, PRINT_HIGH, "Wrong password\n" ); - return; - } - - gi.cprintf (ent, PRINT_HIGH, "You are now a match admin.\n"); - gi.dprintf ("%s is now a match admin\n", ent->client->pers.netname); - IRC_printf (IRC_T_GAME, "%n is now a match admin", ent->client->pers.netname); - ent->client->pers.admin = 1; -} - -void Cmd_ResetScores_f(edict_t * ent) -{ - int i, teamNum, otherCaptain = 0; - - if (!matchmode->value) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - if (ent->client->pers.admin) //Admins can resetscores - { - ResetScores(true); - gi.bprintf(PRINT_HIGH, "Scores and time were reset by match admin %s\n", ent->client->pers.netname); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n"); - return; - } - if (teams[teamNum].captain != ent) { - gi.cprintf(ent, PRINT_HIGH, "You need to be a captain for that\n"); - return; - } - - if (teams[teamNum].wantReset) - { - teams[teamNum].wantReset = 0; - for (i = TEAM1; ivalue) { - gi.cprintf(ent, PRINT_HIGH, "This command needs matchmode to be enabled\n"); - return; - } - - if ((int)mm_pausecount->value < 1) { - gi.cprintf(ent, PRINT_HIGH, "Pause is disabled, mm_pausecount is 0\n"); - return; - } - - if (mm_pausetime->value < FRAMETIME) { - gi.cprintf( ent, PRINT_HIGH, "Pause is disabled, mm_pausetime is 0\n" ); - return; - } - - teamNum = ent->client->resp.team; - if (teamNum == NOTEAM) { - gi.cprintf(ent, PRINT_HIGH, "You need to be on a team for that...\n"); - return; - } - - if (!team_round_going) { - gi.cprintf(ent, PRINT_HIGH, "No match running, so why pause?\n"); - //return; - } - - if (ent->client->resp.subteam) { - gi.cprintf(ent, PRINT_HIGH, "You can't pause when substitute\n"); - return; - } - - if(pause) - { - if(level.pauseFrames > 0) - { - gi.cprintf(ent, PRINT_HIGH, "Game is already paused you silly\n"); - return; - } - if (level.intermission_framenum) { - gi.cprintf(ent, PRINT_HIGH, "Can't pause in an intermission.\n"); - return; - } - if(teams[teamNum].pauses_used >= (int)mm_pausecount->value) - { - gi.cprintf(ent, PRINT_HIGH, "Your team doesn't have any pauses left.\n"); - return; - } - teams[teamNum].pauses_used++; - - CenterPrintAll (va("Game paused by %s\nTeam %i has %i pauses left", ent->client->pers.netname, ent->client->resp.team, (int)mm_pausecount->value - teams[ent->client->resp.team].pauses_used)); - level.pauseFrames = (int)(mm_pausetime->value * 60.0f * HZ); - lastPaused = teamNum; - } - else - { - if (!level.pauseFrames) - { - gi.cprintf(ent, PRINT_HIGH, "Game is not paused\n"); - return; - } - if(!lastPaused) - { - gi.cprintf(ent, PRINT_HIGH, "Already unpausing\n"); - return; - } - if(lastPaused != teamNum) - { - gi.cprintf(ent, PRINT_HIGH, "You can't unpause when paused by the other team\n"); - return; - } - level.pauseFrames = 10 * HZ; - lastPaused = 0; - } -} - diff --git a/actionlite/a_match.h b/actionlite/a_match.h deleted file mode 100644 index d937e7e..0000000 --- a/actionlite/a_match.h +++ /dev/null @@ -1,17 +0,0 @@ -#define IS_CAPTAIN(ent) (teams[(ent)->client->resp.team].captain == (ent)) -#define HAVE_CAPTAIN(teamNum) (teams[(teamNum)].captain) - -void SendScores (void); -bool TeamsReady( void ); -void MM_LeftTeam( edict_t * ent ); -void Cmd_Captain_f (edict_t * ent); -void Cmd_Ready_f (edict_t * ent); -void Cmd_Sub_f (edict_t * ent); -void Cmd_Teamname_f (edict_t * ent); -void Cmd_Teamskin_f (edict_t * ent); -void Cmd_TeamLock_f (edict_t * ent, int a_switch); -int CheckForCaptains (int cteam); - -void Cmd_SetAdmin_f (edict_t * ent); -void Cmd_TogglePause_f(edict_t * ent, bool pause); -void Cmd_ResetScores_f(edict_t * ent); diff --git a/actionlite/a_radio.cpp b/actionlite/a_radio.cpp deleted file mode 100644 index ac6244a..0000000 --- a/actionlite/a_radio.cpp +++ /dev/null @@ -1,817 +0,0 @@ -//----------------------------------------------------------------------------- -// Radio-related code for Action (formerly Axshun) -// -// -Fireblade -// -// $Id: a_radio.c,v 1.6 2004/04/08 23:19:51 slicerdw Exp $ -// -//----------------------------------------------------------------------------- -// $Log: a_radio.c,v $ -// Revision 1.6 2004/04/08 23:19:51 slicerdw -// Optimized some code, added a couple of features and fixed minor bugs -// -// Revision 1.5 2002/03/26 21:49:01 ra -// Bufferoverflow fixes -// -// Revision 1.4 2001/09/28 13:48:34 ra -// I ran indent over the sources. All .c and .h files reindented. -// -// Revision 1.3 2001/09/05 14:33:57 slicerdw -// Added Fix's from the 2.1 release -// -// Revision 1.2 2001/08/15 14:50:48 slicerdw -// Added Flood protections to Radio & Voice, Fixed the sniper bug AGAIN -// -// Revision 1.1.1.1 2001/05/06 17:24:29 igor_rock -// This is the PG Bund Edition V1.25 with all stuff laying around here... -// -//----------------------------------------------------------------------------- - -#include "g_local.h" - -void Cmd_Say_f (edict_t * ent, qboolean team, qboolean arg0, - qboolean partner_msg); - -// Each of the possible radio messages and their length -typedef struct radio_msg_s - -{ - - char *msg; // the msg name - - - - int length; // length in server frames (ie tenths of a second), rounded up - - int sndIndex; - - - -} radio_msg_t; - -static radio_msg_t male_radio_msgs[] = { - {"1", 6, 0}, - {"2", 6, 0}, - {"3", 8, 0}, - {"4", 7, 0}, - {"5", 8, 0}, - {"6", 9, 0}, - {"7", 8, 0}, - {"8", 7, 0}, - {"9", 7, 0}, - {"10", 6, 0}, - {"back", 6, 0}, - {"cover", 7, 0}, - {"down", 13, 0}, - {"enemyd", 10, 0}, - {"enemys", 9, 0}, - {"forward", 6, 0}, - {"go", 6, 0}, - {"im_hit", 7, 0}, - {"left", 7, 0}, - {"reportin", 9, 0}, - {"right", 6, 0}, - {"taking_f", 22, 0}, - {"teamdown", 13, 0}, - {"treport", 12, 0}, - {"up", 4, 0} - //{"END", 0, 0} // end of list delimiter -}; - -static radio_msg_t female_radio_msgs[] = { - {"1", 5, 0}, - {"2", 5, 0}, - {"3", 5, 0}, - {"4", 5, 0}, - {"5", 5, 0}, - {"6", 8, 0}, - {"7", 7, 0}, - {"8", 5, 0}, - {"9", 5, 0}, - {"10", 5, 0}, - {"back", 6, 0}, - {"cover", 5, 0}, - {"down", 6, 0}, - {"enemyd", 9, 0}, - {"enemys", 9, 0}, - {"forward", 8, 0}, - {"go", 6, 0}, - {"im_hit", 7, 0}, - {"left", 8, 0}, - {"reportin", 9, 0}, - {"right", 5, 0}, - {"taking_f", 22, 0}, - {"teamdown", 10, 0}, - {"treport", 12, 0}, - {"up", 6, 0} - //{"END", 0, 0}, // end of list delimiter -}; - -static const int numMaleSnds = ( sizeof( male_radio_msgs ) / sizeof( male_radio_msgs[0] ) ); -static const int numFemaleSnds = ( sizeof( female_radio_msgs ) / sizeof( female_radio_msgs[0] ) ); - -#define RADIO_MALE_DIR "radio/male/" -#define RADIO_FEMALE_DIR "radio/female/" -#define RADIO_CLICK 0 -#define RADIO_DEATH_MALE 1 -#define RADIO_DEATH_FEMALE 2 - -radio_msg_t globalRadio[] = { - {"radio/click.wav", 2, 0}, - {"radio/male/rdeath.wav", 27, 0}, - {"radio/female/rdeath.wav", 30, 0} -}; - -void PrecacheRadioSounds () -{ - int i; - char path[MAX_QPATH]; - - globalRadio[RADIO_CLICK].sndIndex = gi.soundindex(globalRadio[RADIO_CLICK].msg); - globalRadio[RADIO_DEATH_MALE].sndIndex = gi.soundindex(globalRadio[RADIO_DEATH_MALE].msg); - globalRadio[RADIO_DEATH_FEMALE].sndIndex = gi.soundindex(globalRadio[RADIO_DEATH_FEMALE].msg); - - //male - for(i = 0; i < numMaleSnds; i++) - { - Com_sprintf (path, sizeof(path), "%s%s.wav", RADIO_MALE_DIR, male_radio_msgs[i].msg); - male_radio_msgs[i].sndIndex = gi.soundindex(path); - } - - //female - for(i = 0; i < numFemaleSnds; i++) - { - Com_sprintf (path, sizeof(path), "%s%s.wav", RADIO_FEMALE_DIR, female_radio_msgs[i].msg); - female_radio_msgs[i].sndIndex = gi.soundindex(path); - } -} - -static void DeleteRadioQueueEntry( radio_t *radio, int entry_num ) -{ - int i; - - if (radio->queue_size <= entry_num) - { - gi.dprintf("DeleteRadioQueueEntry: attempt to delete out of range queue entry: %i\n", entry_num); - return; - } - - for (i = entry_num + 1; i < radio->queue_size; i++) - { - memcpy(&radio->queue[i - 1], &radio->queue[i], sizeof(radio_queue_entry_t)); - } - - radio->queue_size--; -} - -// RadioThink should be called once on each player per server frame. -void RadioThink (edict_t * ent) -{ - radio_t *radio = &ent->client->resp.radio; - - // Try to clean things up, a bit.... - if (radio->partner) - { - if (!radio->partner->inuse || - radio->partner->client->resp.radio.partner != ent) - { - radio->partner = NULL; - } - } - if (radio->partner_last_offered_to) - { - if (!radio->partner_last_offered_to->inuse || - radio->partner_last_offered_to->solid == SOLID_NOT) - { - radio->partner_last_offered_to = NULL; - } - } - if (radio->partner_last_denied_from) - { - if (!radio->partner_last_denied_from->inuse || - radio->partner_last_denied_from->solid == SOLID_NOT) - { - radio->partner_last_denied_from = NULL; - } - } - // ................................ - - if (radio->power_off) - { - radio->queue_size = 0; - return; - } - - if (radio->delay > 0) - { - radio->delay--; - if (radio->delay) - return; - } - - - if (radio->queue_size) - { - edict_t *from; - int check; - - from = radio->queue[0].from_player; - - if (!radio->queue[0].click && (!from->inuse || !IS_ALIVE(from))) - { - if (radio->queue[0].from_gender) - { - radio->queue[0].sndIndex = globalRadio[RADIO_DEATH_FEMALE].sndIndex; - radio->queue[0].length = globalRadio[RADIO_DEATH_FEMALE].length; - } - else - { - radio->queue[0].sndIndex = globalRadio[RADIO_DEATH_MALE].sndIndex; - radio->queue[0].length = globalRadio[RADIO_DEATH_MALE].length; - } - - for (check = 1; check < radio->queue_size; check++) - { - if (!radio->queue[check].click && radio->queue[check].from_player == from) - { - DeleteRadioQueueEntry( radio, check ); - check--; - } - } - } - - if( ! IsInIgnoreList( ent, from ) ) - { - unicastSound( ent, radio->queue[0].sndIndex, 1.0 ); - radio->delay = radio->queue[0].length; - } - DeleteRadioQueueEntry( radio, 0 ); //We can remove it here? - } -} - -static void AppendRadioMsgToQueue( radio_t *radio, int sndIndex, int len, int click, edict_t *from_player ) -{ - radio_queue_entry_t *newentry; - - if (radio->queue_size >= MAX_RADIO_QUEUE_SIZE) - { - gi.dprintf("AppendRadioMsgToQueue: Maximum radio queue size exceeded\n"); - return; - } - - newentry = &radio->queue[radio->queue_size]; - - newentry->sndIndex = sndIndex; - newentry->from_player = from_player; - newentry->from_gender = from_player->client->resp.radio.gender; - newentry->length = len; - newentry->click = click; - - radio->queue_size++; -} - -static void InsertRadioMsgInQueueBeforeClick( radio_t *radio, int sndIndex, int len, edict_t *from_player ) -{ - radio_queue_entry_t *newentry; - - if (radio->queue_size >= MAX_RADIO_QUEUE_SIZE) - { - gi.dprintf("InsertRadioMsgInQueueBeforeClick: Maximum radio queue size exceeded\n"); - return; - } - - newentry = &radio->queue[radio->queue_size - 1]; - - memcpy( &radio->queue[radio->queue_size], newentry, sizeof(radio_queue_entry_t)); - - newentry->sndIndex = sndIndex; - newentry->from_player = from_player; - newentry->from_gender = from_player->client->resp.radio.gender; - newentry->length = len; - newentry->click = 0; - - radio->queue_size++; -} - -static void AddRadioMsg( radio_t *radio, int sndIndex, int len, edict_t *from_player ) -{ - if (radio->queue_size == 0) - { - AppendRadioMsgToQueue( radio, globalRadio[RADIO_CLICK].sndIndex, globalRadio[RADIO_CLICK].length, 1, from_player ); - AppendRadioMsgToQueue( radio, sndIndex, len, 0, from_player ); - AppendRadioMsgToQueue( radio, globalRadio[RADIO_CLICK].sndIndex, globalRadio[RADIO_CLICK].length, 1, from_player ); - } - else // we have some msgs in it already... - { - if (radio->queue_size < MAX_RADIO_QUEUE_SIZE) - InsertRadioMsgInQueueBeforeClick( radio, sndIndex, len, from_player ); - // else ignore the message... - } -} - -void RadioBroadcast (edict_t * ent, int partner, char *msg) -{ - int j, i, msg_len, numSnds; - edict_t *other; - radio_msg_t *radio_msgs; - int msg_soundIndex = 0; - char msgname_num[8], filteredmsg[48]; - qboolean found = false; - radio_t *radio; - - if (!IS_ALIVE(ent)) - return; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - radio = &ent->client->resp.radio; - if (radio->power_off) - { - gi.centerprintf (ent, "Your radio is off!"); - return; - } - - if (partner && radio->partner == NULL) - { - gi.cprintf (ent, PRINT_HIGH, "You don't have a partner.\n"); - return; - } - - if (radio->gender) - { - radio_msgs = female_radio_msgs; - numSnds = numFemaleSnds; - } - else - { - radio_msgs = male_radio_msgs; - numSnds = numMaleSnds; - } - - i = found = 0; - msg_len = 0; - - Q_strncpyz(filteredmsg, msg, sizeof(filteredmsg)); - - for(i = 0; i < numSnds; i++) - { - if (!Q_stricmp(radio_msgs[i].msg, filteredmsg)) - { - found = true; - msg_soundIndex = radio_msgs[i].sndIndex; - msg_len = radio_msgs[i].length; - break; - } - } - - if (!found) - { - gi.centerprintf (ent, "'%s' is not a valid radio message", filteredmsg); - return; - } - - if (radiolog->value) - { - gi.cprintf (NULL, PRINT_CHAT, "[%s RADIO] %s: %s\n", - partner ? "PARTNER" : "TEAM", ent->client->pers.netname, filteredmsg); - } - - //TempFile BEGIN - if (Q_stricmp (filteredmsg, "enemyd") == 0) - { - if (ent->client->radio_num_kills > 1 && ent->client->radio_num_kills <= 10) - { - // If we are reporting enemy down, add the number of kills. - sprintf( msgname_num, "%i", ent->client->radio_num_kills ); - ent->client->radio_num_kills = 0; // prevent from getting into an endless loop - - RadioBroadcast(ent, partner, msgname_num); // Now THAT'S recursion! =) - } - ent->client->radio_num_kills = 0; - } -//TempFile END - //AQ2:TNG Slicer - if (radio_repeat->value) - { //SLIC2 Optimization - if (CheckForRepeat (ent, i) == false) - return; - } - - if (radio_max->value) - { - if (CheckForFlood (ent) == false) - return; - } - - - //AQ2:TNG END - for (j = 1; j <= game.maxclients; j++) - { - other = &g_edicts[j]; - if (!other->inuse) - continue; - if (!other->client) - continue; - if (!OnSameTeam(ent, other)) - continue; - if (partner && other != radio->partner) - continue; - AddRadioMsg( &other->client->resp.radio, msg_soundIndex, msg_len, ent ); - } -} - -void Cmd_Radio_f (edict_t * ent) -{ - RadioBroadcast(ent, ent->client->resp.radio.partner_mode, gi.args()); -} - -void Cmd_Radiopartner_f (edict_t * ent) -{ - RadioBroadcast(ent, 1, gi.args()); -} - -void Cmd_Radioteam_f (edict_t * ent) -{ - RadioBroadcast(ent, 0, gi.args()); -} - -void Cmd_Radiogender_f (edict_t * ent) -{ - char *arg; - radio_t *radio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - radio = &ent->client->resp.radio; - arg = gi.args(); - if (arg == NULL || !*arg) - { - if (radio->gender) - gi.cprintf (ent, PRINT_HIGH, "Radio gender currently set to female\n"); - else - gi.cprintf (ent, PRINT_HIGH, "Radio gender currently set to male\n"); - return; - } - - if (!Q_stricmp(arg, "male")) - { - gi.cprintf (ent, PRINT_HIGH, "Radio gender set to male\n"); - radio->gender = 0; - } - else if (!Q_stricmp(arg, "female")) - { - gi.cprintf (ent, PRINT_HIGH, "Radio gender set to female\n"); - radio->gender = 1; - } - else - { - gi.cprintf (ent, PRINT_HIGH, "Invalid gender selection, try 'male' or 'female'\n"); - } -} - -void Cmd_Radio_power_f (edict_t * ent) -{ - radio_t *radio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - radio = &ent->client->resp.radio; - - radio->power_off = !radio->power_off; - - - - gi.centerprintf(ent, "Radio switched %s", (radio->power_off) ? "off" : "on"); - - unicastSound(ent, globalRadio[RADIO_CLICK].sndIndex, 1.0); -} - -void Cmd_Channel_f (edict_t * ent) -{ - radio_t *radio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - radio = &ent->client->resp.radio; - - radio->partner_mode = !radio->partner_mode; - if (radio->partner_mode) - { - gi.centerprintf (ent, "Channel set to 1, partner channel"); - } - else - { - gi.centerprintf (ent, "Channel set to 0, team channel"); - } -} - -edict_t *DetermineViewedPlayer(edict_t *ent, qboolean teammate); - -void Cmd_Partner_f (edict_t * ent) -{ - edict_t *target; - char *genderstr; - radio_t *radio, *tRadio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - if (!IS_ALIVE(ent)) - return; - - radio = &ent->client->resp.radio; - if (radio->partner) { - - if (radio->partner->inuse) { - - gi.centerprintf( ent, "You already have a partner, %s", radio->partner->client->pers.netname ); - - return; - - } - - // just in case RadioThink hasn't caught it yet... avoid any problems - - radio->partner = NULL; - - } - - target = DetermineViewedPlayer(ent, true); - if (target == NULL) { - gi.centerprintf (ent, "No potential partner selected"); - return; - } - - tRadio = &target->client->resp.radio; - if (tRadio->partner) { - gi.centerprintf (ent, "%s already has a partner", target->client->pers.netname); - return; - } - - if (tRadio->partner_last_offered_to == ent && - radio->partner_last_offered_from == target) - { - gi.centerprintf (ent, "%s is now your partner", target->client->pers.netname); - gi.centerprintf (target, "%s is now your partner", ent->client->pers.netname); - radio->partner = target; - tRadio->partner = ent; - radio->partner_last_offered_from = NULL; - tRadio->partner_last_offered_to = NULL; - return; - } - - if (tRadio->partner_last_denied_from == ent) - { - gi.centerprintf (ent, "%s has already denied you", target->client->pers.netname); - return; - } - - if (target == radio->partner_last_offered_to) - { - genderstr = GENDER_STR(target, "him", "her", "it"); - gi.centerprintf (ent, "Already awaiting confirmation from %s", genderstr); - return; - } - - genderstr = GENDER_STR(ent, "him", "her", "it"); - - gi.centerprintf (ent, "Awaiting confirmation from %s", target->client->pers.netname); - gi.centerprintf (target, - "%s offers to be your partner\n" - "To accept:\nView %s and use the 'partner' command\n" - "To deny:\nUse the 'deny' command", - ent->client->pers.netname, genderstr); - - radio->partner_last_offered_to = target; - tRadio->partner_last_offered_from = ent; -} - -void Cmd_Unpartner_f (edict_t * ent) -{ - edict_t *target; - radio_t *radio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - radio = &ent->client->resp.radio; - if (radio->partner && !radio->partner->inuse) - { // just in case RadioThink hasn't caught it yet... avoid any problems - radio->partner = NULL; - } - - target = radio->partner; - if (target == NULL) { - gi.centerprintf (ent, "You don't have a partner"); - return; - } - - if (target->client->resp.radio.partner == ent) - { - gi.centerprintf (target, "%s broke your partnership", ent->client->pers.netname); - target->client->resp.radio.partner = NULL; - } - - gi.centerprintf (ent, "You broke your partnership with %s", target->client->pers.netname); - radio->partner = NULL; -} - -void Cmd_Deny_f (edict_t * ent) -{ - edict_t *target; - radio_t *radio; - - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - if (!IS_ALIVE(ent)) - return; - - radio = &ent->client->resp.radio; - target = radio->partner_last_offered_from; - if (target && target->inuse) - { - gi.centerprintf (ent, "You denied %s", target->client->pers.netname); - gi.centerprintf (target, "%s has denied you", ent->client->pers.netname); - radio->partner_last_denied_from = target; - - radio->partner_last_offered_from = NULL; - if (target->client->resp.radio.partner_last_offered_to == ent) - - target->client->resp.radio.partner_last_offered_to = NULL; - } - else - { - gi.centerprintf (ent, "No one has offered to be your partner"); - return; - } -} - -void Cmd_Say_partner_f (edict_t * ent) -{ - if (!teamplay->value) - { - if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) )) - return; // don't allow in a non-team setup... - } - - if (ent->client->resp.radio.partner == NULL) - { - gi.cprintf (ent, PRINT_HIGH, "You don't have a partner.\n"); - return; - } - - Cmd_Say_f (ent, false, false, true); -} - -//SLIC2 Redesigned and optimized these two functions - -qboolean CheckForFlood( edict_t * ent ) - -{ - - radio_t *radio = &ent->client->resp.radio; - - //If he's muted.. - - if (radio->rd_mute) { - - if (radio->rd_mute > level.framenum) // Still muted.. - - return false; - - - - radio->rd_mute = 0; // No longer muted.. - - } - - if (!radio->rd_Count) { - - radio->rd_time = level.framenum; - - radio->rd_Count++; - - } - - else { - - if (level.framenum - radio->rd_time < (int)(radio_time->value * HZ)) { - - if (++radio->rd_Count >= (int)radio_max->value) { - - gi.cprintf( ent, PRINT_HIGH, - - "[RADIO FLOOD PROTECTION]: Flood Detected, you are silenced for %d secs\n", (int)radio_ban->value ); - - radio->rd_mute = level.framenum + (int)(radio_ban->value * HZ); - - return false; - - } - - } - - else { - - radio->rd_Count = 0; - - } - - } - - - - return true; - -} - - - -qboolean CheckForRepeat( edict_t * ent, int radioCode ) - -{ - - radio_t *radio = &ent->client->resp.radio; - - - - //If he's muted.. - - if (radio->rd_mute) { - - if (radio->rd_mute > level.framenum) // Still muted.. - - return false; - - - - radio->rd_mute = 0; // No longer muted.. - - } - - - - if (radio->rd_lastRadio == radioCode) { //He's trying to repeat it.. - - if (level.framenum - radio->rd_repTime < (int)(radio_repeat_time->value * HZ)) { - - if (++radio->rd_repCount == (int)radio_repeat->value) { //Busted - - gi.cprintf( ent, PRINT_HIGH, "[RADIO FLOOD PROTECTION]: Repeat Flood Detected, you are silenced for %d secs\n", (int)radio_ban->value ); - - radio->rd_mute = level.framenum + (int)(radio_ban->value * HZ); - - return false; - - } - - } - - else { - - radio->rd_repCount = 0; - - } - - } - - else { - - radio->rd_lastRadio = radioCode; - - radio->rd_repCount = 0; - - } - - radio->rd_repTime = level.framenum; - - return true; - -} - diff --git a/actionlite/a_radio.h b/actionlite/a_radio.h deleted file mode 100644 index f91036a..0000000 --- a/actionlite/a_radio.h +++ /dev/null @@ -1,55 +0,0 @@ -#define MAX_SOUNDFILE_PATH_LEN 32 // max length of a sound file path -#define MAX_RADIO_MSG_QUEUE_SIZE 4 -#define MAX_RADIO_QUEUE_SIZE 6 // this must be at least 2 greater than the above - -typedef struct radio_queue_entry_s -{ - int sndIndex; - edict_t *from_player; - int from_gender; // true if female - - int length; - bool click; -} radio_queue_entry_t; - - -typedef struct radio_s -{ - int delay; - radio_queue_entry_t queue[MAX_RADIO_QUEUE_SIZE]; - int queue_size; - - bool gender; // radiogender - bool power_off; // radio_power - - // Partners stuff - bool partner_mode; // 'radio' command using team or partner - edict_t *partner; // current partner - edict_t *partner_last_offered_to; // last person I offered a partnership to - edict_t *partner_last_offered_from; // last person I received a partnership offer from - edict_t *partner_last_denied_from; // last person I denied a partnership offer from - - //Flood & Repeat - int rd_mute; //Time to be muted - int rd_Count; //Counter for the last msgs in "xx" secs allowed - int rd_time; //Frame for the first radio message of the ones to follow - - int rd_lastRadio; //Code of the last radio used - int rd_repCount; //Counter for the number of repeated radio msgs - int rd_repTime; //Frame for the last repeated radio msg -} radio_t; - -void RadioThink (edict_t *); -void Cmd_Radio_f (edict_t *); -void Cmd_Radiogender_f (edict_t *); -void Cmd_Radio_power_f (edict_t *); -void Cmd_Radiopartner_f (edict_t *); -void Cmd_Radioteam_f (edict_t *); -void Cmd_Channel_f (edict_t *); -void Cmd_Say_partner_f (edict_t *); -void Cmd_Partner_f (edict_t *); -void Cmd_Deny_f (edict_t *); -void Cmd_Unpartner_f (edict_t *); -void PrecacheRadioSounds (); -bool CheckForFlood (edict_t * ent); -bool CheckForRepeat (edict_t * ent, int radioCode); diff --git a/actionlite/a_team.cpp b/actionlite/a_team.cpp deleted file mode 100644 index d167bf4..0000000 --- a/actionlite/a_team.cpp +++ /dev/null @@ -1,3064 +0,0 @@ -#include "g_local.h" -#include "cgf_sfx_glass.h" - - -bool team_game_going = false; // is a team game going right now? -bool team_round_going = false; // is an actual round of a team game going right now? - -int team_round_countdown = 0; // countdown variable for start of a round -int rulecheckfrequency = 0; // accumulator variable for checking rules every 1.5 secs -int lights_camera_action = 0; // countdown variable for "lights...camera...action!" -int timewarning = 0; // countdown variable for "x Minutes left" -int fragwarning = 0; // countdown variable for "x Frags left" -int holding_on_tie_check = 0; // when a team "wins", countdown for a bit and wait... -int current_round_length = 0; // frames that the current team round has lasted -int round_delay_time = 0; // time gap between round end and new round -int in_warmup = 0; // if warmup is currently on -bool teams_changed = false; // Need to update the join menu. - -team_t teams[TEAM_TOP]; -int teamCount = 2; -int gameSettings; - -#define MAX_SPAWNS 512 // max DM spawn points supported - -edict_t *potential_spawns[MAX_SPAWNS]; -int num_potential_spawns; -edict_t *teamplay_spawns[MAX_TEAMS]; -trace_t trace_t_temp; // used by our trace replace macro in ax_team.h - -// -int NS_num_used_farteamplay_spawns[MAX_TEAMS]; -int NS_num_potential_spawns[MAX_TEAMS]; -edict_t *NS_potential_spawns[MAX_TEAMS][MAX_SPAWNS]; -edict_t *NS_used_farteamplay_spawns[MAX_TEAMS][MAX_SPAWNS]; -int NS_randteam; -// - -void CreditsMenu (edict_t * ent, pmenu_t * p); -static transparent_list_t transparentList[MAX_CLIENTS]; -static size_t transparentEntryCount = 0; -transparent_list_t *transparent_list = NULL; -static transparent_list_t *transparentlistFree = NULL; - -void InitTransparentList( void ) -{ - transparent_list = NULL; - transparentlistFree = NULL; - transparentEntryCount = 0; -} - -void AddToTransparentList( edict_t *ent ) -{ - transparent_list_t *entry; - - if (transparentlistFree) { - entry = transparentlistFree; - transparentlistFree = entry->next; - } - else if (transparentEntryCount < MAX_CLIENTS) { - entry = &transparentList[transparentEntryCount++]; - } - else { - return; - } - - entry->ent = ent; - entry->next = transparent_list; - transparent_list = entry; -} - -void RemoveFromTransparentList( edict_t *ent ) -{ - transparent_list_t *entry, **back; - - back = &transparent_list; - - for (entry = *back; entry; entry = *back) { - if (entry->ent == ent) { - *back = entry->next; - entry->next = transparentlistFree; - transparentlistFree = entry; - return; - } - - back = &entry->next; - } -} - -void TransparentListSet( solid_t solid_type ) -{ - transparent_list_t *entry; - - for (entry = transparent_list; entry; entry = entry->next) { - if (entry->ent->solid == solid_type) - continue; - - entry->ent->solid = solid_type; - gi.linkentity( entry->ent ); - } -} - -bool OnTransparentList( const edict_t *ent ) -{ - const transparent_list_t *entry; - - for( entry = transparent_list; entry; entry = entry->next ) - { - if( entry->ent == ent ) - return true; - } - - return false; -} - -void ReprintMOTD (edict_t * ent, pmenu_t * p) -{ - PMenu_Close (ent); - PrintMOTD (ent); -} - -void PrintMatchRules () -{ - char rulesmsg[256]; - - if (!deathmatch->value) { - if (teamCount == TEAM2) { - snprintf( rulesmsg, sizeof( rulesmsg ), "%s versus: %s\n\nFrag the other team!\n", - teams[TEAM1].name, teams[TEAM2].name ); - } else if (teamCount == TEAM3) { - snprintf( rulesmsg, sizeof( rulesmsg ), "%s versus %s versus %s\n\nFrag the other team!\n", - teams[TEAM1].name, teams[TEAM2].name, teams[TEAM3].name ); - } - } else { - // If nothing else matches, just say glhf - snprintf( rulesmsg, sizeof( rulesmsg ), "Frag 'em all! Good luck and have fun!\n"); - } - CenterPrintAll(rulesmsg); -} - -void JoinTeamAuto (edict_t * ent, pmenu_t * p) -{ - int i, team = TEAM1, num1 = 0, num2 = 0, num3 = 0, score1, score2, score3; - - for (i = 0; i < game.maxclients; i++) - { - if (!g_edicts[i + 1].inuse) - continue; - if (game.clients[i].resp.team == TEAM1) - num1++; - else if (game.clients[i].resp.team == TEAM2) - num2++; - else if (game.clients[i].resp.team == TEAM3) - num3++; - } - - score1 = teams[TEAM1].score; - score2 = teams[TEAM2].score; - score3 = teams[TEAM3].score; - - // if(ctf->value) { - // CTFCalcScores(); - // GetCTFScores(&score1, &score2); - // } - - /* there are many different things to consider when selecting a team */ - if (num1 > num2 || (num1 == num2 && score1 > score2)) - team = TEAM2; - - if (teamCount == 3) - { - if (team == TEAM1) - { - if (num1 > num3 || (num1 == num3 && score1 > score3)) - team = TEAM3; - } - else - { - if (num2 > num3 || (num2 == num3 && score2 > score3)) - team = TEAM3; - } - } - - JoinTeam(ent, team, 0); -} - -void JoinTeam1 (edict_t * ent, pmenu_t * p) -{ - JoinTeam(ent, TEAM1, 0); -} - -void JoinTeam2 (edict_t * ent, pmenu_t * p) -{ - JoinTeam(ent, TEAM2, 0); -} - -void JoinTeam3 (edict_t * ent, pmenu_t * p) -{ - if (teamCount == 3) - JoinTeam(ent, TEAM3, 0); -} - -void LeaveTeams (edict_t * ent, pmenu_t * p) -{ - LeaveTeam(ent); - PMenu_Close(ent); - OpenJoinMenu(ent); -} - -void SelectWeapon2(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_MP5); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/mp5slide.wav"), 1.0); -} - -void SelectWeapon3(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_M3); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/m3in.wav"), 1.0); -} - -void SelectWeapon4(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_HANDCANNON); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/cclose.wav"), 1.0); -} - -void SelectWeapon5(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_SNIPER); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/ssgbolt.wav"), 1.0); -} - -void SelectWeapon6(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_M4); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/m4a1slide.wav"), 1.0); -} - -void SelectWeapon0(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_KNIFE); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/swish.wav"), 1.0); -} - -void SelectWeapon9(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_DUALMK23); - PMenu_Close(ent); - OpenItemMenu(ent); - unicastSound(ent, gi.soundindex("weapons/mk23slide.wav"), 1.0); -} - -void SelectItem1(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_VEST); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/veston.wav"), 1.0); -} - -void SelectItem2(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_LASERSIGHT); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/lasersight.wav"), 1.0); -} - -void SelectItem3(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_SLIPPERS); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/veston.wav"), 1.0); -} - -void SelectItem4(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_QUIET); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/screw.wav"), 1.0); -} - -void SelectItem5(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_BANDOLIER); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/veston.wav"), 1.0); -} - -void SelectItem6(edict_t *ent, pmenu_t *p) -{ - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_HELM); - PMenu_Close(ent); - unicastSound(ent, gi.soundindex("misc/veston.wav"), 1.0); -} - -// newrand returns n, where 0 >= n < top -int newrand (int top) -{ - return (int) (random () * top); -} - - -void CreditsReturnToMain (edict_t * ent, pmenu_t * p) -{ - PMenu_Close (ent); - if (teamplay->value) { - OpenJoinMenu (ent); - } -} - -//PG BUND BEGIN -void DoAGoodie (edict_t * ent, pmenuhnd_t * p) -{ - //PG BUND - unicastSound(ent, gi.soundindex("boss3/bs3idle1.wav"), 1.0); - //stuffcmd (ent, "play boss3/bs3idle1.wav"); -} -//PG BUND END - -// AQ2:TNG - Igor adding the Rock-Sound ;-) -void RockClan (edict_t * ent, pmenu_t * p) -{ - gi.cprintf (ent, PRINT_HIGH, "Let's Rock! http://www.rock-clan.de/\n"); - //PG BUND - unicastSound(ent, gi.soundindex("user/letsrock.wav"), 1.0); - //stuffcmd (ent, "play user/letsrock.wav"); -} -// AQ2:TNG - End Rock-Sound - -// AQ2:TNG Deathwatch - Just for slicer :) -void SlicersCat (edict_t * ent, pmenu_t * p) -{ - gi.cprintf (ent, PRINT_HIGH, "sLiCeR [dW] couldn't have done it without his cat!\n"); - //PG BUND - unicastSound(ent, gi.soundindex("makron/laf4.wav"), 1.0); - //stuffcmd (ent, "play makron/laf4.wav"); -} -// AQ2:TNG End - -// AQ2:TNG Deathwatch - Just for QNI ppl -void QuakeNigguhz (edict_t * ent, pmenu_t * p) -{ - gi.cprintf (ent, PRINT_HIGH, "For all the homies!\n"); - //PG BUND - unicastSound(ent, gi.soundindex("world/xian1.wav"), 1.0); - //stuffcmd (ent, "play world/xian1.wav"); -} - -// AQ2:TNG Deathwatch - Editing all menus to show the correct credits, version, names, locations, urls, etc -pmenu_t creditsmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL}, - {"*Design Team", PMENU_ALIGN_LEFT, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL}, - {"Deathwatch", PMENU_ALIGN_LEFT, DoAGoodie}, - {"Elviz", PMENU_ALIGN_LEFT, DoAGoodie}, - {"Freud [QNI]", PMENU_ALIGN_LEFT, QuakeNigguhz}, - {"Igor[Rock]", PMENU_ALIGN_LEFT, RockClan}, - {"JBravo[QNI]", PMENU_ALIGN_LEFT, QuakeNigguhz}, - {"sLiCeR [dW]", PMENU_ALIGN_LEFT, SlicersCat}, - {NULL, PMENU_ALIGN_LEFT, NULL}, - {"*Credits", PMENU_ALIGN_LEFT, NULL}, - {"(in no particular order)", PMENU_ALIGN_LEFT, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL}, - {"Clan Rock, dW, QNI & DP,", PMENU_ALIGN_LEFT, NULL}, - {"Kobra, Zarjazz,", PMENU_ALIGN_LEFT, NULL}, - {"Killerbee, Rookie[Rock],", PMENU_ALIGN_LEFT, NULL}, - {"PG Bund[Rock], Mort,", PMENU_ALIGN_LEFT, NULL}, - {"ICE-M, Palmtree,", PMENU_ALIGN_LEFT, NULL}, - {"Tempfile, Blackmonk,", PMENU_ALIGN_LEFT, NULL}, - {"Dome, Papst, Apr/ Maniac", PMENU_ALIGN_LEFT, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL}, - {"Return to main menu", PMENU_ALIGN_LEFT, CreditsReturnToMain}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL}, -//PG BUND END -}; - -pmenu_t weapmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL, NULL}, - {"Select your Weapon", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG - Igor adding wp_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "MP5/10 Submachinegun", SelectWeapon2 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "M3 Super90 Assault Shotgun", SelectWeapon3 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Handcannon", SelectWeapon4 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "SSG 3000 Sniper Rifle", SelectWeapon5 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "M4 Assault Rifle", SelectWeapon6 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Combat Knives", SelectWeapon0 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Akimbo Pistols", SelectWeapon9 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG End adding wp_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG - Slicer: changing this - //{"Leave Team", PMENU_ALIGN_LEFT, NULL, LeaveTeams}, - {"Return to Main Menu", PMENU_ALIGN_LEFT, NULL, CreditsReturnToMain}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG END - {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL, NULL}, - {"ENTER to select", PMENU_ALIGN_LEFT, NULL, NULL}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL, NULL}, -}; - -pmenu_t itemmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL, NULL}, - {"Select your Item", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG Igor adding itm_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Kevlar Vest", SelectItem1 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Laser Sight", SelectItem2 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Stealth Slippers", SelectItem3 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Silencer", SelectItem4 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Bandolier", SelectItem5 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, // "Kevlar Helmet", SelectItem6 - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Random Item", PMENU_ALIGN_LEFT, NULL, SelectRandomItem}, - //AQ2:TNG end adding itm_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL, NULL}, - {"ENTER to select", PMENU_ALIGN_LEFT, NULL, NULL}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL, NULL}, -}; - -pmenu_t itemkitmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL, NULL}, - {"Select your Item", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG Igor adding itm_flags - {KEV_NAME, PMENU_ALIGN_LEFT, NULL, NULL}, // "Kevlar Vest", SelectItem1 - {C_KIT_NAME, PMENU_ALIGN_LEFT, NULL, NULL}, // "Commando Kit", SelectKit1 - {S_KIT_NAME, PMENU_ALIGN_LEFT, NULL, NULL}, // "Stealth Kit", SelectKit2 - {A_KIT_NAME, PMENU_ALIGN_LEFT, NULL, NULL}, // "Assassin Kit", SelectKit3 - //AQ2:TNG end adding itm_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL, NULL}, - {"ENTER to select", PMENU_ALIGN_LEFT, NULL, NULL}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL, NULL}, -}; - -pmenu_t randmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Weapon menu disabled!", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"You get random weapon and item", PMENU_ALIGN_CENTER, NULL, NULL}, - {"when round begins.", PMENU_ALIGN_CENTER, NULL, NULL}, - //AQ2:TNG end adding itm_flags - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Return to Main Menu", PMENU_ALIGN_LEFT, NULL, CreditsReturnToMain}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL, NULL}, - {"ENTER to select", PMENU_ALIGN_LEFT, NULL, NULL}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL, NULL}, -}; - -//AQ2:TNG - slicer -void VotingMenu (edict_t * ent, pmenu_t * p) -{ - PMenu_Close (ent); - vShowMenu (ent, ""); -} -//AQ2:TNG END - -pmenu_t joinmenu[] = { - {"*" TNG_TITLE, PMENU_ALIGN_CENTER, NULL, NULL}, - {"\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F", PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL /* lvl name */ , PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL, PMENU_ALIGN_CENTER, NULL, NULL}, - {NULL /* team 1 */ , PMENU_ALIGN_LEFT, NULL, JoinTeam1}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL /* team 2 */ , PMENU_ALIGN_LEFT, NULL, JoinTeam2}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL /* team 3 */ , PMENU_ALIGN_LEFT, NULL, JoinTeam3}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL /* auto-join */ , PMENU_ALIGN_LEFT, NULL, JoinTeamAuto}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - //AQ2:TNG - Slicer - {"Voting & Ignoring Menus", PMENU_ALIGN_LEFT, NULL, VotingMenu}, - //AQ2:TNG END - {"MOTD", PMENU_ALIGN_LEFT, NULL, ReprintMOTD}, - {"Credits", PMENU_ALIGN_LEFT, NULL, CreditsMenu}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL, NULL}, - {"ENTER to select", PMENU_ALIGN_LEFT, NULL, NULL}, - {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL, NULL}, - {NULL, PMENU_ALIGN_LEFT, NULL, NULL}, - {"v" VERSION, PMENU_ALIGN_RIGHT, NULL, NULL}, -}; -// AQ2:TNG End - -void CreditsMenu (edict_t * ent, pmenu_t * p) -{ - PMenu_Close (ent); - PMenu_Open (ent, creditsmenu, 4, sizeof (creditsmenu) / sizeof (pmenu_t)); - unicastSound(ent, gi.soundindex("world/elv.wav"), 1.0); -} - -void killPlayer( edict_t *ent, bool suicidePunish ) -{ - if (!IS_ALIVE(ent)) - return; - - if (suicidePunish && punishkills->value) - { - edict_t *attacker = ent->client->attacker; - if (attacker && attacker != ent && attacker->client) - { - char deathmsg[128]; - snprintf( deathmsg, sizeof( deathmsg ), "%s ph34rs %s so much %s committed suicide! :)\n", - ent->client->pers.netname, attacker->client->pers.netname, - ent->client->pers.gender ? "she" : "he"); - - PrintDeathMessage( deathmsg, ent ); - - if (team_round_going || !OnSameTeam( ent, ent->client->attacker )) { - Add_Frag( ent->client->attacker, MOD_SUICIDE ); - Subtract_Frag( ent ); - Add_Death( ent, true ); - } - } - } - - ent->flags &= ~FL_GODMODE; - ent->health = 0; - meansOfDeath = MOD_SUICIDE; - player_die(ent, ent, ent, 100000, vec3_origin); - ent->deadflag = DEAD_DEAD; -} - -char *TeamName (int team) -{ - if (team >= TEAM1 && team <= TEAM3) - return teams[team].name; - else - return "None"; -} - -void AssignSkin (edict_t * ent, const char *s, bool nickChanged) -{ - int playernum = ent - g_edicts - 1; - char *p; - char t[MAX_SKINLEN], skin[64] = "\0"; - const char *default_skin = "male/grunt"; - - if( force_skin->string[0] ) - { - s = force_skin->string; - default_skin = force_skin->string; - } - - if( (ctf->value || dom->value) && ! matchmode->value ) - { - // forcing CTF model - if(ctf_model->string[0]) { - /* copy at most bytes that the skin name itself fits in with the delimieter and NULL */ - Q_strncpyz( t, ctf_model->string, MAX_SKINLEN-strlen(CTF_TEAM1_SKIN)-1 ); - Q_strncatz(t, "/", sizeof(t)); - } else { - Q_strncpyz(t, s, sizeof(t)); - } - - if ((p = strrchr (t, '/')) != NULL) - p[1] = 0; - else - strcpy (t, "male/"); - - switch (ent->client->resp.team) - { - case TEAM1: - snprintf(skin, sizeof(skin), "%s\\%s%s", ent->client->pers.netname, t, CTF_TEAM1_SKIN); - break; - case TEAM2: - snprintf(skin, sizeof(skin), "%s\\%s%s", ent->client->pers.netname, t, CTF_TEAM2_SKIN); - break; - default: - snprintf(skin, sizeof(skin), "%s\\%s", ent->client->pers.netname, default_skin); - break; - } - } - else - { - switch (ent->client->resp.team) - { - case TEAM1: - case TEAM2: - case TEAM3: - snprintf(skin, sizeof(skin), "%s\\%s", ent->client->pers.netname, teams[ent->client->resp.team].skin); - break; - default: - snprintf(skin, sizeof(skin), "%s\\%s", ent->client->pers.netname, (teamplay->value ? default_skin : s)); - break; - } - } - - gi.configstring(CS_PLAYERSKINS + playernum, skin); -} - -/* -============== -TP_GetTeamFromArgs -============== -*/ -int TP_GetTeamFromArg(const char *name) -{ - int i; - - if (!name || !*name) - return -1; - - if (!name[1]) - { - i = Q_tolower(name[0]); - if (i == '1' || i == 'a') - return TEAM1; - - if (i == '2' || i == 'b') - return TEAM2; - - if (teamCount > 2 && (i == '3' || i == 'c')) - return TEAM3; - - if (i == '0' || i == 's') - return NOTEAM; - } - - for (i = TEAM1; i <= teamCount; i++) { - if (!Q_stricmp(name, teams[i].name)) - return i; - } - - if (!Q_stricmp(name, "none") || !Q_stricmp(name, "spec")) - return NOTEAM; - - if (ctf->value) - { - if (!Q_stricmp(name, "red")) - return TEAM1; - if (!Q_stricmp(name, "blue")) - return TEAM2; - } - - return -1; -} - -void Team_f (edict_t * ent) -{ - char *t; - int desired_team = NOTEAM; - char team[24]; - - if (!teamplay->value) - return; - - Q_strncpyz(team, gi.args(), sizeof(team)); - t = team; - // t = gi.args (); - if (!*t) - { - if (ctf->value) - gi.cprintf(ent, PRINT_HIGH, "You are on %s.\n", CTFTeamName(ent->client->resp.team)); - else - gi.cprintf(ent, PRINT_HIGH, "You are on %s.\n", TeamName(ent->client->resp.team)); - - return; - } - - if( (ent->client->resp.joined_team > 0) && (level.realFramenum - ent->client->resp.joined_team < 5 * HZ) ) - { - gi.cprintf(ent, PRINT_HIGH, "You must wait 5 seconds before changing teams again.\n"); - return; - } - - desired_team = TP_GetTeamFromArg(t); - if (desired_team == -1) { - gi.cprintf(ent, PRINT_HIGH, "Unknown team '%s'.\n", t); - return; - } - - if (desired_team == NOTEAM) - { - if (ent->client->resp.team == NOTEAM) - gi.cprintf(ent, PRINT_HIGH, "You're not on a team.\n"); - else - LeaveTeam(ent); - - return; - } - - if (ent->client->resp.team == desired_team) { - gi.cprintf(ent, PRINT_HIGH, "You are already on %s.\n", TeamName(ent->client->resp.team)); - return; - } - - JoinTeam(ent, desired_team, 1); -} - -void JoinTeam (edict_t * ent, int desired_team, int skip_menuclose) -{ - char *s, *a; - int oldTeam; - - if (!skip_menuclose) - PMenu_Close (ent); - - oldTeam = ent->client->resp.team; - if (oldTeam == desired_team || ent->client->pers.mvdspec) - return; - - if (matchmode->value) - { - if (mm_allowlock->value && teams[desired_team].locked) { - if (skip_menuclose) - gi.cprintf(ent, PRINT_HIGH, "Cannot join %s (locked)\n", TeamName(desired_team)); - else - gi.LocCenter_Print(ent, "Cannot join %s (locked)", TeamName(desired_team)); - - return; - } - } - else - { - if(eventeams->value && desired_team != NOTEAM) { - if(!IsAllowedToJoin(ent, desired_team)) { - gi.LocCenter_Print(ent, "Cannot join %s (has too many players)", TeamName(desired_team)); - return; - } - } - } - - MM_LeftTeam( ent ); - - a = (oldTeam == NOTEAM) ? "joined" : "changed to"; - - ent->client->resp.team = desired_team; - s = Info_ValueForKey (ent->client->pers.userinfo, "skin"); - AssignSkin(ent, s, false); - - ent->flags &= ~FL_GODMODE; - killPlayer(ent, true); - - if (ctf->value) - { - ent->client->resp.ctf_state = CTF_STATE_START; - gi.LocBroadcast_Print (PRINT_HIGH, "%s %s %s.\n", ent->client->pers.netname, a, CTFTeamName(desired_team)); - } - else - { - gi.LocBroadcast_Print (PRINT_HIGH, "%s %s %s.\n", ent->client->pers.netname, a, TeamName(desired_team)); - } - - ent->client->resp.joined_team = level.realFramenum; - - if (oldTeam == NOTEAM || desired_team == NOTEAM) { - G_UpdatePlayerStatusbar(ent, 1); - } - -#ifdef AQTION_EXTENSION - if (desired_team == NOTEAM) - HUD_SetType(ent, 1); - else - HUD_SetType(ent, -1); -#endif - - if (level.intermission_framenum) - return; - - if (!(gameSettings & GS_ROUNDBASED) && team_round_going && ent->inuse && ent->client->resp.team) - { - PutClientInServer (ent); - AddToTransparentList (ent); - } - - //AQ2:TNG END - if (!skip_menuclose && (gameSettings & GS_WEAPONCHOOSE) && !use_randoms->value) - OpenWeaponMenu(ent); - - teams_changed = true; -} - -void LeaveTeam (edict_t * ent) -{ - char *genderstr; - - if (ent->client->resp.team == NOTEAM) - return; - - killPlayer(ent, true); - - genderstr = GENDER_STR(ent, "his", "her", "its"); - - gi.LocBroadcast_Print (PRINT_HIGH, "%s left %s team.\n", ent->client->pers.netname, genderstr); - - MM_LeftTeam( ent ); - ent->client->resp.joined_team = 0; - ent->client->resp.team = NOTEAM; - G_UpdatePlayerStatusbar(ent, 1); - -#ifdef AQTION_EXTENSION - HUD_SetType(ent, 1); -#endif - - teams_changed = true; -} - -void ReturnToMain (edict_t * ent, pmenu_t * p) -{ - PMenu_Close (ent); - OpenJoinMenu (ent); -} - -char *menu_itemnames[KIT_MAX_NUM] = { - "", - MK23_NAME, - MP5_NAME, - M4_NAME, - M3_NAME, - HC_NAME, - "SSG 3000 Sniper Rifle", - "Akimbo Pistols", - "Combat Knives", - GRENADE_NAME, - SIL_NAME, - SLIP_NAME, - BAND_NAME, - KEV_NAME, - "Laser Sight", - HELM_NAME, - "", - "", - "", - "", - "", - "", - "", - "", - "", - C_KIT_NAME_FULL, - S_KIT_NAME_FULL, - A_KIT_NAME_FULL, -}; - - -typedef struct menuentry_s -{ - int itemNum; - void (*SelectFunc) (edict_t * ent, struct pmenu_s * entry); -} menuentry_t; - -void OpenItemMenu (edict_t * ent) -{ - menuentry_t *menuEntry, menu_items[] = { - { IT_ITEM_VEST, SelectItem1 }, - { IT_ITEM_LASERSIGHT, SelectItem2 }, - { IT_ITEM_SLIPPERS, SelectItem3 }, - { IT_ITEM_SLIPPERS, SelectItem4 }, - { IT_ITEM_BANDOLIER, SelectItem5 }, - { IT_ITEM_HELM, SelectItem6 } - }; - int i, count, pos = 4; - - count = sizeof( menu_items ) / sizeof( menu_items[0] ); - - if ((int)itm_flags->value & ITF_MASK) - { - for (menuEntry = menu_items, i = 0; i < count; i++, menuEntry++) { - if (!ITF_ALLOWED(menuEntry->itemNum)) - continue; - - itemmenu[pos].text = menu_itemnames[menuEntry->itemNum]; - itemmenu[pos].SelectFunc = menuEntry->SelectFunc; - pos++; - } - - if ( pos > 4 ) - { - for (; pos < 10; pos++) - { - itemmenu[pos].text = NULL; - itemmenu[pos].SelectFunc = NULL; - } - - PMenu_Open(ent, itemmenu, 4, sizeof(itemmenu) / sizeof(pmenu_t)); - return; - } - } - - PMenu_Close(ent); -} - -void OpenItemKitMenu (edict_t * ent) -{ - menuentry_t *kitmenuEntry, kit_menu_items[] = { - { IT_ITEM_VEST, SelectItem1 }, - { C_KIT_NUM, SelectKit1 }, - { S_KIT_NUM, SelectKit2 }, - { A_KIT_NUM, SelectKit3 } - }; - int i, count, pos = 4; - - count = sizeof( kit_menu_items ) / sizeof( kit_menu_items[0] ); - - for (kitmenuEntry = kit_menu_items, i = 0; i < count; i++, kitmenuEntry++) { - itemkitmenu[pos].text = menu_itemnames[kitmenuEntry->itemNum]; - itemkitmenu[pos].SelectFunc = kitmenuEntry->SelectFunc; - pos++; - } - - if ( pos > 4 ) - { - for (; pos < 10; pos++) - { - itemkitmenu[pos].text = NULL; - itemkitmenu[pos].SelectFunc = NULL; - } - - PMenu_Open(ent, itemkitmenu, 4, sizeof(itemkitmenu) / sizeof(pmenu_t)); - return; - } - - PMenu_Close(ent); -} - -void OpenWeaponMenu (edict_t * ent) -{ - if (use_randoms->value) - { - PMenu_Open(ent, randmenu, 4, sizeof(randmenu) / sizeof(pmenu_t)); - return; - } - - menuentry_t *menuEntry, menu_items[] = { - { IT_WEAPON_MP5, SelectWeapon2 }, - { IT_WEAPON_M3, SelectWeapon3 }, - { IT_WEAPON_HANDCANNON, SelectWeapon4 }, - { IT_WEAPON_SNIPER, SelectWeapon5 }, - { IT_WEAPON_M4, SelectWeapon6 }, - { IT_WEAPON_KNIFE, SelectWeapon0 }, - { IT_WEAPON_DUALMK23, SelectWeapon9 } - }; - int i, count, pos = 4; - - count = sizeof( menu_items ) / sizeof( menu_items[0] ); - - if ((int)wp_flags->value & WPF_MASK) - { - for (menuEntry = menu_items, i = 0; i < count; i++, menuEntry++) { - // TOD: Work in weapon bans - // if (!WPF_ALLOWED(menuEntry->itemNum)) - // continue; - - weapmenu[pos].text = menu_itemnames[menuEntry->itemNum]; - weapmenu[pos].SelectFunc = menuEntry->SelectFunc; - pos++; - } - - if (pos > 4) - { - for (; pos < 11; pos++) - { - weapmenu[pos].text = NULL; - weapmenu[pos].SelectFunc = NULL; - } - - PMenu_Open(ent, weapmenu, 4, sizeof(weapmenu) / sizeof(pmenu_t)); - reurn; - } - } - - OpenItemMenu(ent); -} - -// AQ2:TNG Deathwatch - Updated this for the new menu -void UpdateJoinMenu( void ) -{ - static char levelname[28]; - static char team1players[28]; - static char team2players[28]; - static char team3players[28]; - int num1 = 0, num2 = 0, num3 = 0, i; - - if (ctf->value) - { - joinmenu[4].text = "Join Red Team"; - joinmenu[4].SelectFunc = JoinTeam1; - joinmenu[6].text = "Join Blue Team"; - joinmenu[6].SelectFunc = JoinTeam2; - joinmenu[8].text = NULL; - joinmenu[8].SelectFunc = NULL; - if (ctf_forcejoin->string && *ctf_forcejoin->string) - { - if (Q_stricmp (ctf_forcejoin->string, "red") == 0) - { - joinmenu[6].text = NULL; - joinmenu[6].SelectFunc = NULL; - } - else if (Q_stricmp (ctf_forcejoin->string, "blue") == 0) - { - joinmenu[4].text = NULL; - joinmenu[4].SelectFunc = NULL; - } - } - } - else - { - joinmenu[4].text = teams[TEAM1].name; - joinmenu[4].SelectFunc = JoinTeam1; - joinmenu[6].text = teams[TEAM2].name; - joinmenu[6].SelectFunc = JoinTeam2; - if (teamCount == 3) - { - joinmenu[8].text = teams[TEAM3].name; - joinmenu[8].SelectFunc = JoinTeam3; - } - else - { - joinmenu[8].text = NULL; - joinmenu[8].SelectFunc = NULL; - } - } - joinmenu[11].text = "Auto-join team"; - joinmenu[11].SelectFunc = JoinTeamAuto; - - levelname[0] = '*'; - if (g_edicts[0].message) - Q_strncpyz(levelname + 1, g_edicts[0].message, sizeof(levelname) - 1); - else - Q_strncpyz(levelname + 1, level.mapname, sizeof(levelname) - 1); - - for (i = 0; i < game.maxclients; i++) - { - if (!g_edicts[i + 1].inuse) - continue; - if (game.clients[i].resp.team == TEAM1) - num1++; - else if (game.clients[i].resp.team == TEAM2) - num2++; - else if (game.clients[i].resp.team == TEAM3) - num3++; - } - - sprintf (team1players, " (%d players)", num1); - sprintf (team2players, " (%d players)", num2); - sprintf (team3players, " (%d players)", num3); - - joinmenu[2].text = levelname; - if (joinmenu[4].text) - joinmenu[5].text = team1players; - else - joinmenu[5].text = NULL; - if (joinmenu[6].text) - joinmenu[7].text = team2players; - else - joinmenu[7].text = NULL; - if (joinmenu[8].text && (teamCount == 3)) - joinmenu[9].text = team3players; - else - joinmenu[9].text = NULL; -} - -// AQ2:TNG END - -void OpenJoinMenu (edict_t * ent) -{ - UpdateJoinMenu(); - - PMenu_Open (ent, joinmenu, 11 /* magic for Auto-join menu item */, sizeof (joinmenu) / sizeof (pmenu_t)); -} - -void gib_die( edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point ); // g_misc - -void CleanLevel () -{ - int i, base; - edict_t *ent; - base = 1 + game.maxclients + BODY_QUEUE_SIZE; - ent = g_edicts + base; - action_weapon_num_t weapNum; - action_item_num_t itemNum; - action_ammo_num_t ammoNum; - - for (i = base; i < globals.num_edicts; i++, ent++) - { - if (!ent->classname) - continue; - switch (weapNum) { - case MK23_NUM: - case MP5_NUM: - case M4_NUM: - case M3_NUM: - case HC_NUM: - case SNIPER_NUM: - case DUAL_NUM: - case KNIFE_NUM: - case GRENADE_NUM: - G_FreeEdict( ent ); - break; - } - switch (itemNum) { - case SIL_NUM: - case SLIP_NUM: - case BAND_NUM: - case KEV_NUM: - case LASER_NUM: - case HELM_NUM: - G_FreeEdict( ent ); - break; - } - switch (ammoNum) { - case MK23_ANUM: - case MP5_ANUM: - case M4_ANUM: - case SHELL_ANUM: - case SNIPER_ANUM: - G_FreeEdict( ent ); - break; - } - - if((ent->die == gib_die) - || (strcmp( ent->classname, "medkit" ) == 0) - || (strcmp( ent->classname, "decal" ) == 0) - || (strcmp( ent->classname, "splat" ) == 0) - || (strcmp( ent->classname, "shell" ) == 0)) - G_FreeEdict( ent ); - - } - - CleanBodies(); - // fix glass - CGF_SFX_RebuildAllBrokenGlass (); -} - -void MakeAllLivePlayersObservers(void); - -void ResetScores (bool playerScores) -{ - int i; - edict_t *ent; - - team_round_going = team_round_countdown = team_game_going = 0; - current_round_length = 0; - lights_camera_action = holding_on_tie_check = 0; - - timewarning = fragwarning = 0; - level.pauseFrames = 0; - level.matchTime = 0; - num_ghost_players = 0; - - MakeAllLivePlayersObservers(); - - for(i = TEAM1; i < TEAM_TOP; i++) - { - teams[i].score = teams[i].total = 0; - teams[i].ready = teams[i].locked = 0; - teams[i].pauses_used = teams[i].wantReset = 0; - gi.cvar_forceset(teams[i].teamscore->name, "0"); - } - - ctfgame.team1 = 0; - ctfgame.team2 = 0; - ctfgame.total1 = 0; - ctfgame.total2 = 0; - ctfgame.last_flag_capture = 0; - ctfgame.last_capture_team = 0; - ctfgame.halftime = 0; - - if(!playerScores) - return; - - for (i = 0; i < game.maxclients; i++) - { - ent = g_edicts + 1 + i; - if (!ent->inuse) - continue; - - ent->client->resp.score = 0; - ent->client->resp.kills = 0; - ent->client->resp.damage_dealt = 0; - ent->client->resp.streakHS = 0; - ent->client->resp.streakKills = 0; - ent->client->resp.ctf_caps = 0; - ent->client->resp.ctf_capstreak = 0; - ent->client->resp.deaths = 0; - ent->client->resp.team_kills = 0; - ent->client->resp.team_wounds = 0; - ent->enemy = NULL; - ResetStats(ent); - } -} - -void CenterPrintAll (const char *msg) -{ - int i; - edict_t *ent; - - gi.cprintf (NULL, PRINT_HIGH, "%s\n", msg); // so it goes to the server console... - - for (i = 0; i < game.maxclients; i++) - { - ent = &g_edicts[1 + i]; - if (ent->inuse) - gi.LocCenter_Print (ent, "%s", msg); - } -} - -int TeamHasPlayers (int team) -{ - int i, players; - edict_t *ent; - - players = 0; - - for (i = 0; i < game.maxclients; i++) - { - ent = &g_edicts[1 + i]; - if (!ent->inuse) - continue; - - if (game.clients[i].resp.team == team) - players++; - } - - return players; -} - -int _numclients( void ); // a_vote.c - -bool BothTeamsHavePlayers() -{ - int players[TEAM_TOP] = { 0 }, i, teamsWithPlayers; - edict_t *ent; - - //AQ2:TNG Slicer Matchmode - if (matchmode->value && !TeamsReady()) - return false; - //AQ2:TNG END - - if( ! _numclients() ) - return false; - - for (i = 0; i < game.maxclients; i++) - { - ent = &g_edicts[1 + i]; - if (!ent->inuse || game.clients[i].resp.team == NOTEAM) - continue; - if (!game.clients[i].resp.subteam) - players[game.clients[i].resp.team]++; - } - - teamsWithPlayers = 0; - for (i = TEAM1; i <= teamCount; i++) - { - if (players[i]) { - teamsWithPlayers++; - } - } - - return (teamsWithPlayers >= 2); -} - -// CheckForWinner: Checks for a winner (or not). -int CheckForWinner() -{ - int players[TEAM_TOP] = { 0 }, i = 0, teamNum = 0, teamsWithPlayers = 0; - edict_t *ent; - - if (!(gameSettings & GS_ROUNDBASED)) { - return WINNER_NONE; - } else { - for (i = 0; i < game.maxclients; i++){ - ent = &g_edicts[1 + i]; - if (!ent->inuse || ent->solid == SOLID_NOT) - continue; - - teamNum = game.clients[i].resp.team; - if (teamNum == NOTEAM) - continue; - - players[teamNum]++; - } - teamsWithPlayers = 0; - for (i = TEAM1; i <= teamCount; i++){ - if (players[i]) { - teamsWithPlayers++; - teamNum = i; - } - } - if (teamsWithPlayers) - return (teamsWithPlayers > 1) ? WINNER_NONE : teamNum; - - return WINNER_TIE; - } - return WINNER_NONE; -} - -// CheckForForcedWinner: A winner is being forced, find who it is. -int CheckForForcedWinner() -{ - int players[TEAM_TOP] = { 0 }; - int health[TEAM_TOP] = { 0 }; - int i, teamNum, bestTeam, secondBest; - edict_t *ent; - - for (i = 0; i < game.maxclients; i++) - { - ent = &g_edicts[1 + i]; - if (!ent->inuse || ent->solid == SOLID_NOT) - continue; - teamNum = game.clients[i].resp.team; - if (teamNum == NOTEAM) - continue; - - players[teamNum]++; - health[teamNum] += ent->health; - } - - bestTeam = secondBest = NOTEAM; - for (i = TEAM1; i <= teamCount; i++) - { - if (players[i] < players[bestTeam]) { - continue; - } - if (players[i] > players[bestTeam]) { - bestTeam = i; - secondBest = NOTEAM; - continue; - } - //Same amound of players, check health - if (health[i] < health[bestTeam]) { - continue; - } - if (health[i] > health[bestTeam]) { - bestTeam = i; - secondBest = NOTEAM; - continue; - } - //Same as bestTeam - secondBest = i; - } - - if (bestTeam == NOTEAM || secondBest != NOTEAM) - return WINNER_TIE; - - return bestTeam; -} - -static void SpawnPlayers(void) -{ - int i; - edict_t *ent; - - if (gameSettings & GS_ROUNDBASED) { - NS_SetupTeamSpawnPoints (); - } - - InitTransparentList(); - for (i = 0, ent = &g_edicts[1]; i < game.maxclients; i++, ent++) - { - if (!ent->inuse) - continue; - - if (!ent->client->resp.team || ent->client->resp.subteam) - continue; - - // make sure teamplay spawners always have some weapon, warmup starts only after weapon selected - if (!ent->client->pers.chosenWeapon) { - // TODO: Work in weapon bans - // if (WPF_ALLOWED(IT_WEAPON_MP5)) { - // ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_MP5); - // } else if (WPF_ALLOWED(IT_WEAPON_MK23)) { - // ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_MK23); - // } else if (WPF_ALLOWED(IT_WEAPON_KNIFE)) { - // ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_KNIFE); - // } else { - ent->client->pers.chosenWeapon = GetItemByIndex(IT_WEAPON_MK23); - } - - if (!ent->client->pers.chosenItem) { - ent->client->pers.chosenItem = GetItemByIndex(IT_ITEM_VEST); - } - - PutClientInServer(ent); - AddToTransparentList(ent); - } - - if(matchmode->value && limchasecam->value) - { - for (i = 0, ent = &g_edicts[1]; i < game.maxclients; i++, ent++) - { - if (!ent->inuse) - continue; - - if (!ent->client->resp.team || !ent->client->resp.subteam) - continue; - - ent->client->chase_mode = 0; - NextChaseMode( ent ); - } - } -} - -void RunWarmup () -{ - int i, dead; - edict_t *ent; - - if (!warmup->value || (matchmode->value && level.matchTime > 0) || team_round_going || lights_camera_action || (team_round_countdown > 0 && team_round_countdown <= 101)) - return; - - if (!in_warmup) - { - in_warmup = 1; - InitTransparentList(); - } - - for (i = 0, ent = &g_edicts[1]; i < game.maxclients; i++, ent++) - { - if (!ent->inuse) - continue; - - if(!ent->client->resp.team || ent->client->resp.subteam) - continue; - - if (!ent->client->pers.chosenWeapon || !ent->client->pers.chosenItem) - continue; - - if ((!IS_ALIVE(ent) && ent->movetype == MOVETYPE_NOCLIP) && ent->client->latched_buttons & BUTTON_ATTACK) - { - ent->client->latched_buttons = BUTTON_NONE; - PutClientInServer(ent); - AddToTransparentList(ent); - gi.LocCenter_Print(ent, "WARMUP"); - } - } -} - -void StartRound () -{ - team_round_going = 1; - current_round_length = 0; -} - -static void StartLCA(void) -{ - if ((gameSettings & (GS_WEAPONCHOOSE|GS_ROUNDBASED))) - CleanLevel(); - - - CenterPrintAll ("LIGHTS..."); - gi.sound(&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, snd_lights, 1.0, ATTN_NONE, 0.0); - lights_camera_action = 43; // TempFile changed from 41 - - SpawnPlayers(); -} - -// FindOverlap: Find the first (or next) overlapping player for ent. -edict_t *FindOverlap (edict_t * ent, edict_t * last_overlap) -{ - int i; - edict_t *other; - vec3_t diff; - - for (i = last_overlap ? last_overlap - g_edicts : 0; i < game.maxclients; i++) - { - other = &g_edicts[i + 1]; - - if (!other->inuse || other->client->resp.team == NOTEAM - || other == ent || !IS_ALIVE(other)) - continue; - - VectorSubtract(ent->s.origin, other->s.origin, diff); - - if (diff[0] >= -33 && diff[0] <= 33 && - diff[1] >= -33 && diff[1] <= 33 && diff[2] >= -65 && diff[2] <= 65) - return other; - } - - return NULL; -} - -void ContinueLCA () -{ - if (lights_camera_action == 23) - { - CenterPrintAll("CAMERA..."); - gi.sound(&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, level.snd_camera , 1.0, ATTN_NONE, 0.0); - } - else if (lights_camera_action == 3) - { - CenterPrintAll("ACTION!"); - gi.sound(&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, level.snd_action, 1.0, ATTN_NONE, 0.0); - } - else if (lights_camera_action == 1) - { - StartRound(); - } - lights_camera_action--; -} - -void MakeAllLivePlayersObservers (void) -{ - edict_t *ent; - int saveteam, i; - - /* if someone is carrying a flag it will disappear */ - if(ctf->value) - CTFResetFlags(); - - for (i = 0; i < game.maxclients; i++) - { - ent = &g_edicts[1 + i]; - if (!ent->inuse) - continue; - if(ent->solid == SOLID_NOT && !ent->deadflag) - continue; - - saveteam = ent->client->resp.team; - ent->client->resp.team = NOTEAM; - PutClientInServer(ent); - ent->client->resp.team = saveteam; - } -} - -// PrintScores: Prints the current score on the console -void PrintScores (void) -{ - if (teamCount == 3) { - gi.LocBroadcast_Print (PRINT_HIGH, "Current score is %s: %d to %s: %d to %s: %d\n", TeamName (TEAM1), teams[TEAM1].score, TeamName (TEAM2), teams[TEAM2].score, TeamName (TEAM3), teams[TEAM3].score); - } else { - gi.LocBroadcast_Print (PRINT_HIGH, "Current score is %s: %d to %s: %d\n", TeamName (TEAM1), teams[TEAM1].score, TeamName (TEAM2), teams[TEAM2].score); - } -} - -bool CheckTimelimit( void ) -{ - if (timelimit->value > 0) - { - if (level.matchTime >= timelimit->value * 60) - { - int i; - - for (i = TEAM1; i < TEAM_TOP; i++) { - teams[i].ready = 0; - } - - timewarning = fragwarning = 0; - - if (matchmode->value) { - SendScores(); - team_round_going = team_round_countdown = team_game_going = 0; - MakeAllLivePlayersObservers(); - ctfgame.halftime = 0; - } else { - gi.LocBroadcast_Print( PRINT_HIGH, "Timelimit hit.\n" ); - if (!(gameSettings & GS_ROUNDBASED)) - ResetPlayers(); - EndDMLevel(); - } - - team_round_going = team_round_countdown = team_game_going = 0; - level.matchTime = 0; - - return true; - } - - // CTF with use_warnings should have the same warnings when the map is ending as it does for halftime (see CTFCheckRules). - // Otherwise, use_warnings should warn about 3 minutes and 1 minute left, but only if there aren't round ending warnings. - if( use_warnings->value && (ctf->value || ! roundtimelimit->value) ) - { - if( timewarning < 3 && ctf->value && level.matchTime >= timelimit->value * 60 - 10 ) - { - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex("world/10_0.wav"), 1.0, ATTN_NONE, 0.0 ); - timewarning = 3; - } - else if( timewarning < 2 && level.matchTime >= (timelimit->value - 1) * 60 ) - { - CenterPrintAll( "1 MINUTE LEFT..." ); - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex("tng/1_minute.wav"), 1.0, ATTN_NONE, 0.0 ); - timewarning = 2; - } - else if( timewarning < 1 && (! ctf->value) && timelimit->value > 3 && level.matchTime >= (timelimit->value - 3) * 60 ) - { - CenterPrintAll( "3 MINUTES LEFT..." ); - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex("tng/3_minutes.wav"), 1.0, ATTN_NONE, 0.0 ); - timewarning = 1; - } - } - } - - return false; -} - -int WonGame(int winner); - -static bool CheckRoundTimeLimit( void ) -{ - if (roundtimelimit->value > 0) - { - int roundLimitFrames = (int)(roundtimelimit->value * 600); - - if (current_round_length >= roundLimitFrames) - { - int winTeam = NOTEAM; - - gi.LocBroadcast_Print( PRINT_HIGH, "Round timelimit hit.\n" ); - - winTeam = CheckForForcedWinner(); - if (WonGame( winTeam )) - return true; - - team_round_going = 0; - timewarning = fragwarning = 0; - lights_camera_action = 0; - holding_on_tie_check = 0; - team_round_countdown = 71; - - return true; - } - - if (use_warnings->value && timewarning < 2) - { - roundLimitFrames -= current_round_length; - - if (roundLimitFrames <= 600) - { - CenterPrintAll( "1 MINUTE LEFT..." ); - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex( "tng/1_minute.wav" ), 1.0, ATTN_NONE, 0.0 ); - timewarning = 2; - } - else if (roundLimitFrames <= 1800 && timewarning < 1 && roundtimelimit->value > 3) - { - CenterPrintAll( "3 MINUTES LEFT..." ); - gi.sound( &g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, gi.soundindex( "tng/3_minutes.wav" ), 1.0, ATTN_NONE, 0.0 ); - timewarning = 1; - } - } - } - return false; -} - -static bool CheckRoundLimit( void ) -{ - if (roundlimit->value > 0) - { - int i, winTeam = NOTEAM; - - for (i = TEAM1; i <= teamCount; i++) { - if (teams[i].score >= (int)roundlimit->value) { - winTeam = i; - break; - } - } - - if (winTeam != NOTEAM) - { - for (i = TEAM1; i < TEAM_TOP; i++) { - teams[i].ready = 0; - } - - timewarning = fragwarning = 0; - if (matchmode->value) { - SendScores(); - team_round_going = team_round_countdown = team_game_going = 0; - MakeAllLivePlayersObservers(); - } else { - gi.LocBroadcast_Print( PRINT_HIGH, "Roundlimit hit.\n" ); - EndDMLevel(); - } - team_round_going = team_round_countdown = team_game_going = 0; - level.matchTime = 0; - return true; - } - } - return false; -} - -// WonGame: returns true if we're exiting the level. -int WonGame (int winner) -{ - edict_t *player, *cl_ent; // was: edict_t *player; - int i; - char arg[64]; - - gi.LocBroadcast_Print (PRINT_HIGH, "The round is over:\n"); - if (winner == WINNER_TIE) - { - gi.LocBroadcast_Print (PRINT_HIGH, "It was a tie, no points awarded!\n"); - - if(use_warnings->value) - gi.sound(&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, level.snd_teamwins[0], 1.0, ATTN_NONE, 0.0); - PrintScores (); - } - else - { - gi.LocBroadcast_Print (PRINT_HIGH, "%s won!\n", TeamName(winner)); - // AQ:TNG Igor[Rock] changing sound dir - if(use_warnings->value) - gi.sound(&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, level.snd_teamwins[winner], 1.0, ATTN_NONE, 0.0); - // end of changing sound dir - teams[winner].score++; - - gi.cvar_forceset(teams[winner].teamscore->name, va("%i", teams[winner].score)); - - PrintScores (); - - } - - if (CheckTimelimit()) - return 1; - - if (CheckRoundLimit()) - return 1; - - if (vCheckVote()) { - EndDMLevel (); - team_round_going = team_round_countdown = team_game_going = 0; - return 1; - } - vNewRound (); - - if (teamplay->value && (!timelimit->value || level.matchTime <= ((timelimit->value * 60) - 5))) - { - arg[0] = '\0'; - for (i = 0; i < game.maxclients; i++) - { - cl_ent = &g_edicts[1 + i]; - - if (cl_ent->inuse && cl_ent->client->resp.stat_mode == 2) - Cmd_Stats_f(cl_ent, arg); - } - } - // Increment roundNum for tracking - game.roundNum++; - - // Reset kill streaks in team modes - if (use_killcounts->value){ - for (i = 0; i < game.maxclients; i++) { - cl_ent = g_edicts + 1 + i; - cl_ent->client->resp.streakKills = 0; - } - } - - return 0; -} - - -int CheckTeamRules (void) -{ - int winner = WINNER_NONE, i; - int checked_tie = 0; - char buf[1024]; - struct tm *now = NULL; - time_t tnow = 0; - char ltm[64] = ""; - char mvdstring[512] = ""; - - if (lights_camera_action) - { - ContinueLCA (); - return 0; - } - - if (team_round_going) - current_round_length++; - - if (holding_on_tie_check) - { - holding_on_tie_check--; - if (holding_on_tie_check > 0) - return 0; - holding_on_tie_check = 0; - checked_tie = 1; - } - - if (team_round_countdown) - { - team_round_countdown--; - if(!team_round_countdown) - { - if (BothTeamsHavePlayers ()) - { - in_warmup = 0; - team_game_going = 1; - StartLCA(); - } - else - { - if (!matchmode->value || TeamsReady()) - CenterPrintAll ("Not enough players to play!"); - else - CenterPrintAll ("Both Teams Must Be Ready!"); - - team_round_going = team_round_countdown = team_game_going = 0; - MakeAllLivePlayersObservers (); - } - } - else - { - if (team_round_countdown == 101) - { - gi.sound (&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, - gi.soundindex ("world/10_0.wav"), 1.0, ATTN_NONE, 0.0); - if (printrules->value) { - PrintMatchRules(); - } - } - } - if(team_round_countdown == 41 && !matchmode->value) - { - while(CheckForUnevenTeams(NULL)); - } - } - - // check these rules every 1.5 seconds... - if (++rulecheckfrequency % 15 && !checked_tie) - return 0; - - if (matchmode->value) - { - if (mm_allowlock->value) - { - for (i = TEAM1; i <= teamCount; i++) - { - if (teams[i].locked && !TeamHasPlayers( i )) - { - teams[i].locked = 0; - sprintf( buf, "%s unlocked (no players)", TeamName( i ) ); - CenterPrintAll( buf ); - } - } - } - } - - if (!team_round_going) - { - RunWarmup(); - if (CheckTimelimit()) - return 1; - - if (vCheckVote()) { - EndDMLevel (); - team_round_going = team_round_countdown = team_game_going = 0; - return 1; - } - - if (!team_round_countdown) - { - if (BothTeamsHavePlayers()) - { - int warmup_length = max( warmup->value, round_begin->value ); - char buf[64] = ""; - sprintf( buf, "The round will begin in %d seconds!", warmup_length ); - CenterPrintAll( buf ); - team_round_countdown = warmup_length * 10 + 2; - - // JBravo: Autostart q2pro MVD2 recording on the server - if( use_mvd2->value ) - { - tnow = time(NULL); - now = localtime(&tnow); - strftime( ltm, 64, "%Y%m%d-%H%M%S", now ); - snprintf( mvdstring, sizeof(mvdstring), "mvdrecord %s-%s\n", ltm, level.mapname ); - gi.AddCommandString( mvdstring ); - gi.LocBroadcast_Print( PRINT_HIGH, "Starting MVD recording to file %s-%s.mvd2\n", ltm, level.mapname ); - } - // JBravo: End MVD2 - } - } - } - else - /* team_round_going */ - { - if (!(gameSettings & GS_ROUNDBASED)) - { - if (CheckTimelimit()) - return 1; - - if (ctf->value && CTFCheckRules()) - { - ResetPlayers(); - EndDMLevel(); - team_round_going = team_round_countdown = team_game_going = 0; - return 1; - } - - if (dom->value && DomCheckRules()) - { - EndDMLevel(); - team_round_going = team_round_countdown = team_game_going = 0; - return 1; - } - - if (vCheckVote()) { - EndDMLevel (); - team_round_going = team_round_countdown = team_game_going = 0; - return 1; - } - - if (!BothTeamsHavePlayers()) - { - if (!matchmode->value || TeamsReady()) - CenterPrintAll( "Not enough players to play!" ); - else - CenterPrintAll( "Both Teams Must Be Ready!" ); - - team_round_going = team_round_countdown = team_game_going = 0; - MakeAllLivePlayersObservers(); - - /* try to restart the game */ - while (CheckForUnevenTeams( NULL )); - } - return 0; //CTF and teamDM dont need to check winner, its not round based - } - - winner = CheckForWinner(); - if (winner != WINNER_NONE) - { - if (!checked_tie) - { - holding_on_tie_check = 50; - return 0; - } - if (WonGame(winner)) - return 1; - - team_round_going = 0; - lights_camera_action = 0; - holding_on_tie_check = 0; - timewarning = fragwarning = 0; - team_round_countdown = 71; - - return 0; - } - - if (CheckRoundTimeLimit()) - return 1; - } - return 0; -} - - -void A_Scoreboard (edict_t * ent) -{ - int wteam = 0; - - if (ent->client->layout == LAYOUT_SCORES) - { - // blink header of the winning team during intermission - if (level.intermission_framenum && ((level.realFramenum / FRAMEDIV) & 8)) - { // blink 1/8th second - if (teams[TEAM1].score > teams[TEAM2].score) - wteam = TEAM1; - else if (teams[TEAM2].score > teams[TEAM1].score) - wteam = TEAM2; - else if (teams[TEAM1].total > teams[TEAM2].total) // frag tie breaker - wteam = TEAM1; - else if (teams[TEAM2].total > teams[TEAM1].total) - wteam = TEAM2; - - if(teamCount == 3) - { - if(wteam) { - if (teams[TEAM3].score > teams[wteam].score) - wteam = TEAM3; - else if (teams[TEAM3].score == teams[wteam].score) { - if(teams[TEAM3].total > teams[wteam].total) - wteam = TEAM3; - else if (teams[TEAM3].total == teams[wteam].total) - wteam = 0; - } - } else { - if(teams[TEAM3].score > teams[TEAM1].score) - wteam = TEAM3; - else if (teams[TEAM3].total > teams[TEAM1].total) - wteam = TEAM3; - } - } - - if (wteam == 1) - ent->client->ps.stats[STAT_TEAM1_PIC] = 0; - else if (wteam == 2) - ent->client->ps.stats[STAT_TEAM2_PIC] = 0; - else if (wteam == 3 && (teamCount == 3)) - ent->client->ps.stats[STAT_TEAM3_PIC] = 0; - else // tie game! - { - ent->client->ps.stats[STAT_TEAM1_PIC] = 0; - ent->client->ps.stats[STAT_TEAM2_PIC] = 0; - if(teamCount == 3) - ent->client->ps.stats[STAT_TEAM3_PIC] = 0; - } - } - else - { - ent->client->ps.stats[STAT_TEAM1_PIC] = level.pic_teamskin[TEAM1]; - ent->client->ps.stats[STAT_TEAM2_PIC] = level.pic_teamskin[TEAM2]; - if (teamCount == 3) - ent->client->ps.stats[STAT_TEAM3_PIC] = level.pic_teamskin[TEAM3]; - } - - ent->client->ps.stats[STAT_TEAM1_SCORE] = teams[TEAM1].score; - ent->client->ps.stats[STAT_TEAM2_SCORE] = teams[TEAM2].score; - if (teamCount == 3) - ent->client->ps.stats[STAT_TEAM3_SCORE] = teams[TEAM3].score; - } -} - - -static int G_PlayerCmp( const void *p1, const void *p2 ) -{ - gclient_t *a = *(gclient_t * const *)p1; - gclient_t *b = *(gclient_t * const *)p2; - - if (a->resp.score != b->resp.score) - return b->resp.score - a->resp.score; - - if (a->resp.deaths < b->resp.deaths) - return -1; - if (a->resp.deaths > b->resp.deaths) - return 1; - - if (a->resp.damage_dealt > b->resp.damage_dealt) - return -1; - if (a->resp.damage_dealt < b->resp.damage_dealt) - return 1; - - return 0; -} - -int G_SortedClients( gclient_t **sortedList ) -{ - int i, total = 0; - gclient_t *client; - - for (i = 0, client = game.clients; i < game.maxclients; i++, client++) { - if (!client->pers.connected) - continue; - - sortedList[total++] = client; - } - - qsort( sortedList, total, sizeof( gclient_t * ), G_PlayerCmp ); - - return total; -} - -int G_NotSortedClients( gclient_t **sortedList ) -{ - int i, total = 0; - gclient_t *client; - - for (i = 0, client = game.clients; i < game.maxclients; i++, client++) { - if (!client->pers.connected) - continue; - - sortedList[total++] = client; - } - - return total; -} - -#define MAX_SCOREBOARD_SIZE 1024 -#define TEAM_HEADER_WIDTH 160 //skin icon and team tag -#define TEAM_ROW_CHARS 32 //"yv 42 string2 \"name\" " -#define TEAM_ROW_WIDTH 160 //20 chars, name and possible captain tag -#define TEAM_ROW_CHARS2 44 //yv %d string%c \"%-15s %3d %3d %3d\" " -#define TEAM_ROW_WIDTH2 216 //27 chars, name Frg Tim Png -#define TEAM_ROW_GAP 30 - -// Maximum number of lines of scores to put under each team's header. -#define MAX_SCORES_PER_TEAM 9 - -#define MAX_PLAYERS_PER_TEAM 8 - -void A_NewScoreboardMessage(edict_t * ent) -{ - char buf[1024]; - char string[1024] = { '\0' }; - gclient_t *sortedClients[MAX_CLIENTS]; - int total[TEAM_TOP] = { 0, 0, 0, 0 }; - int i, j, line = 0, lineh = 8; - int dead, alive, totalClients, maxPlayers, printCount; - gclient_t *cl; - edict_t *cl_ent; - - // show alive players when dead - dead = (!IS_ALIVE(ent) || !team_round_going); - if (limchasecam->value != 0) - dead = 0; - - totalClients = G_SortedClients(sortedClients); - - for(i = 0; i < totalClients; i++) { - total[sortedClients[i]->resp.team]++; - } - - // print teams - for (i = TEAM1; i <= teamCount; i++) - { - snprintf( buf, sizeof( buf ), "xv 44 yv %d string2 \"%3d %-11.11s Frg Tim Png\"", line++ * lineh, teams[i].score, teams[i].name ); - Q_strncatz( string, buf, sizeof( string ) ); - - snprintf( buf, sizeof( buf ), "xv 44 yv %d string2 \"%s\" ", - line++ * lineh, - "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F \x9D\x9E\x9F \x9D\x9E\x9F \x9D\x9E\x9F" - ); - Q_strncatz( string, buf, sizeof( string ) ); - - if (!total[i]) - continue; - - printCount = 0; - if (total[i] > MAX_PLAYERS_PER_TEAM) - maxPlayers = MAX_PLAYERS_PER_TEAM - 1; - else - maxPlayers = total[i]; - - for (j = 0; j < totalClients; j++) - { - cl = sortedClients[j]; - if (cl->resp.team != i) - continue; - - cl_ent = g_edicts + 1 + (cl - game.clients); - alive = IS_ALIVE(cl_ent); - - snprintf( buf, sizeof( buf ), "xv 44 yv %d string%c \"%-15s %3d %3d %3d\"", - line++ * lineh, - (alive && dead ? '2' : ' '), - cl->pers.netname, - cl->resp.score, - (level.framenum - cl->resp.enterframe) / 600 / FRAMEDIV, - min(cl->ping, 999) ); - Q_strncatz( string, buf, sizeof( string ) ); - printCount++; - if (printCount >= maxPlayers) - break; - } - - // show the amount of excess players - if (total[i] > MAX_PLAYERS_PER_TEAM) { - snprintf( buf, sizeof( buf ), "xv 44 yv %d string \" ..and %d more\"", line++ * lineh, total[i] - MAX_PLAYERS_PER_TEAM + 1 ); - Q_strncatz( string, buf, sizeof( string ) ); - } - - line++; - } - - string[sizeof( string ) - 1] = '\0'; - if (strlen( string ) > MAX_SCOREBOARD_SIZE - 1) { - string[MAX_SCOREBOARD_SIZE - 1] = '\0'; - } - - gi.WriteByte( svc_layout ); - gi.WriteString( string ); -} - -//AQ2:TNG - Slicer Modified Scores for Match Mode -void A_ScoreboardMessage (edict_t * ent, edict_t * killer) -{ - char string[2048]; - gclient_t *sortedClients[MAX_CLIENTS], *cl; - edict_t *cl_ent; - int totalClients; - int maxsize = 1000, i, j, line_x, line_y; - - string[0] = 0; - - if (ent->client->layout == LAYOUT_SCORES) - { - char footer[256], playername[16]; - int team, len, footerLen = 0, remaining, deadview; - int total[TEAM_TOP] = {0,0,0,0}; - int totalsubs[TEAM_TOP] = {0,0,0,0}; - int totalscore[TEAM_TOP] = {0,0,0,0}; - int totalalive[TEAM_TOP] = {0,0,0,0}; - int totalaliveprinted; - int name_pos, flagindex = 0; - int tpic[TEAM_TOP][2] = {{0,0},{24,26},{25,27},{30,31}}; - char temp[16]; - int maxPlayersPerTeam, scoreWidth = 3, rowWidth, rowChars, rowGap, headerOffset = 0; - int maxPlayers, printCount, base_x, showExtra = 0, subLines = 0; - - // new scoreboard for regular teamplay up to 16 players - if (use_newscore->value == 1 && teamplay->value && !matchmode->value && !ctf->value) { - A_NewScoreboardMessage(ent); - return; - } - - if (use_newscore->value > 1 && teamCount < 3) { - showExtra = 1; - rowWidth = max(TEAM_HEADER_WIDTH, TEAM_ROW_WIDTH2); - rowChars = TEAM_ROW_CHARS2; - rowGap = TEAM_ROW_GAP; - } else { - rowWidth = max(TEAM_HEADER_WIDTH, TEAM_ROW_WIDTH); - rowChars = TEAM_ROW_CHARS; - rowGap = 0; - } - - base_x = 160 - ((rowWidth + rowGap) * teamCount) / 2 + rowGap / 2; - - if(ctf->value) - { - base_x += 8; - tpic[TEAM1][0] = 30; - tpic[TEAM2][0] = 31; - if(teamCount == 3) - tpic[TEAM3][0] = 32; - } - else if(teamdm->value) - { - scoreWidth = 3; - } - - deadview = (!IS_ALIVE(ent) || !team_round_going); - // AQ:TNG - Hack to keep scoreboard from revealing whos alive during matches - JBravo - if (limchasecam->value != 0) - deadview = 0; - - if (noscore->value) - totalClients = G_NotSortedClients(sortedClients); - else - totalClients = G_SortedClients(sortedClients); - - ent->client->ps.stats[STAT_TEAM_HEADER] = level.pic_teamtag; - - for (i = 0; i < totalClients; i++) { - cl = sortedClients[i]; - team = cl->resp.team; - - if (cl->resp.subteam) { - totalsubs[team]++; - continue; - } - - cl_ent = g_edicts + 1 + (cl - game.clients); - if (IS_ALIVE(cl_ent)) - totalalive[team]++; - - totalscore[team] += cl->resp.score; - total[team]++; - } - - len = 0; - //Build team headers - if (use_newscore->value > 2 && rowWidth > TEAM_HEADER_WIDTH) - headerOffset = (rowWidth - TEAM_HEADER_WIDTH) / 2; - - rowWidth += rowGap; - - sprintf(string + len, "yv 8 "); - len = strlen(string); - //Add skin img - for (i = TEAM1, line_x = base_x + headerOffset; i <= teamCount; i++, line_x += rowWidth) - { - sprintf(string + len, - "if %i xv %i pic %i endif ", - tpic[i][0], line_x, tpic[i][0]); - len = strlen(string); - } - - //Add team tag img - if (!ctf->value) { - Q_strlcat(string, "if 22 ", sizeof(string)); - len = strlen(string); - for (i = TEAM1, line_x = base_x + headerOffset; i <= teamCount; i++, line_x += rowWidth) - { - sprintf(string + len, "xv %i pic 22 ", line_x + 32); - len = strlen(string); - } - Q_strlcat(string, "endif ", sizeof(string)); - len = strlen(string); - } - - //Add player info - sprintf( string + len, "yv 28 " ); - len = strlen( string ); - for (i = TEAM1, line_x = base_x + headerOffset; i <= teamCount; i++, line_x += rowWidth) - { - if (matchmode->value) - snprintf(temp, sizeof(temp), "%4i/%2i/%-2d", totalscore[i], total[i], totalsubs[i]); - else - snprintf(temp, sizeof(temp), "%4i/%2i", totalscore[i], total[i]); - - sprintf( string + len, - "xv %i string \"%s\" ", - line_x + 32, temp ); - len = strlen( string ); - } - - //Add score - sprintf( string + len, "yv 12 " ); - len = strlen( string ); - for (i = TEAM1, line_x = base_x + headerOffset; i <= teamCount; i++, line_x += rowWidth) - { - sprintf( string + len, - "xv %i num %i %i ", - line_x + (ctf->value ? 90 : 96), scoreWidth, tpic[i][1] ); - len = strlen( string ); - } - - //Add team name - sprintf( string + len, "yv 0 " ); - len = strlen( string ); - for (i = TEAM1, line_x = base_x + headerOffset; i <= teamCount; i++, line_x += rowWidth) - { - name_pos = ((20 - strlen( teams[i].name )) / 2) * 8; - if (name_pos < 0) - name_pos = 0; - - sprintf( string + len, - "xv %d string \"%s\" ", - line_x + name_pos, teams[i].name ); - len = strlen( string ); - } - - //Build footer - footer[0] = 0; - if (matchmode->value) - { - int secs, mins; - - i = level.matchTime; - mins = i / 60; - secs = i % 60; - - sprintf( footer, "yv 128 " ); - footerLen = strlen( footer ); - for (i = TEAM1, line_x = base_x + 39; i <= teamCount; i++, line_x += rowWidth) - { - sprintf( footer + footerLen, "xv %i string2 \"%s\" ", - line_x, teams[i].ready ? "Ready" : "Not Ready" ); - footerLen = strlen( footer ); - } - - sprintf( footer + footerLen, "xv 112 yv 144 string \"Time: %d:%02d\" ", mins, secs ); - footerLen = strlen( footer ); - } - - remaining = MAX_SCOREBOARD_SIZE - 1 - len - footerLen; - - maxPlayersPerTeam = MAX_SCORES_PER_TEAM; - if (maxPlayersPerTeam > (remaining / rowChars) / teamCount) - maxPlayersPerTeam = (remaining / rowChars) / teamCount; - - for (i = TEAM1, line_x = base_x; i <= teamCount; i++, line_x += rowWidth) - { - line_y = 42; - sprintf( string + len, "xv %i ", line_x ); - len = strlen(string); - - if (showExtra) { - sprintf( string + len, "yv %d string2 \"Name Frg Tim Png\" ", line_y ); - len = strlen( string ); - line_y += 8; - } - - if (ctf->value) - flagindex = (i == TEAM1) ? items[FLAG_T1_NUM].index : items[FLAG_T2_NUM].index; - - printCount = 0; - totalaliveprinted = 0; - - maxPlayers = maxPlayersPerTeam; - - if (matchmode->value) { - subLines = 1 + min(totalsubs[i], 2); //for subs - if (maxPlayers - subLines < 4) - subLines = 1; - - maxPlayers -= subLines; - } - - if (total[i] > maxPlayers) - maxPlayers = maxPlayers - 1; - else - maxPlayers = total[i]; - - if (maxPlayers) - { - for (j = 0; j < totalClients; j++) - { - cl = sortedClients[j]; - - if (cl->resp.team != i) - continue; - if (cl->resp.subteam) - continue; - - cl_ent = g_edicts + 1 + (cl - game.clients); - if (IS_ALIVE(cl_ent)) - totalaliveprinted++; - - playername[0] = 0; - if (IS_CAPTAIN(cl_ent)) { - playername[0] = '@'; - playername[1] = 0; - } - Q_strlcat(playername, cl->pers.netname, sizeof(playername)); - if (showExtra) { - sprintf( string + len, - "yv %d string%s \"%-15s %3d %3d %3d\" ", - line_y, - (deadview && cl_ent->solid != SOLID_NOT) ? "2" : "", - playername, - cl->resp.score, - (level.framenum - cl->resp.enterframe) / (60 * HZ), - min(cl->ping, 999) ); - } else { - sprintf( string + len, - "yv %i string%s \"%s\" ", - line_y, - (deadview && cl_ent->solid != SOLID_NOT) ? "2" : "", - playername ); - } - - len = strlen( string ); - if (ctf->value && cl->inventory[flagindex]){ - sprintf( string + len, "xv %i picn sbfctf%s xv %i ", line_x - 8, i == TEAM1 ? "2" : "1", line_x ); - len = strlen( string ); - } - - line_y += 8; - printCount++; - if (printCount >= maxPlayers) - break; - } - - // Print remaining players if we ran out of room... - if (printCount < total[i]) - { - if (!deadview) // live player viewing scoreboard... - { - sprintf( string + len, - "yv %i string \"..and %i more\" ", - line_y, total[i] - printCount ); - len = strlen( string ); - } - else // dead player viewing scoreboard... - { - sprintf( string + len, - "yv %i string%s \"..and %i/%i more\" ", - line_y, - (totalalive[i] - totalaliveprinted) ? "2" : "", - totalalive[i] - totalaliveprinted, - total[i] - printCount ); - len = strlen( string ); - } - line_y += 8; - } - } - - if (subLines == 1 && totalsubs[i]) //Subs - { - line_y = 96; - sprintf( string + len, "yv %i string2 \"%d Subs\" ", line_y, totalsubs[i] ); - len = strlen( string ); - line_y += 8; - - } - else if (subLines > 0) - { - line_y = 96; - sprintf( string + len, "yv %i string2 \"Subs\" ", line_y ); - len = strlen( string ); - - line_y += 8; - printCount = 0; - - if (totalsubs[i] > subLines - 1) - maxPlayers = subLines - 2; - else - maxPlayers = totalsubs[i]; - - if (maxPlayers) - { - for (j = 0; j < totalClients; j++) - { - cl = sortedClients[j]; - - if (cl->resp.team != i) - continue; - if (!cl->resp.subteam) - continue; - - cl_ent = g_edicts + 1 + (cl - game.clients); - sprintf( string + len, - "yv %d string \"%s%s\" ", - line_y, IS_CAPTAIN(cl_ent) ? "@" : "", cl->pers.netname ); - len = strlen( string ); - - line_y += 8; - printCount++; - if (printCount >= maxPlayers) - break; - } - - // Print remaining players if we ran out of room... - if (printCount < totalsubs[i]) - { - sprintf( string + len, - "yv %i string \" + %i more\" ", - line_y, totalsubs[i] - printCount ); - len = strlen( string ); - - line_y += 8; - } - } - } - } - - if (footerLen) { - string[MAX_SCOREBOARD_SIZE - 1 - footerLen] = 0; - Q_strncatz(string, footer, sizeof(string)); - } - } - else if (ent->client->layout == LAYOUT_SCORES2) - { - const char *sb = scoreboard->string; - int sb_len = 0; - int chars = 0; - - if( ! sb[0] ) - { - if( noscore->value ) - sb = "NMP"; - else if( ctf->value ) - sb = "SNMPCT"; - else if( teamdm->value ) - sb = "FNMPDT"; - else - sb = "FNMPIT"; - } - - sb_len = strlen(sb); - - for( i = 0; i < sb_len; i ++ ) - { - char field = toupper( sb[ i ] ); - if( i ) - chars ++; - if( field == 'F' ) chars += 5; - else if( field == 'T' ) chars += 4; - else if( field == 'N' ) chars += 15; - else if( field == 'M' ) chars += 4; - else if( field == 'P' ) chars += 4; - else if( field == 'C' ) chars += 4; - else if( field == 'S' ) chars += 5; - else if( field == 'K' ) chars += 5; - else if( field == 'D' ) chars += 6; - else if( field == 'I' ) chars += 6; - else if( field == 'A' ) chars += 3; - else chars ++; - } - - if (noscore->value) - totalClients = G_NotSortedClients(sortedClients); - else - totalClients = G_SortedClients(sortedClients); - - line_x = 160 - (chars * 4); - sprintf( string, "xv %i yv 32 string2 \"", line_x ); - - for( i = 0; i < sb_len; i ++ ) - { - char field = toupper( sb[ i ] ); - if( i ) - strcat( string, " " ); - - if( field == 'F' ) strcat( string, "Frags" ); - else if( field == 'T' ) strcat( string, "Team" ); - else if( field == 'N' ) strcat( string, "Player " ); - else if( field == 'M' ) strcat( string, "Time" ); - else if( field == 'P' ) strcat( string, "Ping" ); - else if( field == 'C' ) strcat( string, "Caps" ); - else if( field == 'S' ) strcat( string, "Score" ); - else if( field == 'K' ) strcat( string, "Kills" ); - else if( field == 'D' ) strcat( string, "Deaths" ); - else if( field == 'I' ) strcat( string, "Damage" ); - else if( field == 'A' ) strcat( string, "Acc" ); - else sprintf( string + strlen(string), "%c", sb[ i ] ); - } - - strcat( string, "\" yv 40 string2 \"" ); - - for( i = 0; i < sb_len; i ++ ) - { - char field = toupper( sb[ i ] ); - if( i ) - strcat( string, " " ); - - if( field == 'F' ) strcat( string, "\x9D\x9E\x9E\x9E\x9F" ); - else if( field == 'T' ) strcat( string, "\x9D\x9E\x9E\x9F" ); - else if( field == 'N' ) strcat( string, "\x9D\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9E\x9F" ); - else if( field == 'M' ) strcat( string, "\x9D\x9E\x9E\x9F" ); - else if( field == 'P' ) strcat( string, "\x9D\x9E\x9E\x9F" ); - else if( field == 'C' ) strcat( string, "\x9D\x9E\x9E\x9F" ); - else if( field == 'S' ) strcat( string, "\x9D\x9E\x9E\x9E\x9F" ); - else if( field == 'K' ) strcat( string, "\x9D\x9E\x9E\x9E\x9F" ); - else if( field == 'D' ) strcat( string, "\x9D\x9E\x9E\x9E\x9E\x9F" ); - else if( field == 'I' ) strcat( string, "\x9D\x9E\x9E\x9E\x9E\x9F" ); - else if( field == 'A' ) strcat( string, "\x9D\x9E\x9F" ); - else sprintf( string + strlen(string), "%c", sb[ i ] ); - } - - strcat( string, "\" " ); - - line_y = 48; - - for (i = 0; i < totalClients; i++) - { - cl = sortedClients[i]; - cl_ent = g_edicts + 1 + (cl - game.clients); - - sprintf( string + strlen(string), "yv %i string \"", line_y ); - - for( j = 0; j < sb_len; j ++ ) - { - char buf[ 16 ] = ""; - char field = toupper( sb[ j ] ); - if( j ) - strcat( string, " " ); - - if( field == 'F' ) snprintf( buf, sizeof(buf), "%5i", min( 99999, cl->resp.score ) ); - else if( field == 'T' ) - { - if( matchmode->value ) - { - char suffix = ' '; - if( IS_CAPTAIN(cl_ent) ) - suffix = 'C'; - else if( cl->resp.subteam ) - suffix = 'S'; - snprintf( buf, sizeof(buf), " %c%c", (cl->resp.team ? (cl->resp.team + '0') : ' '), suffix ); - } - else - snprintf( buf, sizeof(buf), " %c", (cl->resp.team ? (cl->resp.team + '0') : ' ') ); - } - else if( field == 'N' ) snprintf( buf, sizeof(buf), "%-15s", cl->pers.netname ); - else if( field == 'M' ) - { - int minutes = (level.framenum - cl->resp.enterframe) / (60 * HZ); - if( minutes < 60 ) - snprintf( buf, sizeof(buf), "%4i", minutes ); - else if( minutes < 600 ) - snprintf( buf, sizeof(buf), "%1i:%02i", minutes / 60, minutes % 60 ); - else - snprintf( buf, sizeof(buf), "%3ih", min( 999, minutes / 60 ) ); - } - else if( field == 'P' ) - { - snprintf( buf, sizeof(buf), "%4i", min( 9999, cl->ping ) ); - } - else if( field == 'C' ) snprintf( buf, sizeof(buf), "%4i", min( 9999, cl->resp.ctf_caps ) ); - else if( field == 'S' ) snprintf( buf, sizeof(buf), "%5i", min( 99999, cl->resp.score ) ); - else if( field == 'K' ) snprintf( buf, sizeof(buf), "%5i", min( 99999, cl->resp.kills) ); - else if( field == 'D' ) snprintf( buf, sizeof(buf), "%6i", min( 999999, cl->resp.deaths) ); - else if( field == 'I' ) snprintf( buf, sizeof(buf), "%6i", min( 999999, cl->resp.damage_dealt) ); - else if( field == 'A' ) snprintf( buf, sizeof(buf), "%3.f", cl->resp.shotsTotal ? (double) cl->resp.hitsTotal * 100.0 / (double) cl->resp.shotsTotal : 0. ); - else sprintf( buf, "%c", sb[ j ] ); - - strcat( string, buf ); - } - - strcat( string, "\" " ); - - line_y += 8; - if (strlen(string) > (maxsize - 100) && i < (totalClients - 2)) - { - sprintf (string + strlen (string), "yv %d string \"..and %d more\" ", - line_y, (totalClients - i - 1) ); - line_y += 8; - break; - } - } - } - - if (strlen(string) > MAX_SCOREBOARD_SIZE - 1) { // for debugging... - gi.Com_PrintFmt("Warning: scoreboard string neared or exceeded max length\nDump:\n%s\n---\n", string); - string[MAX_SCOREBOARD_SIZE - 1] = '\0'; - } - - gi.WriteByte(svc_layout); - gi.WriteString(string); -} - -// called when we enter the intermission -void TallyEndOfLevelTeamScores (void) -{ - int i; - gi.sound (&g_edicts[0], CHAN_VOICE | CHAN_NO_PHS_ADD, - gi.soundindex ("world/xian1.wav"), 1.0, ATTN_NONE, 0.0); - - teams[TEAM1].total = teams[TEAM2].total = teams[TEAM3].total = 0; - for (i = 0; i < game.maxclients; i++) - { - if (!g_edicts[i + 1].inuse) - continue; - if (game.clients[i].resp.team == NOTEAM) - continue; - - teams[game.clients[i].resp.team].total += game.clients[i].resp.score; - } - game.roundNum = 0; -} - - -/* - * Teamplay spawning functions... - */ - -edict_t *SelectTeamplaySpawnPoint (edict_t * ent) -{ - return teamplay_spawns[ent->client->resp.team - 1]; -} - -// SpawnPointDistance: -// Returns the distance between two spawn points (or any entities, actually...) -float SpawnPointDistance (edict_t * spot1, edict_t * spot2) -{ - return Distance(spot1->s.origin, spot2->s.origin); -} - -spawn_distances_t *spawn_distances; -// GetSpawnPoints: -// Put the spawn points into our potential_spawns array so we can work with them easily. -void GetSpawnPoints (void) -{ - edict_t *spot = NULL; - - num_potential_spawns = 0; - - if ((spot = G_FindByString<&edict_t::classname>(spot, "info_player_team1") != nullptr)) - { - potential_spawns[num_potential_spawns] = spot; - num_potential_spawns++; - } - if ((spot = G_FindByString<&edict_t::classname>(spot, "info_player_team2") != nullptr)) - { - potential_spawns[num_potential_spawns] = spot; - num_potential_spawns++; - } - - spot = nullptr; - while ((spot = G_FindByString<&edict_t::classname>(spot, "info_player_deathmatch") != nullptr)) - { - potential_spawns[num_potential_spawns] = spot; - num_potential_spawns++; - if (num_potential_spawns >= MAX_SPAWNS) - { - gi.Com_Print ("Warning: MAX_SPAWNS exceeded\n"); - break; - } - } - - if(spawn_distances) - gi.TagFree (spawn_distances); - - spawn_distances = (spawn_distances_t *)gi.TagMalloc (num_potential_spawns * - sizeof (spawn_distances_t), TAG_GAME); -} - -// compare_spawn_distances is used by the qsort() call -int compare_spawn_distances (const void *sd1, const void *sd2) -{ - if (((spawn_distances_t *)sd1)->distance < ((spawn_distances_t *)sd2)->distance) - return -1; - else if (((spawn_distances_t *)sd1)->distance > ((spawn_distances_t *)sd2)->distance) - return 1; - else - return 0; -} - -void SelectRandomTeamplaySpawnPoint (int team, bool teams_assigned[]) -{ - teamplay_spawns[team] = potential_spawns[newrand(num_potential_spawns)]; - teams_assigned[team] = true; -} - -void SelectFarTeamplaySpawnPoint (int team, bool teams_assigned[]) -{ - int x, y, spawn_to_use, preferred_spawn_points, num_already_used, - total_good_spawn_points; - float closest_spawn_distance, distance; - - if (team < 0 || team >= MAX_TEAMS) { - gi.Com_Print( "Out-of-range teams value in SelectFarTeamplaySpawnPoint, skipping...\n" ); - return; - } - - num_already_used = 0; - for (x = 0; x < num_potential_spawns; x++) - { - closest_spawn_distance = 2000000000; - - for (y = 0; y < teamCount; y++) - { - if (teams_assigned[y]) - { - distance = SpawnPointDistance (potential_spawns[x], teamplay_spawns[y]); - if (distance < closest_spawn_distance) - closest_spawn_distance = distance; - } - } - - if (closest_spawn_distance == 0) - num_already_used++; - - spawn_distances[x].s = potential_spawns[x]; - spawn_distances[x].distance = closest_spawn_distance; - } - - qsort (spawn_distances, num_potential_spawns, - sizeof (spawn_distances_t), compare_spawn_distances); - - total_good_spawn_points = num_potential_spawns - num_already_used; - - if (total_good_spawn_points <= 4) - preferred_spawn_points = 1; - else if (total_good_spawn_points <= 10) - preferred_spawn_points = 2; - else - preferred_spawn_points = 3; - - //FB 6/1/99 - make DF_SPAWN_FARTHEST force far spawn points in TP - if (g_dm_spawn_farthest->integer) - preferred_spawn_points = 1; - //FB 6/1/99 - - spawn_to_use = newrand (preferred_spawn_points); - - teams_assigned[team] = true; - teamplay_spawns[team] = spawn_distances[num_potential_spawns - spawn_to_use - 1].s; -} - -// SetupTeamSpawnPoints: -// -// Setup the points at which the teams will spawn. -// -void SetupTeamSpawnPoints () -{ - bool teams_assigned[MAX_TEAMS]; - int i, l; - - for (l = 0; l < MAX_TEAMS; l++) - { - teamplay_spawns[l] = NULL; - teams_assigned[l] = false; - } - - l = newrand(teamCount); - - SelectRandomTeamplaySpawnPoint(l, teams_assigned); - - for(i = l+1; i < teamCount+l; i++) { - SelectFarTeamplaySpawnPoint(i % teamCount, teams_assigned); - } -} - -// TNG:Freud New Spawning system -// NS_GetSpawnPoints: -// Put the potential spawns into arrays for each team. -void NS_GetSpawnPoints () -{ - int x, i; - - NS_randteam = newrand(teamCount); - - for (x = 0; x < teamCount; x++) - { - NS_num_used_farteamplay_spawns[x] = 0; - NS_num_potential_spawns[x] = num_potential_spawns; - for(i = 0; i < num_potential_spawns; i++) - NS_potential_spawns[x][i] = potential_spawns[i]; - } -} - -// TNG:Freud -// NS_SelectRandomTeamplaySpawnPoint -// Select a random spawn point for the team from remaining spawns. -// returns false if no spawns left. -bool NS_SelectRandomTeamplaySpawnPoint (int team, bool teams_assigned[]) -{ - int spawn_point, z; - - if (NS_num_potential_spawns[team] < 1) { - gi.Com_Print("New Spawncode: gone through all spawns, re-reading spawns\n"); - NS_GetSpawnPoints (); - NS_SetupTeamSpawnPoints (); - return false; - } - - spawn_point = newrand (NS_num_potential_spawns[team]); - NS_num_potential_spawns[team]--; - - teamplay_spawns[team] = NS_potential_spawns[team][spawn_point]; - teams_assigned[team] = true; - - for (z = spawn_point;z < NS_num_potential_spawns[team];z++) { - NS_potential_spawns[team][z] = NS_potential_spawns[team][z + 1]; - } - - return true; -} - -// TNG:Freud -#define MAX_USABLESPAWNS 3 -// NS_SelectFarTeamplaySpawnPoint -// Selects farthest teamplay spawn point from available spawns. -bool NS_SelectFarTeamplaySpawnPoint (int team, bool teams_assigned[]) -{ - int u, x, y, z, spawn_to_use, preferred_spawn_points, num_already_used, - total_good_spawn_points; - float closest_spawn_distance, distance; - edict_t *usable_spawns[MAX_USABLESPAWNS]; - bool used; - int num_usable; - - if (team < 0 || team >= MAX_TEAMS) { - gi.Com_Print( "Out-of-range teams value in SelectFarTeamplaySpawnPoint, skipping...\n" ); - return false; - } - - num_already_used = 0; - for (x = 0; x < NS_num_potential_spawns[team]; x++) - { - closest_spawn_distance = 2000000000; - - for (y = 0; y < teamCount; y++) - { - if (teams_assigned[y]) - { - distance = - SpawnPointDistance (NS_potential_spawns[team][x], teamplay_spawns[y]); - - if (distance < closest_spawn_distance) - closest_spawn_distance = distance; - } - } - - if (closest_spawn_distance == 0) - num_already_used++; - - spawn_distances[x].s = NS_potential_spawns[team][x]; - spawn_distances[x].distance = closest_spawn_distance; - } - - qsort (spawn_distances, NS_num_potential_spawns[team], - sizeof (spawn_distances_t), compare_spawn_distances); - - total_good_spawn_points = NS_num_potential_spawns[team] - num_already_used; - - if (total_good_spawn_points <= 4) - preferred_spawn_points = 1; - else if (total_good_spawn_points <= 10) - preferred_spawn_points = 2; - else - preferred_spawn_points = 3; - - //FB 6/1/99 - make DF_SPAWN_FARTHEST force far spawn points in TP - if (g_dm_spawn_farthest->integer) - preferred_spawn_points = 1; - //FB 6/1/99 - - num_usable = 0; - for (z = 0;z < preferred_spawn_points;z++) { - used = false; - for (u = 0;u < NS_num_used_farteamplay_spawns[team];u++) { - if (NS_used_farteamplay_spawns[team][u] == - spawn_distances[NS_num_potential_spawns[team] - z - 1].s) { - used = true; - break; - } - } - if (used == false) { - usable_spawns[num_usable] = spawn_distances[NS_num_potential_spawns[team] - z - 1].s; - num_usable++; - if (num_usable >= MAX_USABLESPAWNS) { - break; - } - } - } - if (num_usable < 1) { - NS_SetupTeamSpawnPoints(); - return false; - } - - spawn_to_use = newrand(num_usable); - - NS_used_farteamplay_spawns[team][NS_num_used_farteamplay_spawns[team]] = usable_spawns[spawn_to_use]; - NS_num_used_farteamplay_spawns[team]++; - - teams_assigned[team] = true; - teamplay_spawns[team] = usable_spawns[spawn_to_use]; - - return true; -} - -// TNG:Freud -// NS_SetupTeamSpawnPoints -// Finds and assigns spawn points to each team. -void NS_SetupTeamSpawnPoints () -{ - bool teams_assigned[MAX_TEAMS]; - int l; - - for (l = 0; l < MAX_TEAMS; l++) { - teamplay_spawns[l] = NULL; - teams_assigned[l] = false; - } - - if (NS_SelectRandomTeamplaySpawnPoint (NS_randteam, teams_assigned) == false) - return; - - for (l = 0; l < teamCount; l++) { - if (l != NS_randteam && NS_SelectFarTeamplaySpawnPoint(l, teams_assigned) == false) - return; - } -} - -/* -Simple function that just returns the opposite team number -Obviously, do not use this for 3team functions -*/ -int OtherTeam(int teamNum) -{ - if (teamNum < 0 || teamNum > TEAM2) { - gi.Com_Print("OtherTeam() was called but parameter supplied is not 1 or 2"); - return 0; - } - - if (teamNum == 1) - return TEAM2; - else - return TEAM1; - - // Returns zero if teamNum is not 1 or 2 - return 0; -} \ No newline at end of file diff --git a/actionlite/a_team.h b/actionlite/a_team.h deleted file mode 100644 index c060a75..0000000 --- a/actionlite/a_team.h +++ /dev/null @@ -1,112 +0,0 @@ -#include "g_local.h" - -#define NOTEAM 0 -#define TEAM1 1 -#define TEAM2 2 -#define TEAM3 3 - -#define MAX_TEAMS 3 -#define TEAM_TOP (MAX_TEAMS+1) - -#define WINNER_NONE NOTEAM -#define WINNER_TIE TEAM_TOP - -// Pre- and post-trace code for our teamplay anti-stick stuff. If there are -// still "transparent" (SOLID_TRIGGER) players, they need to be set to -// SOLID_BBOX before a trace is performed, then changed back again -// afterwards. PRETRACE() and POSTTRACE() should be called before and after -// traces in all places where combat is taking place (ie "transparent" players -// should be detected), ie shots being traced etc. -// FB 6/1/99: Now crouching players will have their bounding box adjusted here -// too, for better shot areas. (there has to be a better way to do this?) - -#define PRETRACE() \ - if (transparent_list && (((int)teamplay->value && !lights_camera_action))) \ - TransparentListSet(SOLID_BBOX) - -#define POSTTRACE() \ - if (transparent_list && (((int)teamplay->value && !lights_camera_action))) \ - TransparentListSet(SOLID_TRIGGER) - -edict_t *SelectTeamplaySpawnPoint (edict_t *); -bool FallingDamageAmnesty (edict_t * targ); -char * TeamName (int team); -void UpdateJoinMenu( void ); -void OpenJoinMenu (edict_t *); -void OpenWeaponMenu (edict_t *); -void OpenItemMenu (edict_t * ent); -void OpenItemKitMenu (edict_t * ent); -void JoinTeam (edict_t * ent, int desired_team, int skip_menuclose); -edict_t *FindOverlap (edict_t * ent, edict_t * last_overlap); -int CheckTeamRules (void); -void A_Scoreboard (edict_t * ent); -void Team_f (edict_t * ent); -void AssignSkin (edict_t * ent, const char *s, bool nickChanged); -void TallyEndOfLevelTeamScores (void); -void SetupTeamSpawnPoints (); -int CheckTeamSpawnPoints (); -void GetSpawnPoints (); -void CleanBodies (); // from p_client.c, removes all current dead bodies from map - -void LeaveTeam (edict_t *); -int newrand (int top); -void InitTransparentList (); -void AddToTransparentList (edict_t *); -void RemoveFromTransparentList (edict_t *); -bool OnTransparentList( const edict_t *ent ); -void PrintTransparentList (); -void CenterPrintAll (const char *msg); -int TeamHasPlayers( int team ); - -//TNG:Freud - new spawning system -void NS_GetSpawnPoints (); -bool NS_SelectFarTeamplaySpawnPoint (int team, bool teams_assigned[]); -void NS_SetupTeamSpawnPoints (); - -int OtherTeam(int teamNum); - -typedef struct spawn_distances_s -{ - float distance; - edict_t *s; -} -spawn_distances_t; - -typedef struct transparent_list_s -{ - edict_t *ent; - struct transparent_list_s *next; -} -transparent_list_t; - - -extern bool team_game_going; -extern bool team_round_going; -extern int lights_camera_action; -extern int holding_on_tie_check; -extern int team_round_countdown; -extern int timewarning; -extern int fragwarning; -extern transparent_list_t *transparent_list; -extern trace_t trace_t_temp; -extern int current_round_length; // For RoundTimeLeft -extern int day_cycle_at; -extern int teamCount; -extern int in_warmup; -extern bool teams_changed; - -typedef struct menu_list_weapon -{ - int num; - char sound[40]; - char name[40]; -} -menu_list_weapon; - -typedef struct menu_list_item -{ - int num; - char sound[40]; - char name[40]; -} -menu_list_item; diff --git a/actionlite/bg_local.h b/actionlite/bg_local.h index 927e318..8dee061 100644 --- a/actionlite/bg_local.h +++ b/actionlite/bg_local.h @@ -198,24 +198,28 @@ enum player_stat_t STAT_SPECTATOR = 17, STAT_TEAM1_PIC = 18, - STAT_CTF_TEAM1_CAPS = 19, STAT_TEAM2_PIC = 20, - STAT_CTF_TEAM2_CAPS = 21, + STAT_TEAM3_PIC = 21, STAT_FLAG_PIC = 22, STAT_JOINED_TEAM1_PIC = 23, STAT_JOINED_TEAM2_PIC = 24, - STAT_TEAM1_HEADER = 25, - STAT_TEAM2_HEADER = 26, - STAT_CTF_TECH = 27, - STAT_CTF_ID_VIEW = 28, - STAT_CTF_MATCH = 29, - STAT_CTF_ID_VIEW_COLOR = 30, - STAT_CTF_TEAMINFO = 31, + STAT_JOINED_TEAM3_PIC = 25, + // Action: Consolidate team headers into level.pic_teamtag + // STAT_TEAM1_HEADER = 25, + // STAT_TEAM2_HEADER = 26, + STAT_TEAM_HEADER = 26, + STAT_CTF_TEAM1_CAPS = 27, + STAT_CTF_TEAM2_CAPS = 28, + STAT_CTF_TECH = 29, + STAT_CTF_ID_VIEW = 30, + STAT_CTF_MATCH = 31, + STAT_CTF_ID_VIEW_COLOR = 32, + STAT_CTF_TEAMINFO = 33, // [Kex] More stats for weapon wheel - STAT_WEAPONS_OWNED_1 = 32, - STAT_WEAPONS_OWNED_2 = 33, - STAT_AMMO_INFO_START = 34, + STAT_WEAPONS_OWNED_1 = 34, + STAT_WEAPONS_OWNED_2 = 35, + STAT_AMMO_INFO_START = 36, STAT_AMMO_INFO_END = STAT_AMMO_INFO_START + NUM_AMMO_STATS - 1, STAT_POWERUP_INFO_START, STAT_POWERUP_INFO_END = STAT_POWERUP_INFO_START + NUM_POWERUP_STATS - 1, @@ -247,18 +251,12 @@ enum player_stat_t STAT_ITEMS_ICON, STAT_WEAPONS_ICON, STAT_ID_VIEW, - - STAT_TEAM_HEADER, - STAT_TEAM1_SCORE, STAT_TEAM2_SCORE, STAT_TEAM3_SCORE, - STAT_GRENADE_ICON, STAT_GRENADES, - STAT_TEAM3_PIC, - // don't use; just for verification STAT_LAST }; diff --git a/actionlite/cgf_sfx_glass.cpp b/actionlite/cgf_sfx_glass.cpp deleted file mode 100644 index 3ce5e64..0000000 --- a/actionlite/cgf_sfx_glass.cpp +++ /dev/null @@ -1,741 +0,0 @@ -/****************************************************************************/ -/* */ -/* project : CGF (c) 1999 William van der Sterren */ -/* parts (c) 1998 id software */ -/* */ -/* file : cgf_sfx_glass.cpp "special effects for glass entities" */ -/* author(s): William van der Sterren */ -/* version : 0.5 */ -/* */ -/* date (last revision): Jun 12, 99 */ -/* date (creation) : Jun 04, 99 */ -/* */ -/* */ -/* revision history */ -/* -- date ---- | -- revision ---------------------- | -- revisor -- */ -/* Jun 12, 1999 | fixed knife slash breaks glass | William */ -/* Jun 08, 1999 | improved fragment limit | William */ -/* */ -/******* http://www.botepidemic.com/aid/cgf for CGF for Action Quake2 *******/ -// -// $Id: cgf_sfx_glass.c,v 1.2 2001/09/28 13:48:34 ra Exp $ -// -//----------------------------------------------------------------------------- -// $Log: cgf_sfx_glass.c,v $ -// Revision 1.2 2001/09/28 13:48:34 ra -// I ran indent over the sources. All .c and .h files reindented. -// -// Revision 1.1.1.1 2001/05/06 17:29:34 igor_rock -// This is the PG Bund Edition V1.25 with all stuff laying around here... -// -//----------------------------------------------------------------------------- - -#ifdef __cplusplus - // VC++, for CGF -#include // prevent problems between C and STL -extern "C" -{ -#include "g_local.h" -#include "cgf_sfx_glass.h" -} -#else - // C, for other AQ2 variants -#include "g_local.h" -#include "cgf_sfx_glass.h" -#endif - - -// cvar for breaking glass -static cvar_t *breakableglass = 0; - -// cvar for max glass fragment count -static cvar_t *glassfragmentlimit = 0; - -static int glassfragmentcount = 0; - - -// additional functions - Q2 expects C calling convention -#ifdef __cplusplus -extern "C" -{ -#endif - - void CGF_SFX_TouchGlass (edict_t * self, edict_t * other, cplane_t * plane, - csurface_t * surf); -// called whenever an entity hits the trigger spawned for the glass - - void CGF_SFX_EmitGlass (edict_t * aGlassPane, edict_t * anInflictor, - vec3_t aPoint); -// emits glass fragments from aPoint, to show effects of firing thru window - - void CGF_SFX_BreakGlass (edict_t * aGlassPane, edict_t * anOther, - edict_t * anAttacker, int aDamage, vec3_t aPoint, - vec_t aPaneDestructDelay); -// breaks glass - - void CGF_SFX_InstallBreakableGlass (edict_t * aGlassPane); -// when working on a glass pane for the first time, just install trigger -// when working on a glass pane again (after a game ended), move -// glass back to original location - - void CGF_SFX_HideBreakableGlass (edict_t * aGlassPane); -// after being broken, the pane cannot be removed as it is needed in -// subsequent missions/games, so hide it at about z = -1000 - - void CGF_SFX_ApplyGlassFragmentLimit (const char *aClassName); -// updates glassfragmentcount and removes oldest glass fragement if -// necessary to meet limit - - void CGF_SFX_MiscGlassUse (edict_t * self, edict_t * other, - edict_t * activator); -// catches use from unforeseen objects (weapons, debris, -// etc. touching the window) - - void CGF_SFX_MiscGlassDie (edict_t * self, edict_t * inflictor, - edict_t * attacker, int damage, vec3_t point); -// catches die calls caused by unforeseen objects (weapons, debris, -// etc. damaging the window) - - void CGF_SFX_GlassThrowDebris (edict_t * self, char *modelname, float speed, - vec3_t origin); -// variant of id software's ThrowDebris, now numbering the entity (for later removal) - - extern // from a_game.c - edict_t *FindEdictByClassnum (char *classname, int classnum); - -// declaration from g_misc.c - extern // from g_misc.c - void debris_die (edict_t * self, edict_t * inflictor, edict_t * attacker, - int damage, vec3_t point); - -#ifdef __cplusplus -} -#endif - - - -void -CGF_SFX_InstallGlassSupport () -{ - breakableglass = gi.cvar ("breakableglass", "0", 0); - glassfragmentlimit = gi.cvar ("glassfragmentlimit", "30", 0); -} - - -int -CGF_SFX_IsBreakableGlassEnabled () -{ - // returns whether breakable glass is enabled (cvar) and allowed (dm mode) - return breakableglass->value; -} - - - -void -CGF_SFX_TestBreakableGlassAndRemoveIfNot_Think (edict_t * - aPossibleGlassEntity) -{ - // at level.time == 0.1 the entity has been introduced in the game, - // and we can use gi.pointcontents and gi.trace to check the entity - vec3_t origin; - int breakingglass; - trace_t trace; - - // test for cvar - if (!CGF_SFX_IsBreakableGlassEnabled ()) - { - G_FreeEdict (aPossibleGlassEntity); - return; - } - - VectorAdd (aPossibleGlassEntity->absmax, aPossibleGlassEntity->absmin, - origin); - VectorScale (origin, 0.5, origin); - - // detect glass (does not work for complex shapes, - // for example, the glass window near the satellite - // dish at Q2 base3 - breakingglass = (gi.pointcontents (origin) & CONTENTS_TRANSLUCENT); - - if (!breakingglass) - { - // test for complex brushes that happen to be - // hollow in their origin (for instance, the - // window at Q2 base3, near the satellite dish - trace = - gi.trace (origin, vec3_origin, vec3_origin, - aPossibleGlassEntity->absmax, 0, MASK_PLAYERSOLID); - breakingglass = ((trace.ent == aPossibleGlassEntity) - && (trace.contents & CONTENTS_TRANSLUCENT)); - trace = - gi.trace (origin, vec3_origin, vec3_origin, - aPossibleGlassEntity->absmin, 0, MASK_PLAYERSOLID); - breakingglass = ((breakingglass) - || ((trace.ent == aPossibleGlassEntity) - && (trace.contents & CONTENTS_TRANSLUCENT))); - } - - if (!breakingglass) - { - // do remove other func_explosives - G_FreeEdict (aPossibleGlassEntity); - return; - } - - // discovered some glass - now make store the origin - // we need that after hiding the glass - VectorCopy (aPossibleGlassEntity->s.origin, aPossibleGlassEntity->pos1); // IMPORTANT! - - // make a backup of the health in light_level - aPossibleGlassEntity->light_level = aPossibleGlassEntity->health; - - // install the glass - CGF_SFX_InstallBreakableGlass (aPossibleGlassEntity); -} - - - -void -CGF_SFX_InstallBreakableGlass (edict_t * aGlassPane) -{ - // when working on a glass pane for the first time, just install trigger - // when working on a glass pane again (after a game ended), move - // glass back to original location - edict_t *trigger; - vec3_t maxs; - vec3_t mins; - - // reset origin based on aGlassPane->pos1 - VectorCopy (aGlassPane->pos1, aGlassPane->s.origin); - - // reset health based on aGlassPane->light_level - aGlassPane->health = aGlassPane->light_level; - - // replace die and use functions by glass specific ones - aGlassPane->die = CGF_SFX_MiscGlassDie; - aGlassPane->use = CGF_SFX_MiscGlassUse; - - // reset some pane attributes - aGlassPane->takedamage = DAMAGE_YES; - aGlassPane->solid = SOLID_BSP; - aGlassPane->movetype = MOVETYPE_FLYMISSILE; - // for other movetypes, cannot move pane to hidden location and back - - // try to establish size - VectorCopy (aGlassPane->maxs, maxs); - VectorCopy (aGlassPane->mins, mins); - - // set up trigger, similar to triggers for doors - // but with a smaller box - mins[0] -= 24; - mins[1] -= 24; - mins[2] -= 24; - maxs[0] += 24; - maxs[1] += 24; - maxs[2] += 24; - - // adjust some settings - trigger = G_Spawn (); - trigger->classname = "breakableglass_trigger"; - VectorCopy (mins, trigger->mins); - VectorCopy (maxs, trigger->maxs); - trigger->owner = aGlassPane; - trigger->solid = SOLID_TRIGGER; - trigger->movetype = MOVETYPE_NONE; - trigger->touch = CGF_SFX_TouchGlass; - gi.linkentity (trigger); -} - - -void -CGF_SFX_ShootBreakableGlass (edict_t * aGlassPane, edict_t * anAttacker, - /*trace_t* */ void *tr, - int mod) -{ - // process gunshots thru glass - edict_t *trigger; - int destruct; - - // depending on mod, destroy window or emit fragments - switch (mod) - { - // break for ap, shotgun, handcannon, and kick, destory window - case MOD_M3: - case MOD_HC: - case MOD_SNIPER: - case MOD_KICK: - case MOD_GRENADE: - case MOD_G_SPLASH: - case MOD_HANDGRENADE: - case MOD_HG_SPLASH: - case MOD_KNIFE: // slash damage - destruct = true; - break; - default: - destruct = (rand () % 3 == 0); - break; - }; - - if (destruct) - { - // break glass (and hurt if doing kick) - CGF_SFX_BreakGlass (aGlassPane, anAttacker, 0, aGlassPane->health, - vec3_origin, FRAMETIME); - if (mod.id == MOD_KICK) - { - vec3_t bloodorigin; - vec3_t dir; - vec3_t normal; - VectorAdd (aGlassPane->absmax, aGlassPane->absmin, bloodorigin); - VectorScale (bloodorigin, 0.5, bloodorigin); - VectorSubtract (bloodorigin, anAttacker->s.origin, dir); - VectorNormalize (dir); - VectorMA (anAttacker->s.origin, 32.0, dir, bloodorigin); - VectorSet (normal, 0, 0, -1); - T_Damage (anAttacker, aGlassPane, anAttacker, dir, bloodorigin, - normal, 15.0, 0, 0, MOD_BREAKINGGLASS); - } - - // remove corresponding trigger - trigger = 0; - while ((trigger = G_Find (trigger, FOFS (classname), "breakableglass_trigger")) != NULL) - { - if (trigger->owner == aGlassPane) - { - // remove it - G_FreeEdict (trigger); - // only one to be found - break; - } - } - } - else - { - // add decal (if not grenade) - if ((mod != MOD_HANDGRENADE) - && (mod != MOD_HG_SPLASH) - && (mod != MOD_GRENADE) && (mod != MOD_G_SPLASH)) - { - AddDecal (anAttacker, (trace_t *) tr); - } - // and emit glass - CGF_SFX_EmitGlass (aGlassPane, anAttacker, ((trace_t *) tr)->endpos); - } -} - - -void -CGF_SFX_TouchGlass (edict_t * self, edict_t * other, cplane_t * plane, - csurface_t * surf) -{ - // called whenever an entity hits the trigger spawned for the glass - - vec3_t origin; - vec3_t normal; - vec3_t spot; - trace_t trace; - edict_t *glass; - vec3_t velocity; - vec_t speed; - vec_t projected_speed; - int is_hgrenade; - int is_knife; - - is_hgrenade = is_knife = false; - - // ignore non-clients-non-grenade-non-knife - if (!other->client) - { - is_knife = (0 == Q_stricmp ("weapon_knife", other->classname)); - if (!is_knife) - { - is_hgrenade = (0 == Q_stricmp ("hgrenade", other->classname)); - } - - if ((!is_knife) && (!is_hgrenade)) - return; - if (is_knife) - goto knife_and_grenade_handling; - } - - // test whether other really hits the glass - deal with - // the special case that other hits some boundary close to the border of the glass pane - // - // - // ....trigger....... - // +++++++++ +++++++++++ - // .+---glass------+. - // wall .+--------------+.wall - // +++++++++ +++++++++++ - // ----->.................. - // wrong ^ ^ - // | | - // wrong ok - // - glass = self->owner; - // hack - set glass' movetype to MOVETYPE_PUSH as it is not - // moving as long as the trigger is active - glass->movetype = MOVETYPE_PUSH; - - VectorAdd (glass->absmax, glass->absmin, origin); - VectorScale (origin, 0.5, origin); - - // other needs to be able to trace to glass origin - trace = gi.trace (other->s.origin, vec3_origin, vec3_origin, origin, other, - MASK_PLAYERSOLID); - if (trace.ent != glass) - return; - - // we can reach the glass origin, so we have the normal of - // the glass plane - VectorCopy (trace.plane.normal, normal); - - // we need to check if client is not running into wall next - // to the glass (the trigger stretches into the wall) - VectorScale (normal, -1000.0, spot); - VectorAdd (spot, other->s.origin, spot); - // line between other->s.origin and spot (perpendicular to glass - // surface should not hit wall but glass instead - trace = gi.trace (other->s.origin, vec3_origin, vec3_origin, spot, other, - MASK_PLAYERSOLID); - if (trace.ent != glass) - return; - - // now, we check if the client's speed perpendicular to - // the glass plane, exceeds the required 175 - // (speed should be < -200, as the plane's normal - // points towards the client - VectorCopy (other->velocity, velocity); - speed = VectorNormalize (velocity); - projected_speed = speed * DotProduct (velocity, normal); - - // bump projected speed for grenades - they should break - // the window more easily - if (is_hgrenade) - projected_speed *= 1.5f; - - // if hitting the glass with sufficient speed (project < -175), - // being jumpkicked (speed > 700, project < -5) break the window - if (!((projected_speed < -175.0) || - ((projected_speed < -5) && (speed > 700)))) - goto knife_and_grenade_handling; - - // break glass - CGF_SFX_BreakGlass (glass, other, other, glass->health, vec3_origin, - 3.0f * FRAMETIME); - // glass can take care of itself, but the trigger isn't needed anymore - G_FreeEdict (self); - - /* not needed - // reduce momentum of the client (he just broke the window - // so he should lose speed. in addition, it doesn't feel - // right if he overtakes the glass fragments - // VectorScale(normal, 200.0, velocity); - // VectorAdd(other->velocity, velocity, other->velocity); - */ - - // make sure client takes damage - T_Damage (other, glass, other, normal, other->s.origin, normal, 15.0, 0, 0, - MOD_BREAKINGGLASS); - return; - - // goto label -knife_and_grenade_handling: - // if knife or grenade, bounce them - if ((is_knife) || (is_hgrenade)) - { - // change clipmask to bounce of glass - other->clipmask = MASK_SOLID; - } -} - - -void -CGF_SFX_BreakGlass (edict_t * aGlassPane, edict_t * anInflictor, - edict_t * anAttacker, int aDamage, vec3_t aPoint, - vec_t aPaneDestructDelay) -{ - // based on func_explode, but with lotsa subtle differences - vec3_t origin; - vec3_t old_origin; - vec3_t chunkorigin; - vec3_t size; - int count; - int mass; - - // bmodel origins are (0 0 0), we need to adjust that here - VectorCopy (aGlassPane->s.origin, old_origin); - VectorScale (aGlassPane->size, 0.5, size); - VectorAdd (aGlassPane->absmin, size, origin); - VectorCopy (origin, aGlassPane->s.origin); - - aGlassPane->takedamage = DAMAGE_NO; - - VectorSubtract (aGlassPane->s.origin, anInflictor->s.origin, - aGlassPane->velocity); - VectorNormalize (aGlassPane->velocity); - // use speed 250 instead of 150 for funkier glass spray - VectorScale (aGlassPane->velocity, 250.0, aGlassPane->velocity); - - // start chunks towards the center - VectorScale (size, 0.75, size); - - mass = aGlassPane->mass; - if (!mass) - mass = 75; - - // big chunks - if (mass >= 100) - { - count = mass / 100; - if (count > 8) - count = 8; - while (count--) - { - CGF_SFX_ApplyGlassFragmentLimit ("debris"); - chunkorigin[0] = origin[0] + crandom () * size[0]; - chunkorigin[1] = origin[1] + crandom () * size[1]; - chunkorigin[2] = origin[2] + crandom () * size[2]; - CGF_SFX_GlassThrowDebris (aGlassPane, - "models/objects/debris1/tris.md2", 1, - chunkorigin); - } - } - - // small chunks - count = mass / 25; - if (count > 16) - count = 16; - while (count--) - { - CGF_SFX_ApplyGlassFragmentLimit ("debris"); - chunkorigin[0] = origin[0] + crandom () * size[0]; - chunkorigin[1] = origin[1] + crandom () * size[1]; - chunkorigin[2] = origin[2] + crandom () * size[2]; - CGF_SFX_GlassThrowDebris (aGlassPane, "models/objects/debris2/tris.md2", - 2, chunkorigin); - } - - // clear velocity, reset origin (that has been abused in ThrowDebris) - VectorClear (aGlassPane->velocity); - VectorCopy (old_origin, aGlassPane->s.origin); - - if (anAttacker) - { - // jumping thru - G_UseTargets (aGlassPane, anAttacker); - } - else - { - // firing thru - the pane has no direct attacker to hurt, - // but G_UseTargets expects one. So make it a DIY - G_UseTargets (aGlassPane, aGlassPane); - } - - // have glass plane be visible for two more frames, - // and have it self-destruct then - // meanwhile, make sure the player can move thru - aGlassPane->solid = SOLID_NOT; - aGlassPane->think = CGF_SFX_HideBreakableGlass; - aGlassPane->nextthink = level.framenum + aPaneDestructDelay * HZ; -} - - - -void -CGF_SFX_EmitGlass (edict_t * aGlassPane, edict_t * anInflictor, vec3_t aPoint) -{ - // based on func_explode, but with lotsa subtle differences - vec3_t old_origin; - vec3_t chunkorigin; - vec3_t size; - int count; - - // bmodel origins are (0 0 0), we need to adjust that here - VectorCopy (aGlassPane->s.origin, old_origin); - VectorCopy (aPoint, aGlassPane->s.origin); - - VectorSubtract (aGlassPane->s.origin, anInflictor->s.origin, - aGlassPane->velocity); - VectorNormalize (aGlassPane->velocity); - // use speed 250 instead of 150 for funkier glass spray - VectorScale (aGlassPane->velocity, 250.0, aGlassPane->velocity); - - // start chunks towards the center - VectorScale (aGlassPane->size, 0.25, size); - - count = 4; - while (count--) - { - CGF_SFX_ApplyGlassFragmentLimit ("debris"); - chunkorigin[0] = aPoint[0] + crandom () * size[0]; - chunkorigin[1] = aPoint[1] + crandom () * size[1]; - chunkorigin[2] = aPoint[2] + crandom () * size[2]; - CGF_SFX_GlassThrowDebris (aGlassPane, "models/objects/debris2/tris.md2", - 2, chunkorigin); - } - - // clear velocity, reset origin (that has been abused in ThrowDebris) - VectorClear (aGlassPane->velocity); - VectorCopy (old_origin, aGlassPane->s.origin); - - // firing thru - the pane has no direct attacker to hurt, - // but G_UseTargets expects one. So make it a DIY - G_UseTargets (aGlassPane, aGlassPane); -} - - - -void -CGF_SFX_HideBreakableGlass (edict_t * aGlassPane) -{ - // remove all attached decals - edict_t *decal; - decal = 0; - while ((decal = G_Find (decal, FOFS (classname), "decal")) != NULL) - { - if (decal->owner == aGlassPane) - { - // make it goaway in the next frame - decal->think = G_FreeEdict; - decal->nextthink = level.framenum + 1; - } - } - - while ((decal = G_Find (decal, FOFS (classname), "splat")) != NULL) - { - if (decal->owner == aGlassPane) - { - // make it goaway in the next frame - decal->think = G_FreeEdict; - decal->nextthink = level.framenum + 1; - } - } - - // after being broken, the pane cannot be freed as it is needed in - // subsequent missions/games, so hide it at about z = -1000 lower - aGlassPane->movetype = MOVETYPE_FLYMISSILE; - VectorCopy (aGlassPane->s.origin, aGlassPane->pos1); - aGlassPane->s.origin[2] -= 1000.0; -} - - - -void -CGF_SFX_AttachDecalToGlass (edict_t * aGlassPane, edict_t * aDecal) -{ - // just set aDecal's owner to be the glass pane - aDecal->owner = aGlassPane; -} - - - -void -CGF_SFX_RebuildAllBrokenGlass () -{ - // iterate over all func_explosives - edict_t *glass; - glass = 0; - while ((glass = G_Find (glass, FOFS (classname), "func_explosive")) != NULL) - { - // glass is broken if solid != SOLID_BSP - if (glass->solid != SOLID_BSP) - { - CGF_SFX_InstallBreakableGlass (glass); - } - } -} - - - -void -CGF_SFX_ApplyGlassFragmentLimit (const char *aClassName) -{ - edict_t *oldfragment; - - glassfragmentcount++; - if (glassfragmentcount > glassfragmentlimit->value) - glassfragmentcount = 1; - - // remove fragment with corresponding number if any - oldfragment = FindEdictByClassnum ((char *) aClassName, glassfragmentcount); - - if (oldfragment) - { - // oldfragment->nextthink = level.framenum + 1; - G_FreeEdict (oldfragment); - } -} - - - -void -CGF_SFX_MiscGlassUse (edict_t * self, edict_t * other, edict_t * activator) -{ -#ifdef _DEBUG - const char *classname; - classname = other->classname; -#endif -} - - - -void -CGF_SFX_MiscGlassDie (edict_t * self, edict_t * inflictor, edict_t * attacker, - int damage, vec3_t point) -{ -#ifdef _DEBUG - const char *classname; - classname = inflictor->classname; -#endif -} - - - -static vec_t previous_throw_time = 0; -static int this_throw_count = 0; - -void -CGF_SFX_GlassThrowDebris (edict_t * self, char *modelname, float speed, - vec3_t origin) -{ - // based on ThrowDebris from id software - now returns debris created - edict_t *chunk; - vec3_t v; - - if (level.time != previous_throw_time) - { - previous_throw_time = level.time; - this_throw_count = 0; - } - else - { - this_throw_count++; - if (this_throw_count > glassfragmentlimit->value) - return; - } - - chunk = G_Spawn (); - VectorCopy (origin, chunk->s.origin); - gi.setmodel (chunk, modelname); - v[0] = 100 * crandom (); - v[1] = 100 * crandom (); - v[2] = 100 + 100 * crandom (); - VectorMA (self->velocity, speed, v, chunk->velocity); - chunk->movetype = MOVETYPE_BOUNCE; - chunk->solid = SOLID_NOT; - chunk->avelocity[0] = random () * 600; - chunk->avelocity[1] = random () * 600; - chunk->avelocity[2] = random () * 600; - chunk->think = G_FreeEdict; - chunk->nextthink = level.framenum + (5 + random() * 5) * HZ; - chunk->s.frame = 0; - chunk->flags = 0; - chunk->classname = "debris"; - chunk->takedamage = DAMAGE_YES; - chunk->die = debris_die; - gi.linkentity (chunk); - - // number chunk - chunk->classnum = glassfragmentcount; -} diff --git a/actionlite/cgf_sfx_glass.h b/actionlite/cgf_sfx_glass.h deleted file mode 100644 index 0a70b94..0000000 --- a/actionlite/cgf_sfx_glass.h +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************************/ -/* */ -/* project : CGF (c) 1999 William van der Sterren */ -/* parts (c) 1998 id software */ -/* */ -/* file : cgf_sfx_glass.h "special effects for glass entities" */ -/* author(s): William van der Sterren */ -/* version : 0.5 */ -/* */ -/* date (last revision): Jun 12, 99 */ -/* date (creation) : Jun 04, 99 */ -/* */ -/* */ -/* revision history */ -/* -- date ---- | -- revision ---------------------- | -- revisor -- */ -/* Jun 12, 1999 | fixed knife slash breaks glass | William */ -/* */ -/******* http://www.botepidemic.com/aid/cgf for CGF for Action Quake2 *******/ -// -// $Id: cgf_sfx_glass.h,v 1.2 2001/09/28 13:48:34 ra Exp $ -// -//----------------------------------------------------------------------------- -// $Log: cgf_sfx_glass.h,v $ -// Revision 1.2 2001/09/28 13:48:34 ra -// I ran indent over the sources. All .c and .h files reindented. -// -// Revision 1.1.1.1 2001/05/06 17:29:34 igor_rock -// This is the PG Bund Edition V1.25 with all stuff laying around here... -// -//----------------------------------------------------------------------------- - -#ifndef __CGF_SFX_GLASS_H_ -#define __CGF_SFX_GLASS_H_ - - -// defines (should be consistent with other weapon defs in g_local.h) -#define MOD_BREAKINGGLASS 46 - -/* - // forward definitions - typedef struct edict_s edict_t; - */ - - -// export a number of functions to g_func.c: -// -// - -void CGF_SFX_InstallGlassSupport (); -// registers cvar breakableglass (default 0) -// registers cvar glassfragmentlimit (default 30) - - -void CGF_SFX_RebuildAllBrokenGlass (); -// upon starting a new team play game, reconstruct any -// broken glass because we like to break it again - - -int CGF_SFX_IsBreakableGlassEnabled (); -// returns whether breakable glass is enabled (cvar breakableglass) - - -void CGF_SFX_TestBreakableGlassAndRemoveIfNot_Think (edict_t * - aPossibleGlassEntity); -// initial think function for all func_explosives -// because we cannot verify the contents of the entity unless the entity -// has been spawned, we need to first introduce the entity, and remove -// it later (level.time == 0.1) if required - - -void CGF_SFX_ShootBreakableGlass (edict_t * aGlassPane, edict_t * anAttacker, - /*trace_t */ void *tr, - int mod); -// shoot thru glass - depending on bullet types and -// random effects, glass just emits fragments, or breaks - - -void CGF_SFX_AttachDecalToGlass (edict_t * aGlassPane, edict_t * aDecal); -// a glass that breaks will remove all decals (blood splashes, bullet -// holes) if they are attached - - -#endif diff --git a/actionlite/ctf/g_ctf.cpp b/actionlite/ctf/g_ctf.cpp index 5456583..24bcdbc 100644 --- a/actionlite/ctf/g_ctf.cpp +++ b/actionlite/ctf/g_ctf.cpp @@ -5,52 +5,15 @@ #include -enum match_t -{ - MATCH_NONE, - MATCH_SETUP, - MATCH_PREGAME, - MATCH_GAME, - MATCH_POST -}; - -enum elect_t -{ - ELECT_NONE, - ELECT_MATCH, - ELECT_ADMIN, - ELECT_MAP -}; - -struct ctfgame_t -{ - int team1, team2; - int total1, total2; // these are only set when going into intermission except in teamplay - gtime_t last_flag_capture; - int last_capture_team; - - match_t match; // match state - gtime_t matchtime; // time for match start/end (depends on state) - int lasttime; // last time update, explicitly truncated to seconds - bool countdown; // has audio countdown started? - - elect_t election; // election type - edict_t *etarget; // for admin election, who's being elected - char elevel[32]; // for map election, target level - int evotes; // votes so far - int needvotes; // votes needed - gtime_t electtime; // remaining time until election times out - char emsg[256]; // election name - int warnactive; // true if stat string 30 is active - - ghost_t ghosts[MAX_CLIENTS]; // ghost codes -}; - ctfgame_t ctfgame; cvar_t *ctf; cvar_t *teamplay; cvar_t *g_teamplay_force_join; +cvar_t *ctf_mode = NULL; +cvar_t *ctf_dropflag = NULL; +cvar_t *ctf_respawn = NULL; +cvar_t *ctf_model = NULL; // [Paril-KEX] bool G_TeamplayEnabled() diff --git a/actionlite/ctf/g_ctf.h b/actionlite/ctf/g_ctf.h index 9be1825..c59bbd9 100644 --- a/actionlite/ctf/g_ctf.h +++ b/actionlite/ctf/g_ctf.h @@ -38,6 +38,50 @@ struct ghost_t edict_t *ent; }; +enum match_t +{ + MATCH_NONE, + MATCH_SETUP, + MATCH_PREGAME, + MATCH_GAME, + MATCH_POST +}; + +enum elect_t +{ + ELECT_NONE, + ELECT_MATCH, + ELECT_ADMIN, + ELECT_MAP +}; + +struct ctfgame_t +{ + int team1, team2; + int total1, total2; // these are only set when going into intermission except in teamplay + gtime_t last_flag_capture; + int last_capture_team; + + match_t match; // match state + gtime_t matchtime; // time for match start/end (depends on state) + int lasttime; // last time update, explicitly truncated to seconds + bool countdown; // has audio countdown started? + + elect_t election; // election type + edict_t *etarget; // for admin election, who's being elected + char elevel[32]; // for map election, target level + int evotes; // votes so far + int needvotes; // votes needed + gtime_t electtime; // remaining time until election times out + char emsg[256]; // election name + int warnactive; // true if stat string 30 is active + + ghost_t ghosts[MAX_CLIENTS]; // ghost codes + + // Action + int32_t halftime; +}; + extern cvar_t *ctf; extern cvar_t *g_teamplay_force_join; extern cvar_t *teamplay; diff --git a/actionlite/g_cmds.cpp b/actionlite/g_cmds.cpp index 7aeccbf..15aaf2c 100644 --- a/actionlite/g_cmds.cpp +++ b/actionlite/g_cmds.cpp @@ -120,6 +120,91 @@ void LaserSightThink(edict_t * self) self->nextthink = level.time + 1_ms; } + +// sets variable to toggle nearby door status +void Cmd_OpenDoor_f(edict_t * ent) +{ + ent->client->doortoggle = 1; + return; +} + +void Cmd_Bandage_f(edict_t *ent) +{ + if (!IS_ALIVE(ent)) + return; + + if (ent->client->bandaging) { + gi.LocClient_Print(ent, PRINT_HIGH, "Already bandaging\n"); + return; + } + + bool can_use_medkit = (ent->client->medkit > 0) && (ent->health < ent->max_health); + + // No need to bandage if enhanced slippers are enabled and you only have fall damage + // but you can still use the medkit to regain health + if (ent->client->bleeding == 0 && e_enhancedSlippers->value && ! can_use_medkit){ + gi.LocClient_Print(ent, PRINT_HIGH, "No need to bandage\n"); + return; + } + + if (ent->client->bleeding == 0 && ent->client->leg_damage == 0 && ! can_use_medkit) { + gi.LocClient_Print(ent, PRINT_HIGH, "No need to bandage\n"); + return; + } + + ent->client->reload_attempts = 0; // prevent any further reloading + + if (ent->client->weaponstate != WEAPON_READY && ent->client->weaponstate != WEAPON_END_MAG) { + gi.LocClient_Print(ent, PRINT_HIGH, "Can't bandage now\n"); + return; + } + + // zucc - check if they have a primed grenade + if (ent->client->pers.weapon->id == IT_WEAPON_GRENADES + && ((ent->client->ps.gunframe >= GRENADE_IDLE_FIRST + && ent->client->ps.gunframe <= GRENADE_IDLE_LAST) + || (ent->client->ps.gunframe >= GRENADE_THROW_FIRST + && ent->client->ps.gunframe <= GRENADE_THROW_LAST))) + { + int damage; + + ent->client->ps.gunframe = 0; + + damage = GRENADE_DAMRAD; + + fire_grenade2(ent, ent->s.origin, vec3_origin, damage, 0, 80_ms, damage * 2, false); + + INV_AMMO(ent, IT_WEAPON_GRENADES)--; + if (INV_AMMO(ent, IT_WEAPON_GRENADES) <= 0) { + ent->client->newweapon = GetItemByIndex(IT_WEAPON_MK23); + } + } + + ent->client->bandaging = 1; + ent->client->resp.sniper_mode = SNIPER_1X; + ent->client->ps.fov = 90; + ent->client->desired_fov = 90; + if (ent->client->pers.weapon) + ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model); + gi.LocClient_Print(ent, PRINT_HIGH, "You've started bandaging\n"); +} + +// function called in generic_weapon function that does the bandaging + +void Bandage(edict_t * ent) +{ + ClientFixLegs(ent); + ent->client->bleeding = 0; + ent->client->bleed_remain = 0; + ent->client->bandaging = 0; + ent->client->attacker = NULL; + ent->client->bandage_stopped = 1; + if (esp->value && esp_leaderenhance->value) + ent->client->idle_weapon = ENHANCED_BANDAGE_TIME; + else + ent->client->idle_weapon = BANDAGE_TIME; +} + void Cmd_New_Reload_f(edict_t * ent) { //FB 6/1/99 - refuse to reload during LCA diff --git a/actionlite/g_local.h b/actionlite/g_local.h index d79d346..860b180 100644 --- a/actionlite/g_local.h +++ b/actionlite/g_local.h @@ -6,9 +6,16 @@ #include "bg_local.h" -#include "a_team.h" -#include "a_game.h" -#include "cgf_sfx_glass.h" +// Action includes +#include "action/a_team.h" +#include "action/a_game.h" +#include "action/cgf_sfx_glass.h" +#include "action/a_match.h" +#include "action/a_radio.h" +#include "action/a_ini.h" +#include "action/a_stats.h" +#include "action/a_balancer.h" + // the "gameversion" client command will print this plus compile date constexpr const char *GAMEVERSION = "action"; @@ -1995,6 +2002,8 @@ extern cvar_t *radio_ban; extern cvar_t *radio_repeat; //SLIC2 extern cvar_t *radio_repeat_time; +extern cvar_t *warmup; +extern cvar_t *round_begin; void LaserSightThink (edict_t * self); void SP_LaserSight (edict_t * self, gitem_t * item); @@ -2961,6 +2970,7 @@ struct client_respawn_t gtime_t ctf_lastreturnedflag; gtime_t ctf_flagsince; gtime_t ctf_lastfraggedcarrier; + int32_t ctf_caps; int32_t ctf_capstreak; bool id_state; gtime_t lastidtime; @@ -2971,12 +2981,17 @@ struct client_respawn_t // ZOID // Action Add + int32_t joined_team; // last frame # at which the player joined a team + int32_t lastWave; //last time used wave + + radio_t radio; + + int32_t motd_refreshes; + int32_t last_motd_refresh; + edict_t *last_chase_target; // last person they chased, to resume at the same place later... int32_t enterframe; // frame when player entered the game int32_t team_kills; - int32_t team_wounds; - int32_t joined_team; // last frame # at which the player joined a team - int32_t lastWave; //last time used wave - + int32_t team_wounds; int32_t team; int32_t subteam; int32_t sniper_mode; @@ -3041,7 +3056,15 @@ struct team_t }; extern team_t teams[TEAM_TOP]; -// Action Add +#ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +// Action Add End // [Paril-KEX] seconds until we are fully invisible after // making a racket diff --git a/actionlite/g_main.cpp b/actionlite/g_main.cpp index ecc256a..7da5a0b 100644 --- a/actionlite/g_main.cpp +++ b/actionlite/g_main.cpp @@ -170,6 +170,8 @@ cvar_t *respawn_effect; cvar_t *use_warnings; cvar_t *use_killcounts; cvar_t *use_rewards; +cvar_t *warmup; +cvar_t *round_begin; // UI / Menu / Messaging Settings cvar_t *motd_time; diff --git a/actionlite/g_spawn.cpp b/actionlite/g_spawn.cpp index b2f0d79..5fd4bba 100644 --- a/actionlite/g_spawn.cpp +++ b/actionlite/g_spawn.cpp @@ -1323,9 +1323,9 @@ static void G_InitStatusbar() .yb(-84) .endifstat() .endifstat(); - sb.ifstat(STAT_KEY_A).xv(296).pic(STAT_KEY_A).endifstat(); - sb.ifstat(STAT_KEY_B).xv(272).pic(STAT_KEY_B).endifstat(); - sb.ifstat(STAT_KEY_C).xv(248).pic(STAT_KEY_C).endifstat(); + // sb.ifstat(STAT_KEY_A).xv(296).pic(STAT_KEY_A).endifstat(); + // sb.ifstat(STAT_KEY_B).xv(272).pic(STAT_KEY_B).endifstat(); + // sb.ifstat(STAT_KEY_C).xv(248).pic(STAT_KEY_C).endifstat(); if (coop->integer) { diff --git a/actionlite/p_hud.cpp b/actionlite/p_hud.cpp index d8d7ad1..a29f3e5 100644 --- a/actionlite/p_hud.cpp +++ b/actionlite/p_hud.cpp @@ -973,11 +973,11 @@ void G_SetStats(edict_t *ent) if (!deathmatch->integer) { int32_t key_offset = 0; - player_stat_t stat = STAT_KEY_A; + // player_stat_t stat = STAT_KEY_A; - ent->client->ps.stats[STAT_KEY_A] = - ent->client->ps.stats[STAT_KEY_B] = - ent->client->ps.stats[STAT_KEY_C] = 0; + // ent->client->ps.stats[STAT_KEY_A] = + // ent->client->ps.stats[STAT_KEY_B] = + // ent->client->ps.stats[STAT_KEY_C] = 0; // there's probably a way to do this in one pass but // I'm lazy