Save point

This commit is contained in:
Aaron Dean 2023-09-05 17:18:39 -04:00
parent c139980419
commit 1eea4c8a4c
10 changed files with 412 additions and 333 deletions

View file

@ -10,7 +10,6 @@ set(GAME_SRC
${CMAKE_CURRENT_SOURCE_DIR}/action/a_game.cpp
${CMAKE_CURRENT_SOURCE_DIR}/action/a_team.cpp
${CMAKE_CURRENT_SOURCE_DIR}/action/a_balancer.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

View file

@ -161,12 +161,15 @@ void PrintMOTD(edict_t * ent)
*/
//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_strlcat(msg_buf, hostname->string, strlen(msg_buf)+40);
strcat(msg_buf, "\n");
lines++;
}
// TODO: When hostnames become a thing, re-enable this
//if (hostname->string[0] && strcmp(hostname->string, "Unnamed TNG Server"))
const char *hostname = "An Action Server";
Q_strlcat(msg_buf, hostname, strlen(msg_buf)+40);
strcat(msg_buf, "\n");
lines++;
/*
Now all the settings
@ -716,21 +719,20 @@ void PlaceHolder( edict_t * ent ); // p_weapon.c
FindEdictByClassnum
==================
*/
edict_t *FindEdictByClassnum(char *classname, int classnum)
{
int i;
edict_t *it;
// 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) && (strcmp(it->classname, classname) == 0))
// return 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;
return NULL;
}
// }
// /********* Bulletholes/wall stuff ***********/
@ -801,10 +803,10 @@ edict_t *FindEdictByClassnum(char *classname, int classnum)
// 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) ));
// || (strcmp( ent->classname, "func_plat" ) == 0)
// || (strcmp( ent->classname, "func_rotating" ) == 0)
// || (strcmp( ent->classname, "func_train" ) == 0)
// || (strcmp( ent->classname, "func_button" ) == 0) ));
// }
// void AddDecal(edict_t * self, trace_t * tr)
@ -849,7 +851,7 @@ edict_t *FindEdictByClassnum(char *classname, int classnum)
// decal->classname = "decal";
// decal->classnum = decals;
// if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname))) {
// if ((tr->ent) && (0 == strcmp("func_explosive", tr->ent->classname))) {
// CGF_SFX_AttachDecalToGlass(tr->ent, decal);
// }
// else if( attached )
@ -910,7 +912,7 @@ edict_t *FindEdictByClassnum(char *classname, int classnum)
// splat->classname = "splat";
// splat->classnum = splats;
// if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname))) {
// if ((tr->ent) && (0 == strcmp("func_explosive", tr->ent->classname))) {
// CGF_SFX_AttachDecalToGlass(tr->ent, splat);
// }
// else if( attached )
@ -940,7 +942,7 @@ void GetItemName( edict_t *ent, char *buf )
{
for( i = 0; i < ITEM_COUNT; i ++ )
{
itemNum = ITEM_FIRST + i;
itemNum = IT_ITEM_QUIET;
if( INV_AMMO( ent, itemNum ) )
{
strcpy( buf, GET_ITEM(itemNum)->pickup_name );

View file

@ -1,7 +1,5 @@
#include "../g_local.h"
#include "cgf_sfx_glass.h"
#include "../ctf/g_ctf.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?
@ -37,7 +35,7 @@ edict_t *NS_used_farteamplay_spawns[MAX_TEAMS][MAX_SPAWNS];
int NS_randteam;
// </TNG:Freud>
void CreditsMenu (edict_t * ent, pmenu_t * p);
void CreditsMenu (edict_t * ent, pmenuhnd_t * p);
static transparent_list_t transparentList[MAX_CLIENTS];
static size_t transparentEntryCount = 0;
transparent_list_t *transparent_list = NULL;
@ -114,7 +112,7 @@ bool OnTransparentList( const edict_t *ent )
return false;
}
void ReprintMOTD (edict_t * ent, pmenu_t * p)
void ReprintMOTD (edict_t * ent, pmenuhnd_t * p)
{
PMenu_Close (ent);
PrintMOTD (ent);
@ -139,7 +137,7 @@ void PrintMatchRules ()
CenterPrintAll(rulesmsg);
}
void JoinTeamAuto (edict_t * ent, pmenu_t * p)
void JoinTeamAuto (edict_t * ent, pmenuhnd_t * p)
{
int i, team = TEAM1, num1 = 0, num2 = 0, num3 = 0, score1, score2, score3;
@ -356,7 +354,7 @@ void QuakeNigguhz (edict_t * ent, pmenuhnd_t * p)
}
// AQ2:TNG Deathwatch - Editing all menus to show the correct credits, version, names, locations, urls, etc
pmenu_t creditsmenu[] = {
const 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},
@ -386,26 +384,54 @@ pmenu_t creditsmenu[] = {
//PG BUND END
};
pmenu_t weapmenu[] = {
{"*" 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},
{"Select your Weapon", PMENU_ALIGN_CENTER, NULL},
{NULL, PMENU_ALIGN_LEFT, NULL},
// const pmenu_t weapmenu[] = {
// {"*" 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},
// {"Select your Weapon", PMENU_ALIGN_CENTER, NULL},
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG - Igor adding wp_flags
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "MP5/10 Submachinegun", SelectWeapon2
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "M3 Super90 Assault Shotgun", SelectWeapon3
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Handcannon", SelectWeapon4
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "SSG 3000 Sniper Rifle", SelectWeapon5
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "M4 Assault Rifle", SelectWeapon6
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Combat Knives", SelectWeapon0
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Akimbo Pistols", SelectWeapon9
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG End adding wp_flags
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG - Slicer: changing this
// //{"Leave Team", PMENU_ALIGN_LEFT, NULL, LeaveTeams},
// {"Return to Main Menu", PMENU_ALIGN_LEFT, CreditsReturnToMain},
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG END
// {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL},
// {"ENTER to select", PMENU_ALIGN_LEFT, NULL},
// {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL},
// {NULL, PMENU_ALIGN_LEFT, NULL},
// {"v" VERSION, PMENU_ALIGN_RIGHT, NULL},
// };
const pmenu_t weapmenu[] = {
{"*" TNG_TITLE, PMENU_ALIGN_CENTER, nullptr},
{"\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, nullptr},
{"Select your Weapon", PMENU_ALIGN_CENTER, nullptr},
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG - Igor adding wp_flags
{NULL, PMENU_ALIGN_LEFT, NULL}, // "MP5/10 Submachinegun", SelectWeapon2
{NULL, PMENU_ALIGN_LEFT, NULL}, // "M3 Super90 Assault Shotgun", SelectWeapon3
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Handcannon", SelectWeapon4
{NULL, PMENU_ALIGN_LEFT, NULL}, // "SSG 3000 Sniper Rifle", SelectWeapon5
{NULL, PMENU_ALIGN_LEFT, NULL}, // "M4 Assault Rifle", SelectWeapon6
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Combat Knives", SelectWeapon0
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Akimbo Pistols", SelectWeapon9
{NULL, PMENU_ALIGN_LEFT, NULL},
{MP5_NAME, PMENU_ALIGN_LEFT, SelectWeapon2}, // "MP5/10 Submachinegun", SelectWeapon2
{M3_NAME, PMENU_ALIGN_LEFT, SelectWeapon3}, // "M3 Super90 Assault Shotgun", SelectWeapon3
{HC_NAME, PMENU_ALIGN_LEFT, SelectWeapon4}, // "Handcannon", SelectWeapon4
{SNIPER_NAME, PMENU_ALIGN_LEFT, SelectWeapon5}, // "SSG 3000 Sniper Rifle", SelectWeapon5
{M4_NAME, PMENU_ALIGN_LEFT, SelectWeapon6}, // "M4 Assault Rifle", SelectWeapon6
{KNIFE_NAME, PMENU_ALIGN_LEFT, SelectWeapon0}, // "Combat Knives", SelectWeapon0
{DUAL_NAME, PMENU_ALIGN_LEFT, SelectWeapon9}, // "Akimbo Pistols", SelectWeapon9
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG End adding wp_flags
{NULL, PMENU_ALIGN_LEFT, NULL},
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG - Slicer: changing this
//{"Leave Team", PMENU_ALIGN_LEFT, NULL, LeaveTeams},
//{"Leave Team", PMENU_ALIGN_LEFT, nullptr, LeaveTeams},
{"Return to Main Menu", PMENU_ALIGN_LEFT, CreditsReturnToMain},
{NULL, PMENU_ALIGN_LEFT, NULL},
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG END
{"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL},
{"ENTER to select", PMENU_ALIGN_LEFT, NULL},
@ -414,69 +440,90 @@ pmenu_t weapmenu[] = {
{"v" VERSION, PMENU_ALIGN_RIGHT, NULL},
};
pmenu_t itemmenu[] = {
{"*" 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},
{"Select your Item", PMENU_ALIGN_CENTER, NULL},
{NULL, PMENU_ALIGN_LEFT, NULL},
//AQ2:TNG Igor adding itm_flags
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Kevlar Vest", SelectItem1
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Laser Sight", SelectItem2
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Stealth Slippers", SelectItem3
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Silencer", SelectItem4
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Bandolier", SelectItem5
{NULL, PMENU_ALIGN_LEFT, NULL}, // "Kevlar Helmet", SelectItem6
{NULL, PMENU_ALIGN_LEFT, NULL},
//AQ2:TNG end adding itm_flags
{NULL, PMENU_ALIGN_LEFT, NULL},
{"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL},
{"ENTER to select", PMENU_ALIGN_LEFT, NULL},
{"TAB to exit menu", PMENU_ALIGN_LEFT, NULL},
{NULL, PMENU_ALIGN_LEFT, NULL},
{"v" VERSION, PMENU_ALIGN_RIGHT, NULL},
};
// pmenu_t itemmenu[] = {
// {"*" 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},
// {"Select your Item", PMENU_ALIGN_CENTER, NULL},
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG Igor adding itm_flags
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Kevlar Vest", SelectItem1
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Laser Sight", SelectItem2
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Stealth Slippers", SelectItem3
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Silencer", SelectItem4
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Bandolier", SelectItem5
// {NULL, PMENU_ALIGN_LEFT, NULL}, // "Kevlar Helmet", SelectItem6
// {NULL, PMENU_ALIGN_LEFT, NULL},
// //AQ2:TNG end adding itm_flags
// {NULL, PMENU_ALIGN_LEFT, NULL},
// {"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL},
// {"ENTER to select", PMENU_ALIGN_LEFT, NULL},
// {"TAB to exit menu", PMENU_ALIGN_LEFT, NULL},
// {NULL, PMENU_ALIGN_LEFT, NULL},
// {"v" VERSION, PMENU_ALIGN_RIGHT, NULL},
// };
const pmenu_t itemmenu[] = {
{"*" TNG_TITLE, PMENU_ALIGN_CENTER, nullptr},
{"\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, nullptr},
{"Select your Item", PMENU_ALIGN_CENTER, nullptr},
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG Igor adding itm_flags
{KEV_NAME, PMENU_ALIGN_LEFT, SelectItem1}, // "Kevlar Vest", SelectItem1
{LASER_NAME, PMENU_ALIGN_LEFT, SelectItem2}, // "Laser Sight", SelectItem2
{SLIP_NAME, PMENU_ALIGN_LEFT, SelectItem3}, // "Stealth Slippers", SelectItem3
{SIL_NAME, PMENU_ALIGN_LEFT, SelectItem4}, // "Silencer", SelectItem4
{BAND_NAME, PMENU_ALIGN_LEFT, SelectItem5}, // "Bandolier", SelectItem5
{HELM_NAME, PMENU_ALIGN_LEFT, SelectItem6}, // "Kevlar Helmet", SelectItem6
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG end adding itm_flags
{"", PMENU_ALIGN_LEFT, nullptr},
{"Use arrows to move cursor", PMENU_ALIGN_LEFT, nullptr},
{"ENTER to select", PMENU_ALIGN_LEFT, nullptr},
{"TAB to exit menu", PMENU_ALIGN_LEFT, nullptr},
{"", PMENU_ALIGN_LEFT, nullptr},
{"v" VERSION, PMENU_ALIGN_RIGHT, nullptr},
};
//AQ2:TNG - slicer
void VotingMenu (edict_t * ent, pmenu_t * p)
void VotingMenu (edict_t * ent, pmenuhnd_t * p)
{
PMenu_Close (ent);
//vShowMenu (ent, "");
}
//AQ2:TNG END
pmenu_t joinmenu[] = {
{"*" 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},
{NULL /* lvl name */ , PMENU_ALIGN_CENTER, NULL},
{NULL, PMENU_ALIGN_CENTER, NULL},
{NULL /* team 1 */ , PMENU_ALIGN_LEFT, JoinTeam1},
{NULL, PMENU_ALIGN_LEFT, NULL},
{NULL /* team 2 */ , PMENU_ALIGN_LEFT, JoinTeam2},
{NULL, PMENU_ALIGN_LEFT, NULL},
{NULL /* team 3 */ , PMENU_ALIGN_LEFT, JoinTeam3},
{NULL, PMENU_ALIGN_LEFT, NULL},
{NULL, PMENU_ALIGN_LEFT, NULL},
{NULL /* auto-join */ , PMENU_ALIGN_LEFT, JoinTeamAuto},
{NULL, PMENU_ALIGN_LEFT, NULL},
const pmenu_t joinmenu[] = {
{"*" TNG_TITLE, PMENU_ALIGN_CENTER, nullptr},
{"\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, nullptr},
{"" /* lvl name */ , PMENU_ALIGN_CENTER, nullptr},
{"", PMENU_ALIGN_CENTER, nullptr},
{"" /* team 1 */ , PMENU_ALIGN_LEFT, JoinTeam1},
{"", PMENU_ALIGN_LEFT, nullptr},
{"" /* team 2 */ , PMENU_ALIGN_LEFT, JoinTeam2},
{"", PMENU_ALIGN_LEFT, nullptr},
{"" /* team 3 */ , PMENU_ALIGN_LEFT, JoinTeam3},
{"", PMENU_ALIGN_LEFT, nullptr},
{"", PMENU_ALIGN_LEFT, nullptr},
{"" /* auto-join */ , PMENU_ALIGN_LEFT, JoinTeamAuto},
{"", PMENU_ALIGN_LEFT, nullptr},
//AQ2:TNG - Slicer
{"Voting & Ignoring Menus", PMENU_ALIGN_LEFT, VotingMenu},
//AQ2:TNG END
{"MOTD", PMENU_ALIGN_LEFT, ReprintMOTD},
{"Credits", PMENU_ALIGN_LEFT, CreditsMenu},
{NULL, PMENU_ALIGN_LEFT, NULL},
{"Use arrows to move cursor", PMENU_ALIGN_LEFT, NULL},
{"ENTER to select", PMENU_ALIGN_LEFT, NULL},
{"TAB to exit menu", PMENU_ALIGN_LEFT, NULL},
{NULL, PMENU_ALIGN_LEFT, NULL},
{"v" VERSION, PMENU_ALIGN_RIGHT, NULL},
{"", PMENU_ALIGN_LEFT, nullptr},
{"Use arrows to move cursor", PMENU_ALIGN_LEFT, nullptr},
{"ENTER to select", PMENU_ALIGN_LEFT, nullptr},
{"TAB to exit menu", PMENU_ALIGN_LEFT, nullptr},
{"", PMENU_ALIGN_LEFT, nullptr},
{"v" VERSION, PMENU_ALIGN_RIGHT, nullptr},
};
// AQ2:TNG End
void CreditsMenu (edict_t * ent, pmenu_t * p)
void CreditsMenu (edict_t * ent, pmenuhnd_t * p)
{
PMenu_Close (ent);
PMenu_Open (ent, creditsmenu, 4, sizeof (creditsmenu) / sizeof (pmenu_t));
gi.sound(ent, gi.soundindex("world/elv.wav"), 1, ATTN_NORM, 1.0);
PMenu_Open (ent, creditsmenu, 4, sizeof (creditsmenu) / sizeof (pmenu_t), nullptr, nullptr);
gi.sound(ent, CHAN_VOICE, gi.soundindex("world/elv.wav"), 1, ATTN_NORM, 1.0);
}
void killPlayer( edict_t *ent, bool suicidePunish )
@ -609,8 +656,7 @@ void Team_f (edict_t * ent)
return;
}
if( (ent->client->resp.joined_team > 0) && (level.realFramenum - ent->client->resp.joined_team < 5 * HZ) )
if( (ent->client->resp.joined_team > 0) && (gtime_t::from_sec(ent->client->resp.joined_team)) )
{
gi.LocClient_Print(ent, PRINT_HIGH, "You must wait 5 seconds before changing teams again.\n");
return;
@ -749,19 +795,28 @@ typedef struct menuentry_s
void (*SelectFunc) (edict_t * ent, struct pmenu_s * entry);
} menuentry_t;
static void CTFNoChaseCamUpdate(edict_t *ent)
{
pmenu_t *entries = ent->client->menu->entries;
}
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;
PMenu_Close(ent);
PMenu_Open(ent, itemmenu, -1, sizeof(itemmenu) / sizeof(pmenu_t), nullptr, nullptr);
// 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] );
// count = sizeof( menu_items ) / sizeof( menu_items[0] );
// if ((int)itm_flags->value & ITF_MASK)
// {
@ -787,23 +842,26 @@ void OpenItemMenu (edict_t * ent)
// }
// }
PMenu_Close(ent);
//PMenu_Close(ent);
}
void OpenWeaponMenu (edict_t * ent)
{
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;
PMenu_Close(ent);
PMenu_Open(ent, weapmenu, -1, sizeof(weapmenu) / sizeof(pmenu_t), nullptr, nullptr);
// 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] );
// count = sizeof( menu_items ) / sizeof( menu_items[0] );
// TODO Weapon bans
// if ((int)wp_flags->value & WPF_MASK)
@ -831,102 +889,102 @@ void OpenWeaponMenu (edict_t * ent)
// }
// }
OpenItemMenu(ent);
//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;
// 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 (g_teamplay_force_join->string && *g_teamplay_force_join->string)
{
if (strcmp (g_teamplay_force_join->string, "red") == 0)
{
joinmenu[6].text = NULL;
joinmenu[6].SelectFunc = NULL;
}
else if (strcmp (g_teamplay_force_join->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;
// 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 (g_teamplay_force_join->string && *g_teamplay_force_join->string)
// {
// if (strcmp (g_teamplay_force_join->string, "red") == 0)
// {
// joinmenu[6].text = NULL;
// joinmenu[6].SelectFunc = NULL;
// }
// else if (strcmp (g_teamplay_force_join->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_strlcpy(levelname + 1, g_edicts[0].message, sizeof(levelname) - 1);
else
Q_strlcpy(levelname + 1, level.mapname, sizeof(levelname) - 1);
// levelname[0] = '*';
// if (g_edicts[0].message)
// Q_strlcpy(levelname + 1, g_edicts[0].message, sizeof(levelname) - 1);
// else
// Q_strlcpy(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++;
}
// 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);
// 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;
}
// 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();
//UpdateJoinMenu();
PMenu_Open (ent, joinmenu, 11 /* magic for Auto-join menu item */, sizeof (joinmenu) / sizeof (pmenu_t), nullptr, nullptr);
}
@ -991,7 +1049,8 @@ void CleanLevel ()
CleanBodies();
// fix glass
CGF_SFX_RebuildAllBrokenGlass ();
// Review this later
//CGF_SFX_RebuildAllBrokenGlass ();
}
void MakeAllLivePlayersObservers(void);
@ -2128,7 +2187,8 @@ void A_ScoreboardMessage (edict_t * ent, edict_t * killer)
else
totalClients = G_SortedClients(sortedClients);
ent->client->ps.stats[STAT_TEAM_HEADER] = level.pic_teamtag;
// TODO: Fix this
ent->client->ps.stats[STAT_TEAM1_HEADER] = level.pic_teamtag;
for (i = 0; i < totalClients; i++) {
cl = sortedClients[i];
@ -2311,7 +2371,7 @@ void A_ScoreboardMessage (edict_t * ent, edict_t * killer)
playername,
cl->resp.score,
(level.time - cl->resp.entertime).minutes());
min(cl->ping, 999) );
min(cl->ping, 999);
} else {
sprintf( string + len,
"yv %i string%s \"%s\" ",

View file

@ -70,7 +70,7 @@ extern "C"
void CGF_SFX_BreakGlass (edict_t * aGlassPane, edict_t * anOther,
edict_t * anAttacker, int aDamage, vec3_t aPoint,
vec_t aPaneDestructDelay);
vec3_t aPaneDestructDelay);
// breaks glass
void CGF_SFX_InstallBreakableGlass (edict_t * aGlassPane);
@ -117,8 +117,8 @@ extern "C"
void
CGF_SFX_InstallGlassSupport ()
{
breakableglass = gi.cvar ("breakableglass", "0", 0);
glassfragmentlimit = gi.cvar ("glassfragmentlimit", "30", 0);
breakableglass = gi.cvar ("breakableglass", "0", CVAR_NOFLAGS);
glassfragmentlimit = gi.cvar ("glassfragmentlimit", "30", CVAR_NOFLAGS);
}
@ -422,7 +422,7 @@ CGF_SFX_TouchGlass (edict_t * self, edict_t * other, cplane_t * plane,
// break glass
CGF_SFX_BreakGlass (glass, other, other, glass->health, vec3_origin,
3.0f * FRAMETIME);
3.0f * 10);
// glass can take care of itself, but the trigger isn't needed anymore
G_FreeEdict (self);
@ -435,7 +435,7 @@ CGF_SFX_TouchGlass (edict_t * self, edict_t * other, cplane_t * plane,
*/
// make sure client takes damage
T_Damage (other, glass, other, normal, other->s.origin, normal, 15.0, 0, 0,
T_Damage (other, glass, other, normal, other->s.origin, normal, 15.0, 0, DAMAGE_NONE,
MOD_BREAKINGGLASS);
return;
@ -453,7 +453,7 @@ knife_and_grenade_handling:
void
CGF_SFX_BreakGlass (edict_t * aGlassPane, edict_t * anInflictor,
edict_t * anAttacker, int aDamage, vec3_t aPoint,
vec_t aPaneDestructDelay)
vec3_t aPaneDestructDelay)
{
// based on func_explode, but with lotsa subtle differences
vec3_t origin;
@ -537,7 +537,7 @@ CGF_SFX_BreakGlass (edict_t * aGlassPane, edict_t * anInflictor,
// meanwhile, make sure the player can move thru
aGlassPane->solid = SOLID_NOT;
aGlassPane->think = CGF_SFX_HideBreakableGlass;
aGlassPane->nextthink = level.framenum + aPaneDestructDelay * HZ;
aGlassPane->nextthink = level.time + 100_ms;
}
@ -592,23 +592,23 @@ CGF_SFX_HideBreakableGlass (edict_t * aGlassPane)
// remove all attached decals
edict_t *decal;
decal = 0;
while ((decal = G_Find (decal, FOFS (classname), "decal")) != NULL)
while ((decal = G_FindByString<&edict_t::classname>(nullptr, "decal")) != NULL)
{
if (decal->owner == aGlassPane)
{
// make it goaway in the next frame
decal->think = G_FreeEdict;
decal->nextthink = level.framenum + 1;
decal->nextthink = level.time + 40_ms;
}
}
while ((decal = G_Find (decal, FOFS (classname), "splat")) != NULL)
while ((decal = G_FindByString<&edict_t::classname>(nullptr, "splat")) != NULL)
{
if (decal->owner == aGlassPane)
{
// make it goaway in the next frame
decal->think = G_FreeEdict;
decal->nextthink = level.framenum + 1;
decal->nextthink = level.time + 40_ms;
}
}
@ -636,7 +636,7 @@ CGF_SFX_RebuildAllBrokenGlass ()
// iterate over all func_explosives
edict_t *glass;
glass = 0;
while ((glass = G_Find (glass, FOFS (classname), "func_explosive")) != NULL)
while ((glass = G_FindByString<&edict_t::classname>(nullptr, "func_explosive")) != NULL)
{
// glass is broken if solid != SOLID_BSP
if (glass->solid != SOLID_BSP)
@ -692,7 +692,7 @@ CGF_SFX_MiscGlassDie (edict_t * self, edict_t * inflictor, edict_t * attacker,
static vec_t previous_throw_time = 0;
static vec3_t previous_throw_time = 0;
static int this_throw_count = 0;
void
@ -728,9 +728,9 @@ CGF_SFX_GlassThrowDebris (edict_t * self, char *modelname, float speed,
chunk->avelocity[1] = random () * 600;
chunk->avelocity[2] = random () * 600;
chunk->think = G_FreeEdict;
chunk->nextthink = level.framenum + (5 + random() * 5) * HZ;
chunk->nextthink = level.time + FRAME_TIME_S;
chunk->s.frame = 0;
chunk->flags = 0;
chunk->flags = FL_NONE;
chunk->classname = "debris";
chunk->takedamage = DAMAGE_YES;
chunk->die = debris_die;

View file

@ -34,7 +34,8 @@
// defines (should be consistent with other weapon defs in g_local.h)
#define MOD_BREAKINGGLASS 46
// Moved to mod_id_t enum
//#define MOD_BREAKINGGLASS 46
/*
// forward definitions

View file

@ -207,19 +207,21 @@ enum player_stat_t
// 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,
STAT_TEAM1_HEADER = 26,
STAT_TEAM2_HEADER = 27,
STAT_TEAM3_HEADER = 28,
STAT_CTF_TEAM1_CAPS = 29,
STAT_CTF_TEAM2_CAPS = 30,
STAT_CTF_TECH = 31,
STAT_CTF_ID_VIEW = 32,
STAT_CTF_MATCH = 33,
STAT_CTF_ID_VIEW_COLOR = 34,
STAT_CTF_TEAMINFO = 35,
// [Kex] More stats for weapon wheel
STAT_WEAPONS_OWNED_1 = 34,
STAT_WEAPONS_OWNED_2 = 35,
STAT_AMMO_INFO_START = 36,
STAT_WEAPONS_OWNED_1 = 36,
STAT_WEAPONS_OWNED_2 = 37,
STAT_AMMO_INFO_START = 38,
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,

View file

@ -199,10 +199,7 @@ void Bandage(edict_t * ent)
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;
ent->client->idle_weapon = BANDAGE_TIME;
}
void Cmd_New_Reload_f(edict_t * ent)

View file

@ -632,6 +632,13 @@ constexpr size_t BODY_QUEUE_SIZE = 8;
// null trace used when touches don't need a trace
constexpr trace_t null_trace {};
enum damage_t
{
DAMAGE_NO,
DAMAGE_YES, // will take damage if hit
DAMAGE_AIM // auto targeting recognizes this
};
enum weaponstate_t
{
WEAPON_READY,
@ -659,6 +666,96 @@ enum gib_type_t
};
MAKE_ENUM_BITFLAGS(gib_type_t);
// Action Add
enum layout_t{
LAYOUT_NONE,
LAYOUT_SCORES,
LAYOUT_SCORES2,
LAYOUT_MENU
};
enum action_sniper_modes_t
{
SNIPER_1X,
SNIPER_2X,
SNIPER_4X,
SNIPER_6X,
SNIPER_MODE_MAX
};
enum action_weapon_num_t
{
NO_WEAP_NUM,
MK23_NUM,
MP5_NUM,
M4_NUM,
M3_NUM,
HC_NUM,
SNIPER_NUM,
DUAL_NUM,
KNIFE_NUM,
GRENADE_NUM,
WEAPON_MAX
};
enum action_item_num_t
{
NO_ITEM_NUM,
SIL_NUM,
SLIP_NUM,
BAND_NUM,
KEV_NUM,
LASER_NUM,
HELM_NUM,
ITEM_MAX
};
enum action_ammo_num_t
{
NO_AMMO_NUM,
MK23_ANUM,
MP5_ANUM,
M4_ANUM,
SHELL_ANUM,
SNIPER_ANUM,
AMMO_MAX_ANUM
};
constexpr int32_t weap_ids[] = {
MP5_NUM,
M4_NUM,
M3_NUM,
HC_NUM,
SNIPER_NUM
};
enum damage_loc_t {
LOC_HDAM, // head
LOC_CDAM, // chest
LOC_SDAM, // stomach
LOC_LDAM, // legs
LOC_KVLR_HELMET, // kevlar helmet Freud, for %D
LOC_KVLR_VEST, // kevlar vest Freud, for %D
LOC_NO, // Shot by shotgun or handcannon
LOC_MAX // must be last
};
enum award_t {
ACCURACY,
IMPRESSIVE,
EXCELLENT
};
enum gender_t {
GENDER_MALE,
GENDER_FEMALE,
GENDER_NEUTRAL
};
#define GENDER_STR( ent, he, she, it ) (((ent)->client->pers.gender == GENDER_MALE) ? he : (((ent)->client->pers.gender == GENDER_FEMALE) ? she : it))
// Action add end
// monster ai flags
enum monster_ai_flags_t : uint64_t
{
@ -997,7 +1094,8 @@ enum mod_id_t : uint8_t
MOD_KICK,
MOD_GRAPPLE,
MOD_TOTAL,
MOD_FRIENDLY_FIRE
MOD_FRIENDLY_FIRE,
MOD_BREAKINGGLASS
};
struct mod_t
@ -1689,6 +1787,7 @@ extern cvar_t *uvtime;
extern cvar_t *warmup;
extern cvar_t *rrot;
extern cvar_t *vrot;
extern cvar_t *e_enhancedSlippers;
extern mod_id_t meansOfDeath;
@ -2022,93 +2121,6 @@ void SP_LaserSight (edict_t * self, gitem_t * item);
void Cmd_Reload_f (edict_t * ent);
void Cmd_New_Reload_f (edict_t * ent);
enum layout_t{
LAYOUT_NONE,
LAYOUT_SCORES,
LAYOUT_SCORES2,
LAYOUT_MENU
};
enum action_sniper_modes_t
{
SNIPER_1X,
SNIPER_2X,
SNIPER_4X,
SNIPER_6X,
SNIPER_MODE_MAX
};
enum action_weapon_num_t
{
NO_WEAP_NUM,
MK23_NUM,
MP5_NUM,
M4_NUM,
M3_NUM,
HC_NUM,
SNIPER_NUM,
DUAL_NUM,
KNIFE_NUM,
GRENADE_NUM,
WEAPON_MAX
};
enum action_item_num_t
{
NO_ITEM_NUM,
SIL_NUM,
SLIP_NUM,
BAND_NUM,
KEV_NUM,
LASER_NUM,
HELM_NUM,
ITEM_MAX
};
enum action_ammo_num_t
{
NO_AMMO_NUM,
MK23_ANUM,
MP5_ANUM,
M4_ANUM,
SHELL_ANUM,
SNIPER_ANUM,
AMMO_MAX_ANUM
};
constexpr item_id_t weap_ids[] = {
IT_WEAPON_MP5,
IT_WEAPON_M4,
IT_WEAPON_M3,
IT_WEAPON_HANDCANNON,
IT_WEAPON_SNIPER
};
enum damage_loc_t {
LOC_HDAM, // head
LOC_CDAM, // chest
LOC_SDAM, // stomach
LOC_LDAM, // legs
LOC_KVLR_HELMET, // kevlar helmet Freud, for %D
LOC_KVLR_VEST, // kevlar vest Freud, for %D
LOC_NO, // Shot by shotgun or handcannon
LOC_MAX // must be last
};
enum award_t {
ACCURACY,
IMPRESSIVE,
EXCELLENT
};
enum gender_t {
GENDER_MALE,
GENDER_FEMALE,
GENDER_NEUTRAL
};
#define GENDER_STR( ent, he, she, it ) (((ent)->client->pers.gender == GENDER_MALE) ? he : (((ent)->client->pers.gender == GENDER_FEMALE) ? she : it))
struct gunStats_t
{
int shots; //Number of shots
@ -2966,6 +2978,7 @@ struct client_persistant_t
int32_t irvision; // ir on or off (only matters if player has ir device, currently bandolier)
int32_t spec_flags;
int32_t firing_style;
int32_t *menu_shown;
// Action Add End
};
@ -3015,8 +3028,6 @@ struct client_respawn_t
int32_t idletime;
int32_t totalidletime;
edict_t *kickvote;
int32_t *menu_shown;
char *mapvote; // pointer to map voted on (if any)
char *cvote; // pointer to config voted on (if any)
bool scramblevote; // want scramble
@ -3073,13 +3084,13 @@ struct team_t
};
extern team_t teams[TEAM_TOP];
#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif
// #ifndef max
// # define max(a,b) ((a) > (b) ? (a) : (b))
// #endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
// #ifndef min
// # define min(a,b) ((a) < (b) ? (a) : (b))
// #endif
// Action Add End
@ -3323,6 +3334,8 @@ struct gclient_t
int32_t knife_max;
int32_t grenade_max;
int32_t medkit;
bool bandaging;
bool bandage_stopped;
bool weapon_after_bandage_warned; // to fix message bug when calling weapon while bandaging
@ -3603,6 +3616,9 @@ struct edict_t
uint32_t crosslevel_flags;
// NOTE: if adding new elements, make sure to add them
// in g_save.cpp too!
// Action
int32_t light_level;
};
//=============

View file

@ -204,6 +204,7 @@ cvar_t *weapon_respawn;
cvar_t *ammo_respawn;
cvar_t *hc_single;
cvar_t *use_punch;
cvar_t *e_enhancedSlippers;
// Radio Settings
cvar_t *radiolog;

View file

@ -2311,8 +2311,9 @@ static void fire_lead_ap(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
while (tr.fraction < 1.0 && (tr.surface->flags & (SURF_TRANS33|SURF_TRANS66))
&& (tr.ent) && (0 == strcmp(tr.ent->classname, "func_explosive")))
{
// break glass
CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, mod);
// break glass
// Will review this later
//CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, mod);
// continue trace from current endpos to start
PRETRACE();
tr = gi.trace(tr.endpos, self->mins, self->maxs, end, tr.ent, content_mask);