/* ====================================================== RPG-X Emotes Window By TiM 14-5-2006 This menu is designed to allow players to choose emotes they want their characters to play ingame. ====================================================== */ #include "ui_local.h" #include "ui_logger.h" enum ui_emotesIDs_e { ID_RECENT = 1, ID_FAVORITES, ID_VIEWALL, ID_SITTING, ID_CONSOLE, ID_GESTURE, ID_FULLBODY, ID_INJURED, ID_MISC, ID_MAINMENU = 15, ID_BIND_EMOTE, ID_FAV_EMOTE, ID_DO_EMOTE, ID_LIST_UP = 20, ID_LIST_DN, ID_SCROLLBAR, ID_EMOTELIST1 = 101, ID_EMOTELIST2, ID_EMOTELIST3, ID_EMOTELIST4, ID_EMOTELIST5, ID_EMOTELIST6, ID_EMOTELIST7, ID_EMOTELIST8, ID_EMOTELIST9, ID_EMOTELIST10, ID_EMOTELIST11, ID_EMOTELIST12 }; static const char PIC_ARROW_UP[] = "menu/common/arrow_up_16.tga"; static const char PIC_ARROW_DOWN[] = "menu/common/arrow_dn_16.tga"; enum ui_emotesLimits_e { MIN_SCROLLHEIGHT = 8, MAX_MENULISTITEMS = 12, MAX_SCROLLRANGE = 198, MAX_SCROLLTOP = 204, LOW_MEMORY = (5 * 1024 * 1024) }; //Defined here so the PlayerModel APIs can handle them :) static void PlayerEmotes_FillEmotesArray(int32_t emoteCategory); static void PlayerEmotes_UpdateScrollBar(menuaction_s *bar); static void PlayerEmotes_SetupScrollBar(menuaction_s *bar); //TiM - data necessary for a scroll bar typedef struct { qboolean mouseDown; qboolean doubleStep; int32_t yStart; } scrollData_t; typedef struct { menuframework_s menu; //main buttons menubitmap_s recentFilter; menubitmap_s favoritesFilter; menubitmap_s viewAllFilter; menubitmap_s sittingFilter; menubitmap_s consoleFilter; menubitmap_s gestureFilter; menubitmap_s fullMotionFilter; menubitmap_s injuredFilter; menubitmap_s miscFilter; menubitmap_s mainMenu; //Return to game ( or main menu ) //menu arrows menubitmap_s upArrow; menubitmap_s dnArrow; menuaction_s scrollBar; //emote parameters list char emoteTitle[26]; //Emote name displayed at the top menufield_s modelOffset; //button used to enter in modeloffset data menuaction_s emoteBind; //keybind(s) for this emote int32_t bindValue; //ASCII index of the key this emote is bound to qboolean keyBindActive; //True while the code is waiting for the user to enter a new emote bind menubitmap_s addFav; //Add Favorites Button menubitmap_s playEmote; //Play Emote Button int32_t selectedEmote; int32_t favvedEmote; //the cvar index this emote is favved at //playermodel rendering variables menubitmap_s playerMdl; char playerModel[MAX_QPATH]; playerInfo_t playerInfo; vec3_t viewAngles; vec3_t moveAngles; //graphics definitions qhandle_t corner_ll_4_18; qhandle_t corner_ll_4_4; qhandle_t corner_ur_18_18; qhandle_t corner_lr_18_4; qhandle_t corner_lr_4_18; //active emotes storage definitions int32_t emoteListOffset; //offset that is incremented/decremented by the arrow tools int32_t numEmotes; //number of emotes in main list menubitmap_s emotesMenu[MAX_MENULISTITEMS]; //buttons to display the active emote set char emoteNames[MAX_MENULISTITEMS][25]; //local store for the emotes name int32_t mainEmotesList[175]; //the primary emote list, reset each time a new category is picked int32_t prevOffset; //Save the modeloffset so as to execute the command when we leave teh menu if changed int32_t currentMenu; //Save the current menu... we need this to refresh the fav menu if need be //ie this menu was called via the console ( ie a key bind instead of from the main menu) qboolean fromConsole; scrollData_t scrollData; //TiM - Scroll data } playerEmotes_t; playerEmotes_t s_playerEmotes; /* ================= Player_SpinPlayer ================= */ static void PlayerEmotes_SpinPlayer(void* ptr, int32_t event) { UI_LogFuncBegin(); if (event == QM_ACTIVATED) { uis.spinView = qtrue; uis.cursorpx = uis.cursorx; } UI_LogFuncEnd(); } /* ================= Player_InitModel ================= */ static void PlayerEmotes_InitModel(void) { UI_LogFuncBegin(); memset(&s_playerEmotes.playerInfo, 0, sizeof(playerInfo_t)); UI_PlayerInfo_SetModel(&s_playerEmotes.playerInfo, UI_Cvar_VariableString("model")); //Player_UpdateModel( ANIM_IDLE ); VectorClear(s_playerEmotes.viewAngles); VectorClear(s_playerEmotes.moveAngles); s_playerEmotes.viewAngles[YAW] = uis.lastYaw; s_playerEmotes.viewAngles[PITCH] = 0; s_playerEmotes.viewAngles[ROLL] = 0; s_playerEmotes.moveAngles[YAW] = 0; //s_main.playerViewangles[YAW]; UI_PlayerInfo_SetInfo(&s_playerEmotes.playerInfo, BOTH_STAND1, BOTH_STAND1, s_playerEmotes.viewAngles, s_playerEmotes.moveAngles, WP_0, trap_Cvar_VariableValue("height"), trap_Cvar_VariableValue("weight"), qfalse); UI_LogFuncEnd(); } /* ================= Player_DrawPlayer ================= */ static void PlayerEmotes_DrawPlayer(void) //*self ) { UI_LogFuncBegin(); vec3_t origin = { -20, 5, -4 };//{ 0, 3.8, 0}; char buf[MAX_QPATH]; if (trap_MemoryRemaining() <= LOW_MEMORY) { UI_DrawProportionalString(s_playerEmotes.playerMdl.generic.x, s_playerEmotes.playerMdl.generic.y + s_playerEmotes.playerMdl.height / 2, "LOW MEMORY", UI_LEFT, color_red); return; } trap_Cvar_VariableStringBuffer("model", buf, sizeof(buf)); //if model is changed in the console if (Q_stricmp(buf, s_playerEmotes.playerInfo.modelName)) { UI_PlayerInfo_SetModel(&s_playerEmotes.playerInfo, buf); s_playerEmotes.viewAngles[YAW] = uis.lastYaw; //yaw UI_PlayerInfo_SetInfo(&s_playerEmotes.playerInfo, BOTH_STAND1, BOTH_STAND1, s_playerEmotes.viewAngles, vec3_origin, WP_0, trap_Cvar_VariableValue("height"), trap_Cvar_VariableValue("weight"), qfalse); //reload the menu just in case PlayerEmotes_FillEmotesArray(s_playerEmotes.currentMenu); } UI_DrawPlayer(s_playerEmotes.playerMdl.generic.x, s_playerEmotes.playerMdl.generic.y, s_playerEmotes.playerMdl.width, s_playerEmotes.playerMdl.height, origin, &s_playerEmotes.playerInfo, uis.realtime); UI_LogFuncEnd(); } /* ================= Player_DoEmote TiM: Called to make the player model onscreen do the emote animation ================= */ static void Player_DoEmote(int32_t emoteNum) { UI_LogFuncBegin(); emoteList_t *emote; int32_t torsoAnim = BOTH_STAND1; int32_t legsAnim = BOTH_STAND1; int32_t legsTimer = 0; int32_t torsoTimer = 0; emote = &bg_emoteList[emoteNum]; //UI_Logger( LL_DEBUG, "Emote num: %i, Enum: %i, Legs time: %i\n", emoteNum, emote->enumName ); if (!emote){ UI_LogFuncEnd(); return; } if (emote->bodyFlags & EMOTE_LOWER) { legsAnim = emote->enumName; if (emote->enumLoop > 0) s_playerEmotes.playerInfo.lowerLoopEmote = emote->enumLoop; else s_playerEmotes.playerInfo.lowerLoopEmote = 0; } if (emote->bodyFlags & EMOTE_UPPER) { torsoAnim = emote->enumName; if (emote->enumLoop > 0) s_playerEmotes.playerInfo.upperLoopEmote = emote->enumLoop; else s_playerEmotes.playerInfo.upperLoopEmote = 0; } if (!(emote->animFlags & EMOTE_LOOP_LOWER)) { legsTimer = s_playerEmotes.playerInfo.animations[emote->enumName].numFrames * s_playerEmotes.playerInfo.animations[emote->enumName].frameLerp; s_playerEmotes.playerInfo.lowerEmoting = qtrue; } if (!(emote->animFlags & EMOTE_LOOP_UPPER)) { torsoTimer = s_playerEmotes.playerInfo.animations[emote->enumName].numFrames * s_playerEmotes.playerInfo.animations[emote->enumName].frameLerp; s_playerEmotes.playerInfo.upperEmoting = qtrue; } s_playerEmotes.playerInfo.legsAnimationTimer = legsTimer; s_playerEmotes.playerInfo.torsoAnimationTimer = torsoTimer; s_playerEmotes.viewAngles[YAW] = uis.lastYaw; UI_PlayerInfo_SetInfo(&s_playerEmotes.playerInfo, legsAnim, torsoAnim, s_playerEmotes.viewAngles, vec3_origin, WP_0, trap_Cvar_VariableValue("height"), trap_Cvar_VariableValue("weight"), qfalse); UI_LogFuncEnd(); } /* =============== PlayerEmotes_BuildEmotesList TiM: Fills in the main menu list from the main emote array. Called upon new list defines as well as when the arrow key is clicked =============== */ static void PlayerEmotes_BuildEmotesList(int32_t *emoteListOffset) { UI_LogFuncBegin(); int32_t i; int32_t offset; //clamp the offset value if (*emoteListOffset < 0) { *emoteListOffset = 0; UI_LogFuncEnd(); return; } if (s_playerEmotes.numEmotes > MAX_MENULISTITEMS && *emoteListOffset > s_playerEmotes.numEmotes - MAX_MENULISTITEMS) { *emoteListOffset = s_playerEmotes.numEmotes - MAX_MENULISTITEMS; UI_LogFuncEnd(); return; } //clear all of the previous list data memset(&s_playerEmotes.emoteNames, 0, sizeof(s_playerEmotes.emoteNames)); //populate the list for (i = 0; i < MAX_MENULISTITEMS; i++) { offset = *emoteListOffset + i; //if there's no data (ie there are no emotes this far), //make the button hidden and continue if (i > s_playerEmotes.numEmotes || s_playerEmotes.mainEmotesList[offset] == -1 || s_playerEmotes.mainEmotesList[offset] >= bg_numEmotes) { s_playerEmotes.emotesMenu[i].generic.flags = (QMF_INACTIVE | QMF_HIDDEN); s_playerEmotes.emotesMenu[i].textPtr = NULL; continue; } Q_strncpyz(s_playerEmotes.emoteNames[i], bg_emoteList[s_playerEmotes.mainEmotesList[offset]].name, sizeof(s_playerEmotes.emoteNames[i])); Q_strupr(s_playerEmotes.emoteNames[i]); s_playerEmotes.emotesMenu[i].generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.emotesMenu[i].textPtr = s_playerEmotes.emoteNames[i]; } UI_LogFuncEnd(); } /* =============== PlayerEmotes_FillEmotesArray TiM: Called when a new category button is pressed. It flushes the main list of emotes, and re-populates it with the new category. Then it reloads the main list with these new emotes =============== */ static void PlayerEmotes_FillEmotesArray(int32_t emoteCategory) { UI_LogFuncBegin(); int32_t i; emoteList_t *emote; //reset the list and counting data //NB: -1 instead of 0 since 0 is a valid emote for (i = 0; i < 175; i++) { s_playerEmotes.mainEmotesList[i] = -1; } s_playerEmotes.numEmotes = 0; s_playerEmotes.currentMenu = emoteCategory; //The first few categories are pre-set //so we'll manually handle those switch (emoteCategory) { //this one's a kicker ROFL case ID_VIEWALL: for (i = 0; i < bg_numEmotes; i++) { //TiM: Make sure we don't include emote stubs. No point emote = &bg_emoteList[i]; if (!emote || (emote->enumName >= 0 && emote->enumName < MAX_ANIMATIONS && s_playerEmotes.playerInfo.animations[emote->enumName].numFrames < 0) || !emote->name[0]) continue; s_playerEmotes.mainEmotesList[s_playerEmotes.numEmotes] = i; s_playerEmotes.numEmotes++; } break; //Console stored emote lists case ID_RECENT: case ID_FAVORITES: { char consoleName[25]; char fullName[32]; char cvarValue[5]; int32_t emoteNum; //favorites and recent are basically the same, so with a quick condition here, //we can re-use the same code for both :) if (emoteCategory == ID_RECENT) Q_strncpyz(consoleName, "ui_recentEmote", sizeof(consoleName)); else Q_strncpyz(consoleName, "ui_favoriteEmote", sizeof(consoleName)); //reversed so the thing that was added last is displayed first :) for (i = NUM_CVAR_STORES; i > 0; i--) { Com_sprintf(fullName, sizeof(fullName), "%s%i", consoleName, i); //even tho we are loading int32_t values from these CVARs, we'll be handling them like strings at first. //reason being, "0" is a valid emote number, "" isn't trap_Cvar_VariableStringBuffer(fullName, cvarValue, sizeof(cvarValue)); if (!cvarValue[0] || !Q_stricmp(cvarValue, "-1")) continue; emoteNum = atoi(cvarValue); //error check the int32_t if (emoteNum >= bg_numEmotes || emoteNum < 0) { continue; } //TiM: Make sure we don't include emote stubs. No point emote = &bg_emoteList[emoteNum]; if (!emote || (emote->enumName >= 0 && emote->enumName < MAX_ANIMATIONS && s_playerEmotes.playerInfo.animations[emote->enumName].numFrames < 0)) continue; //add to the list s_playerEmotes.mainEmotesList[s_playerEmotes.numEmotes] = emoteNum; s_playerEmotes.numEmotes++; } } break; //specific per-category emotes case ID_SITTING: case ID_CONSOLE: case ID_GESTURE: case ID_FULLBODY: case ID_INJURED: case ID_MISC: { int32_t emoteIndex; //find out the actual ID we need from that lot up there //lol a case in a case switch (emoteCategory) { case ID_SITTING: emoteIndex = TYPE_SITTING; break; case ID_CONSOLE: emoteIndex = TYPE_CONSOLE; break; case ID_GESTURE: emoteIndex = TYPE_GESTURE; break; case ID_FULLBODY: emoteIndex = TYPE_FULLBODY; break; case ID_INJURED: emoteIndex = TYPE_INJURED; break; case ID_MISC: emoteIndex = TYPE_MISC; break; default: emoteIndex = TYPE_NONE; break; } if (emoteIndex < 0) { break; } //loop thru all the emotes, and add any that have a matching Index for (i = 0; i < bg_numEmotes; i++) { //TiM: Make sure we don't include emote stubs. No point emote = &bg_emoteList[i]; if (!emote || (emote->enumName >= 0 && emote->enumName < MAX_ANIMATIONS && s_playerEmotes.playerInfo.animations[emote->enumName].numFrames < 0)) continue; if (bg_emoteList[i].emoteType == emoteIndex) { s_playerEmotes.mainEmotesList[s_playerEmotes.numEmotes] = i; s_playerEmotes.numEmotes++; } } } break; } //if the number of emotes exceeded our displayable total, then activate the arrow buttons if (s_playerEmotes.numEmotes > MAX_MENULISTITEMS) { s_playerEmotes.upArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.dnArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; } s_playerEmotes.emoteListOffset = 0; PlayerEmotes_BuildEmotesList(&s_playerEmotes.emoteListOffset); UI_LogFuncEnd(); } /* =============== PlayerEmotes_HandleNewEmote TiM: An emotes button was pressed Now to handle the tonnes of button checks n' stuff =============== */ static void PlayerEmotes_HandleNewEmote(int32_t buttonId) { UI_LogFuncBegin(); int32_t i; int32_t buttonPressed = buttonId - 100; //offset by 100 so they wouldn't get in the way char binding[256]; //get emote from stored list s_playerEmotes.selectedEmote = s_playerEmotes.mainEmotesList[buttonPressed + s_playerEmotes.emoteListOffset - 1]; Q_strncpyz(s_playerEmotes.emoteTitle, bg_emoteList[s_playerEmotes.selectedEmote].name, sizeof(s_playerEmotes.emoteTitle)); Q_strupr(s_playerEmotes.emoteTitle); //search for binds for this emote s_playerEmotes.bindValue = -1; for (i = 0; i < 256; i++){ trap_Key_GetBindingBuf(i, binding, sizeof(binding)); if (*binding == 0) continue; if (strstr(binding, bg_emoteList[s_playerEmotes.selectedEmote].name)) { s_playerEmotes.bindValue = i; break; } } s_playerEmotes.emoteBind.generic.flags = QMF_CENTER_JUSTIFY | QMF_HIGHLIGHT_IF_FOCUS; //check for favorites s_playerEmotes.favvedEmote = 0; for (i = 1; i <= NUM_CVAR_STORES; i++) { if ((int32_t)trap_Cvar_VariableValue(va("ui_favoriteEmote%i", i)) == s_playerEmotes.selectedEmote) { s_playerEmotes.favvedEmote = i; s_playerEmotes.addFav.textEnum = MBT_KILL_FAV_EMOTE; break; } } //set button title either way if (!s_playerEmotes.favvedEmote) { s_playerEmotes.addFav.textEnum = MBT_FAV_EMOTE; } //either way, make the fav button active if ((s_playerEmotes.addFav.generic.flags & QMF_INACTIVE)) { s_playerEmotes.addFav.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; } //make our player character do teh emote Player_DoEmote(s_playerEmotes.selectedEmote); UI_LogFuncEnd(); } /* =============== PlayerEmotes_HandleFav =============== */ static void PlayerEmotes_HandleFav(void) { UI_LogFuncBegin(); int32_t i; char* cvar; //safety net lol if (s_playerEmotes.selectedEmote < 0){ UI_LogFuncEnd(); return; } //this emote's been favved, so I guess we're unfaving it now if (s_playerEmotes.favvedEmote > 0) { cvar = va("ui_favoriteEmote%i", s_playerEmotes.favvedEmote); //double chack. make sure that we've got the right emote if ((int32_t)trap_Cvar_VariableValue(cvar) == s_playerEmotes.selectedEmote) { //okay, all good. unfave it trap_Cvar_Set(cvar, "-1"); //shuffle all the other favorites up the list for (i = s_playerEmotes.favvedEmote + 1; i <= NUM_CVAR_STORES; i++) { if ((int32_t)trap_Cvar_VariableValue(va("ui_favoriteEmote%i", i - 1)) == -1) { //set the previous CVAR, the value of this CVAR regardless if it's -1 or not trap_Cvar_SetValue(va("ui_favoriteEmote%i", i - 1), (int32_t)trap_Cvar_VariableValue(va("ui_favoriteEmote%i", i))); //and then flush out this CVAR trap_Cvar_Set(va("ui_favoriteEmote%i", i), "-1"); } } // if fav menu, refresh the list, else just change teh button if (s_playerEmotes.currentMenu == ID_FAVORITES) PlayerEmotes_FillEmotesArray(ID_FAVORITES); s_playerEmotes.favvedEmote = 0; s_playerEmotes.addFav.textEnum = MBT_FAV_EMOTE; } } else { //alraedy unfavved! Let's fav it! //search for the first unfavved slot we can for (i = 1; i <= NUM_CVAR_STORES; i++) { cvar = va("ui_favoriteEmote%i", i); if ((int32_t)trap_Cvar_VariableValue(cvar) == -1) { //found a slot trap_Cvar_SetValue(cvar, s_playerEmotes.selectedEmote); s_playerEmotes.favvedEmote = i; break; } } //aw damn, no slots were found if (s_playerEmotes.favvedEmote == 0) { //okay... so we're going to push the top one off, and shuffle the rest up for (i = 2; i <= NUM_CVAR_STORES; i++) { cvar = va("ui_favoriteEmote%i", i - 1); trap_Cvar_SetValue(cvar, (int32_t)trap_Cvar_VariableValue(va("ui_favoriteEmote%i", i))); if (i == NUM_CVAR_STORES) { trap_Cvar_SetValue(va("ui_favoriteEmote%i", i), s_playerEmotes.selectedEmote); s_playerEmotes.favvedEmote = NUM_CVAR_STORES; } } } if (s_playerEmotes.currentMenu == ID_FAVORITES) PlayerEmotes_FillEmotesArray(ID_FAVORITES); else { s_playerEmotes.addFav.textEnum = MBT_KILL_FAV_EMOTE; } } UI_LogFuncEnd(); } /* =============== PlayerEmotes_ExecuteOffset =============== */ static void PlayerEmotes_ExecuteOffset(void) { UI_LogFuncBegin(); int32_t offset; offset = atoi(s_playerEmotes.modelOffset.field.buffer); if (offset != s_playerEmotes.prevOffset) trap_Cmd_ExecuteText(EXEC_APPEND, va("modelOffset %i\n", offset)); UI_LogFuncEnd(); } /* =============== PlayerEmotes_Event =============== */ static void PlayerEmotes_Event(void* ptr, int32_t event) { UI_LogFuncBegin(); if (event != QM_ACTIVATED){ UI_LogFuncEnd(); return; } s_playerEmotes.keyBindActive = qfalse; switch (((menucommon_s *)ptr)->id) { //Fav button hit case ID_FAV_EMOTE: PlayerEmotes_HandleFav(); break; //emote button pressed case ID_EMOTELIST1: case ID_EMOTELIST2: case ID_EMOTELIST3: case ID_EMOTELIST4: case ID_EMOTELIST5: case ID_EMOTELIST6: case ID_EMOTELIST7: case ID_EMOTELIST8: case ID_EMOTELIST9: case ID_EMOTELIST10: case ID_EMOTELIST11: case ID_EMOTELIST12: PlayerEmotes_HandleNewEmote(((menucommon_s *)ptr)->id); break; //any of the main buttons case ID_RECENT: case ID_FAVORITES: case ID_VIEWALL: case ID_SITTING: case ID_CONSOLE: case ID_GESTURE: case ID_FULLBODY: case ID_INJURED: case ID_MISC: PlayerEmotes_FillEmotesArray(((menucommon_s *)ptr)->id); PlayerEmotes_SetupScrollBar(&s_playerEmotes.scrollBar); break; case ID_BIND_EMOTE: s_playerEmotes.keyBindActive = qtrue; break; case ID_DO_EMOTE: PlayerEmotes_ExecuteOffset(); if (s_playerEmotes.selectedEmote >= 0) trap_Cmd_ExecuteText(EXEC_APPEND, va("emote %s\n", bg_emoteList[s_playerEmotes.selectedEmote].name)); UI_ForceMenuOff(); break; case ID_LIST_UP: s_playerEmotes.emoteListOffset--; PlayerEmotes_BuildEmotesList(&s_playerEmotes.emoteListOffset); PlayerEmotes_UpdateScrollBar(&s_playerEmotes.scrollBar); break; case ID_LIST_DN: s_playerEmotes.emoteListOffset++; PlayerEmotes_BuildEmotesList(&s_playerEmotes.emoteListOffset); PlayerEmotes_UpdateScrollBar(&s_playerEmotes.scrollBar); break; case ID_MAINMENU: UI_PopMenu(); break; } UI_LogFuncEnd(); } /* =============== PlayerEmotes_Draw =============== */ static void PlayerEmotes_Draw(void) { UI_LogFuncBegin(); UI_MenuFrame(&s_playerEmotes.menu); //Left side LCARS bars trap_R_SetColor(colorTable[CT_LTGOLD1]); UI_DrawHandlePic(30, 203, 47, 70, uis.whiteShader); trap_R_SetColor(colorTable[CT_LTBROWN1]); UI_DrawHandlePic(30, 276, 47, 78, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKRED1]); UI_DrawHandlePic(30, 357, 47, 32, uis.whiteShader); //LCARS Numbers UI_DrawProportionalString(74, 66, "6154", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 84, "67144", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 188, "31456", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 206, "914344", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 279, "41634", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 360, "23513", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(74, 395, "56123", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); UI_DrawProportionalString(584, 142, "2112", UI_RIGHT | UI_TINYFONT, colorTable[CT_BLACK]); //Lines for player model frame trap_R_SetColor(colorTable[CT_LTBLUE1]); UI_DrawHandlePic(444, 228, 165, 1, uis.whiteShader); //81 UI_DrawHandlePic(446, 293, 161, 1, uis.whiteShader); //83 UI_DrawHandlePic(444, 365, 165, 1, uis.whiteShader); //81 UI_DrawHandlePic(499, 162, 1, 266, uis.whiteShader); //136 UI_DrawHandlePic(548, 162, 1, 266, uis.whiteShader); //136 //Draw Player PlayerEmotes_DrawPlayer(); //Left Bracket around model picture trap_R_SetColor(colorTable[CT_DKPURPLE2]); UI_DrawHandlePic(444, 158, 16, 16, uis.graphicBracket1CornerLU); //81 UI_DrawHandlePic(444, 174, 8, 94, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKBROWN1]); UI_DrawHandlePic(444, 271, 8, 11, uis.whiteShader); trap_R_SetColor(colorTable[CT_LTORANGE]); UI_DrawHandlePic(446, 285, 6, 21, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKBROWN1]); UI_DrawHandlePic(444, 310, 8, 11, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKPURPLE2]); UI_DrawHandlePic(444, 324, 8, 94, uis.whiteShader); UI_DrawHandlePic(444, 418, 16, -16, uis.graphicBracket1CornerLU); //LD //Right Bracket around model picture trap_R_SetColor(colorTable[CT_DKPURPLE2]); UI_DrawHandlePic(593, 158, -16, 16, uis.graphicBracket1CornerLU); //230 UI_DrawHandlePic(601, 174, 8, 94, uis.whiteShader); //238 trap_R_SetColor(colorTable[CT_DKBROWN1]); UI_DrawHandlePic(601, 271, 8, 11, uis.whiteShader); trap_R_SetColor(colorTable[CT_LTORANGE]); UI_DrawHandlePic(601, 285, 6, 21, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKBROWN1]); UI_DrawHandlePic(601, 310, 8, 11, uis.whiteShader); trap_R_SetColor(colorTable[CT_DKPURPLE2]); UI_DrawHandlePic(601, 324, 8, 94, uis.whiteShader); UI_DrawHandlePic(593, 418, -16, -16, uis.graphicBracket1CornerLU); //375 //RD //Frame around the emotes selection list UI_DrawHandlePic(85, 146, 8, -32, s_playerEmotes.corner_ll_4_18); // UL Corner UI_DrawHandlePic(85, 427, 8, 8, s_playerEmotes.corner_ll_4_4); // LL Corner UI_DrawHandlePic(237, 158, 32, 32, s_playerEmotes.corner_ur_18_18); // UR Corner UI_DrawHandlePic(239, 426, 32, 8, s_playerEmotes.corner_lr_18_4); // LR Corner UI_DrawHandlePic(85, 177, 4, 252, uis.whiteShader); // Left side UI_DrawHandlePic(241, 183, 18, 18, uis.whiteShader); //Right Side Up Arrow Button //UI_DrawHandlePic( 241, 204, 18, 198, uis.whiteShader); // Right side if (s_playerEmotes.scrollBar.generic.flags & QMF_HIDDEN) { UI_DrawHandlePic(241, 204, 18, 198, uis.whiteShader); // Right side } else { if (s_playerEmotes.scrollBar.generic.y > MAX_SCROLLTOP + 4) UI_DrawHandlePic(241, 204, 18, s_playerEmotes.scrollBar.generic.y - MAX_SCROLLTOP - 3, uis.whiteShader); if (s_playerEmotes.scrollBar.generic.bottom + 3 < 402) //343 UI_DrawHandlePic(241, s_playerEmotes.scrollBar.generic.bottom + 3, 18, 402 - 3 - s_playerEmotes.scrollBar.generic.bottom, uis.whiteShader); } UI_DrawHandlePic(241, 405, 18, 18, uis.whiteShader); //Right Side Down Button UI_DrawHandlePic(89, 158, 151, 18, uis.whiteShader); // Top UI_DrawHandlePic(90, 429, 150, 4, uis.whiteShader); // Bottom //Frame around the specific emote parameters UI_DrawHandlePic(263, 146, 8, -32, s_playerEmotes.corner_ll_4_18); // UL Corner UI_DrawHandlePic(263, 427, 8, 8, s_playerEmotes.corner_ll_4_4); // LL Corner UI_DrawHandlePic(432, 146, -8, -32, s_playerEmotes.corner_ll_4_18); // UR Corner UI_DrawHandlePic(432, 427, -8, 8, s_playerEmotes.corner_ll_4_4); // LR Corner UI_DrawHandlePic(263, 178, 4, 249, uis.whiteShader); // Left side UI_DrawHandlePic(436, 178, 4, 249, uis.whiteShader); // Right side UI_DrawHandlePic(267, 158, 166, 18, uis.whiteShader); // Top UI_DrawHandlePic(267, 429, 168, 4, uis.whiteShader); // Bottom //Emote Name / "Select an Emote" { char text[32]; if (s_playerEmotes.selectedEmote < 0) Q_strncpyz(text, menu_normal_text[MNT_CHOOSEEMOTE], sizeof(text)); else Q_strncpyz(text, s_playerEmotes.emoteTitle, sizeof(text)); UI_DrawProportionalString(351, 189, text, UI_CENTER | UI_SMALLFONT, colorTable[CT_LTGOLD1]); } //Emote List Text UI_DrawProportionalString(92, 160, menu_normal_text[MNT_EMOTELIST], UI_SMALLFONT, colorTable[CT_BLACK]); //Emote Parameters Text UI_DrawProportionalString(351, 160, menu_normal_text[MNT_EMOTEPARAM], UI_CENTER | UI_SMALLFONT, colorTable[CT_BLACK]); //set the relevant enum for the binds button if (s_playerEmotes.keyBindActive) s_playerEmotes.emoteBind.textEnum = MBT_PRESS_KEY; else s_playerEmotes.emoteBind.textEnum = MBT_KEY_BIND; if (s_playerEmotes.selectedEmote < 0) s_playerEmotes.playEmote.textEnum = MBT_CHANGE_OFFSET; else s_playerEmotes.playEmote.textEnum = MBT_DO_EMOTE; Menu_Draw(&s_playerEmotes.menu); UI_LogFuncEnd(); } /* =============== PlayerEmotes_DrawBinding =============== */ static void PlayerEmotes_DrawBinding(void *self) { UI_LogFuncBegin(); qboolean focus; menuaction_s *action; int32_t x, y; int32_t bind; char name[20]; int32_t buttonColor; int32_t textColor; int32_t width; action = (menuaction_s *)self; x = action->generic.x; y = action->generic.y; focus = (Menu_ItemAtCursor(action->generic.parent) == action); bind = s_playerEmotes.bindValue; //Get bind name if (bind <= 0 || bind >= 256) { Q_strncpyz(name, "???", sizeof(name)); } else { trap_Key_KeynumToStringBuf(bind, name, sizeof(name)); Q_strupr(name); } //get relevant colors if (focus) { buttonColor = CT_LTPURPLE1; textColor = CT_WHITE; } else { buttonColor = CT_DKPURPLE1; textColor = CT_BLACK; } if (focus) { if (menu_button_text[action->textEnum][1]) { UI_DrawProportionalString(action->generic.parent->descX, action->generic.parent->descY, menu_button_text[action->textEnum][1], UI_LEFT | UI_TINYFONT, colorTable[CT_BLACK]); } } width = action->width; if (!width) { if (menu_button_text[action->textEnum][0]) width = 19 + (SMALLCHAR_WIDTH * strlen(menu_button_text[action->textEnum][0])) + 19; else width = 19 + (SMALLCHAR_WIDTH * 11) + 19; } if (action->generic.flags & QMF_GRAYED) trap_R_SetColor(colorMdGrey); else trap_R_SetColor(colorTable[buttonColor]); UI_DrawHandlePic(x - (width >> 1), y, 19, 19, uis.graphicButtonLeftEnd); UI_DrawHandlePic(x + (width >> 1) - 19, y, -19, 19, uis.graphicButtonLeftEnd); //right UI_DrawHandlePic((x - (width >> 1)) + 11, y, width - 24, 19, uis.whiteShader); trap_R_SetColor(NULL); //button text if (strlen(menu_button_text[action->textEnum][0])) { UI_DrawProportionalString(x + action->textX, y + action->textY, menu_button_text[action->textEnum][0], UI_CENTER | UI_SMALLFONT, colorTable[textColor]); } //bind text if (action->generic.flags & QMF_GRAYED) textColor = CT_DKGREY; else textColor = CT_WHITE; UI_DrawProportionalString(x + action->textX, y + action->textY + MENU_BUTTON_MED_HEIGHT + 4, name, UI_CENTER | UI_SMALLFONT, colorTable[textColor]); UI_LogFuncEnd(); } /* ================= PlayerEmotes_DrawScrollBar ================= */ static void PlayerEmotes_DrawScrollBar(void *self) { UI_LogFuncBegin(); qboolean focus; menuaction_s *bar; int32_t *y; int32_t color; int32_t newY; int32_t dif; bar = (menuaction_s *)self; focus = (Menu_ItemAtCursor(bar->generic.parent) == bar); if (focus) color = bar->color2; else color = bar->color; trap_R_SetColor(colorTable[color]); UI_DrawHandlePic(bar->generic.x, bar->generic.y, bar->width, bar->height, uis.whiteShader); trap_R_SetColor(NULL); if (!s_playerEmotes.scrollData.mouseDown){ UI_LogFuncEnd(); return; } if (!trap_Key_IsDown(K_MOUSE1)) { s_playerEmotes.scrollData.mouseDown = qfalse; uis.activemenu->noNewSelecting = qfalse; return; } if (uis.cursory == s_playerEmotes.scrollData.yStart){ UI_LogFuncEnd(); return; } y = &bar->generic.y; newY = *y + (uis.cursory - s_playerEmotes.scrollData.yStart); if (newY + bar->height > MAX_SCROLLTOP + MAX_SCROLLRANGE) newY = (MAX_SCROLLTOP + MAX_SCROLLRANGE) - bar->height; if (newY < MAX_SCROLLTOP) newY = MAX_SCROLLTOP; dif = newY - *y; s_playerEmotes.emoteListOffset += dif * (s_playerEmotes.scrollData.doubleStep ? 2 : 1); PlayerEmotes_BuildEmotesList(&s_playerEmotes.emoteListOffset); *y = newY; bar->generic.top = *y; bar->generic.bottom = *y + bar->height; s_playerEmotes.scrollData.yStart = uis.cursory; UI_LogFuncEnd(); } /* ================= PlayerEmotes_SetupScrollBar ================= */ static void PlayerEmotes_SetupScrollBar(menuaction_s *bar) { UI_LogFuncBegin(); int32_t height; //first make sure it's worth enabling this at all if (s_playerEmotes.numEmotes <= MAX_MENULISTITEMS) { bar->generic.flags = QMF_INACTIVE | QMF_HIDDEN; UI_LogFuncEnd(); return; } //show the bar bar->generic.flags &= ~(QMF_INACTIVE | QMF_HIDDEN); //calculate the necessary height of the bar //by default, assume 1 pixel per offset height = (MAX_SCROLLRANGE)-(s_playerEmotes.numEmotes - MAX_MENULISTITEMS); //ensure box doesn't get too small if (height < MIN_SCROLLHEIGHT) { //double the step in that case //a bit hacky, but no need for 3 since the limit isn't that high height = (MAX_SCROLLRANGE)-(s_playerEmotes.numEmotes * 0.5 - MAX_MENULISTITEMS); s_playerEmotes.scrollData.doubleStep = qtrue; } else { s_playerEmotes.scrollData.doubleStep = qfalse; } //reset to top bar->generic.y = bar->generic.top = MAX_SCROLLTOP; bar->height = height; bar->generic.bottom = bar->generic.y + height; UI_LogFuncEnd(); } /* ================= PlayerEmotes_UpdateScrollBar ================= */ static void PlayerEmotes_UpdateScrollBar(menuaction_s *bar) { UI_LogFuncBegin(); bar->generic.y = MAX_SCROLLTOP + s_playerEmotes.emoteListOffset*(s_playerEmotes.scrollData.doubleStep ? 0.5 : 1); bar->generic.top = bar->generic.y; bar->generic.bottom = bar->generic.top + bar->height; UI_LogFuncEnd(); } /* =============== PlayerEmotes_KeyEvent =============== */ static sfxHandle_t PlayerEmotes_KeyEvent(int32_t key) { UI_LogFuncBegin(); menucommon_s *s; int32_t i; char command[256]; s = (menucommon_s *)Menu_ItemAtCursor(&s_playerEmotes.menu); if (s_playerEmotes.keyBindActive) { if (key & K_CHAR_FLAG) goto end; if (key < 1 || key > 256) goto end; switch (key) { case K_ESCAPE: s_playerEmotes.keyBindActive = qfalse; return (menu_out_sound); case '`': goto end; break; } //unbind this emote from anything else for (i = 1; i < 256; i++) { trap_Key_GetBindingBuf(i, command, 256); if (!Q_stricmp(command, va("emote %s", bg_emoteList[s_playerEmotes.selectedEmote].name))) { trap_Key_SetBinding(i, ""); } } //set the new command trap_Key_SetBinding(key, va("emote %s", bg_emoteList[s_playerEmotes.selectedEmote].name)); s_playerEmotes.bindValue = key; s_playerEmotes.keyBindActive = qfalse; UI_LogFuncEnd(); return (menu_out_sound); } else { //unbind the current key if (s->id == ID_BIND_EMOTE) { switch (key) { case K_BACKSPACE: case K_DEL: case K_KP_DEL: for (i = 1; i < 256; i++) { trap_Key_GetBindingBuf(i, command, 256); if (!Q_stricmp(command, va("emote %s", bg_emoteList[s_playerEmotes.selectedEmote].name))) { trap_Key_SetBinding(i, ""); s_playerEmotes.bindValue = -1; } } UI_LogFuncEnd(); return (menu_out_sound); } } } //TiM - scroll bar if (key == K_MOUSE1 && Menu_ItemAtCursor(&s_playerEmotes.menu) == &s_playerEmotes.scrollBar) { uis.activemenu->noNewSelecting = qtrue; s_playerEmotes.scrollData.mouseDown = qtrue; s_playerEmotes.scrollData.yStart = uis.cursory; } if (key == K_MOUSE2 && (s->id >= ID_EMOTELIST1 && s->id <= ID_EMOTELIST12)) { PlayerEmotes_ExecuteOffset(); int32_t emoteId = s_playerEmotes.mainEmotesList[((s->id - 100) - 1) + s_playerEmotes.emoteListOffset]; if (emoteId >= 0 && emoteId < bg_numEmotes) { trap_Cmd_ExecuteText(EXEC_APPEND, va("wait 5;emote %s\n", bg_emoteList[emoteId].name)); UI_ForceMenuOff(); UI_LogFuncEnd(); return menu_out_sound; } } end: UI_LogFuncEnd(); return (Menu_DefaultKey(&s_playerEmotes.menu, key)); } void UI_PlayerEmotes_Cache(void) { UI_LogFuncBegin(); s_playerEmotes.corner_ll_4_4 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_4_4"); s_playerEmotes.corner_ll_4_18 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_4_18"); s_playerEmotes.corner_lr_4_18 = trap_R_RegisterShaderNoMip("menu/common/corner_lr_4_18"); s_playerEmotes.corner_lr_18_4 = trap_R_RegisterShaderNoMip("menu/common/corner_lr_18_4"); s_playerEmotes.corner_ur_18_18 = trap_R_RegisterShaderNoMip("menu/common/corner_ur_18_18"); trap_R_RegisterShaderNoMip(PIC_ARROW_UP); trap_R_RegisterShaderNoMip(PIC_ARROW_DOWN); UI_LogFuncEnd(); } /* =============== PlayerEmotes_Init =============== */ static void PlayerEmotes_Init(void) { UI_LogFuncBegin(); int32_t x, y; int32_t i; qboolean showRecent = qfalse; UI_PlayerEmotes_Cache(); uis.spinView = qfalse; uis.lastYaw = 160; PlayerEmotes_InitModel(); s_playerEmotes.menu.wrapAround = qtrue; s_playerEmotes.menu.fullscreen = qtrue; s_playerEmotes.menu.draw = PlayerEmotes_Draw; s_playerEmotes.menu.descX = MENU_DESC_X; s_playerEmotes.menu.descY = MENU_DESC_Y; s_playerEmotes.menu.titleX = MENU_TITLE_X; s_playerEmotes.menu.titleY = MENU_TITLE_Y; s_playerEmotes.menu.footNoteEnum = MNT_EMOTES; s_playerEmotes.menu.titleI = MNT_EMOTES_MENU; s_playerEmotes.menu.key = PlayerEmotes_KeyEvent; x = 119; y = 57; s_playerEmotes.recentFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.recentFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.recentFilter.generic.x = x; s_playerEmotes.recentFilter.generic.y = y; s_playerEmotes.recentFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.recentFilter.generic.id = ID_RECENT; s_playerEmotes.recentFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.recentFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.recentFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.recentFilter.color = CT_DKPURPLE1; s_playerEmotes.recentFilter.color2 = CT_LTPURPLE1; s_playerEmotes.recentFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.recentFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.recentFilter.textEnum = MBT_RECENT_FILTER; s_playerEmotes.recentFilter.textcolor = CT_BLACK; s_playerEmotes.recentFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.favoritesFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.favoritesFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.favoritesFilter.generic.x = x; s_playerEmotes.favoritesFilter.generic.y = y; s_playerEmotes.favoritesFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.favoritesFilter.generic.id = ID_FAVORITES; s_playerEmotes.favoritesFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.favoritesFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.favoritesFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.favoritesFilter.color = CT_DKPURPLE1; s_playerEmotes.favoritesFilter.color2 = CT_LTPURPLE1; s_playerEmotes.favoritesFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.favoritesFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.favoritesFilter.textEnum = MBT_FAV_FILTER; s_playerEmotes.favoritesFilter.textcolor = CT_BLACK; s_playerEmotes.favoritesFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.viewAllFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.viewAllFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.viewAllFilter.generic.x = x; s_playerEmotes.viewAllFilter.generic.y = y; s_playerEmotes.viewAllFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.viewAllFilter.generic.id = ID_VIEWALL; s_playerEmotes.viewAllFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.viewAllFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.viewAllFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.viewAllFilter.color = CT_DKPURPLE1; s_playerEmotes.viewAllFilter.color2 = CT_LTPURPLE1; s_playerEmotes.viewAllFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.viewAllFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.viewAllFilter.textEnum = MBT_ALL_FILTER; s_playerEmotes.viewAllFilter.textcolor = CT_BLACK; s_playerEmotes.viewAllFilter.textcolor2 = CT_WHITE; y = 57; x += 153; s_playerEmotes.sittingFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.sittingFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.sittingFilter.generic.x = x; s_playerEmotes.sittingFilter.generic.y = y; s_playerEmotes.sittingFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.sittingFilter.generic.id = ID_SITTING; s_playerEmotes.sittingFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.sittingFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.sittingFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.sittingFilter.color = CT_DKPURPLE1; s_playerEmotes.sittingFilter.color2 = CT_LTPURPLE1; s_playerEmotes.sittingFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.sittingFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.sittingFilter.textEnum = MBT_SITTING_FILTER; s_playerEmotes.sittingFilter.textcolor = CT_BLACK; s_playerEmotes.sittingFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.consoleFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.consoleFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.consoleFilter.generic.x = x; s_playerEmotes.consoleFilter.generic.y = y; s_playerEmotes.consoleFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.consoleFilter.generic.id = ID_CONSOLE; s_playerEmotes.consoleFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.consoleFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.consoleFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.consoleFilter.color = CT_DKPURPLE1; s_playerEmotes.consoleFilter.color2 = CT_LTPURPLE1; s_playerEmotes.consoleFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.consoleFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.consoleFilter.textEnum = MBT_CONSOLE_FILTER; s_playerEmotes.consoleFilter.textcolor = CT_BLACK; s_playerEmotes.consoleFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.gestureFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.gestureFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.gestureFilter.generic.x = x; s_playerEmotes.gestureFilter.generic.y = y; s_playerEmotes.gestureFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.gestureFilter.generic.id = ID_GESTURE; s_playerEmotes.gestureFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.gestureFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.gestureFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.gestureFilter.color = CT_DKPURPLE1; s_playerEmotes.gestureFilter.color2 = CT_LTPURPLE1; s_playerEmotes.gestureFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.gestureFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.gestureFilter.textEnum = MBT_GESTURE_FILTER; s_playerEmotes.gestureFilter.textcolor = CT_BLACK; s_playerEmotes.gestureFilter.textcolor2 = CT_WHITE; x += 153; y = 57; s_playerEmotes.fullMotionFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.fullMotionFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.fullMotionFilter.generic.x = x; s_playerEmotes.fullMotionFilter.generic.y = y; s_playerEmotes.fullMotionFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.fullMotionFilter.generic.id = ID_FULLBODY; s_playerEmotes.fullMotionFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.fullMotionFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.fullMotionFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.fullMotionFilter.color = CT_DKPURPLE1; s_playerEmotes.fullMotionFilter.color2 = CT_LTPURPLE1; s_playerEmotes.fullMotionFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.fullMotionFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.fullMotionFilter.textEnum = MBT_FULLMOTION_FILTER; s_playerEmotes.fullMotionFilter.textcolor = CT_BLACK; s_playerEmotes.fullMotionFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.injuredFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.injuredFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.injuredFilter.generic.x = x; s_playerEmotes.injuredFilter.generic.y = y; s_playerEmotes.injuredFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.injuredFilter.generic.id = ID_INJURED; s_playerEmotes.injuredFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.injuredFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.injuredFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.injuredFilter.color = CT_DKPURPLE1; s_playerEmotes.injuredFilter.color2 = CT_LTPURPLE1; s_playerEmotes.injuredFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.injuredFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.injuredFilter.textEnum = MBT_INJURED_FILTER; s_playerEmotes.injuredFilter.textcolor = CT_BLACK; s_playerEmotes.injuredFilter.textcolor2 = CT_WHITE; y += 25; s_playerEmotes.miscFilter.generic.type = MTYPE_BITMAP; s_playerEmotes.miscFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.miscFilter.generic.x = x; s_playerEmotes.miscFilter.generic.y = y; s_playerEmotes.miscFilter.generic.name = GRAPHIC_SQUARE; s_playerEmotes.miscFilter.generic.id = ID_MISC; s_playerEmotes.miscFilter.generic.callback = PlayerEmotes_Event; s_playerEmotes.miscFilter.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.miscFilter.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.miscFilter.color = CT_DKPURPLE1; s_playerEmotes.miscFilter.color2 = CT_LTPURPLE1; s_playerEmotes.miscFilter.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.miscFilter.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.miscFilter.textEnum = MBT_MISC_FILTER; s_playerEmotes.miscFilter.textcolor = CT_BLACK; s_playerEmotes.miscFilter.textcolor2 = CT_WHITE; x = 90; y = 179; for (i = 0; i < MAX_MENULISTITEMS; i++) { s_playerEmotes.emotesMenu[i].generic.type = MTYPE_BITMAP; s_playerEmotes.emotesMenu[i].generic.flags = QMF_INACTIVE | QMF_HIDDEN; s_playerEmotes.emotesMenu[i].generic.x = x; s_playerEmotes.emotesMenu[i].generic.y = y; s_playerEmotes.emotesMenu[i].generic.callback = PlayerEmotes_Event; s_playerEmotes.emotesMenu[i].generic.id = ID_EMOTELIST1 + i; s_playerEmotes.emotesMenu[i].width = 129; s_playerEmotes.emotesMenu[i].height = 16; s_playerEmotes.emotesMenu[i].color = CT_DKPURPLE1; s_playerEmotes.emotesMenu[i].color2 = CT_LTPURPLE1; s_playerEmotes.emotesMenu[i].textPtr = NULL; s_playerEmotes.emotesMenu[i].textX = 4; s_playerEmotes.emotesMenu[i].textY = 1; s_playerEmotes.emotesMenu[i].textcolor = CT_DKGOLD1; s_playerEmotes.emotesMenu[i].textcolor2 = CT_LTGOLD1; s_playerEmotes.emotesMenu[i].textStyle = UI_SMALLFONT; y += 21; } s_playerEmotes.upArrow.generic.type = MTYPE_BITMAP; s_playerEmotes.upArrow.generic.flags = QMF_INACTIVE | QMF_GRAYED; s_playerEmotes.upArrow.generic.x = 242; s_playerEmotes.upArrow.generic.y = 185; s_playerEmotes.upArrow.generic.name = PIC_ARROW_UP; s_playerEmotes.upArrow.generic.id = ID_LIST_UP; s_playerEmotes.upArrow.generic.callback = PlayerEmotes_Event; s_playerEmotes.upArrow.width = 16; s_playerEmotes.upArrow.height = 16; s_playerEmotes.upArrow.color = CT_DKPURPLE1; s_playerEmotes.upArrow.color2 = CT_LTPURPLE1; s_playerEmotes.upArrow.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.upArrow.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.upArrow.textcolor = CT_BLACK; s_playerEmotes.upArrow.textcolor2 = CT_WHITE; s_playerEmotes.dnArrow.generic.type = MTYPE_BITMAP; s_playerEmotes.dnArrow.generic.flags = QMF_INACTIVE | QMF_GRAYED; s_playerEmotes.dnArrow.generic.x = 242; s_playerEmotes.dnArrow.generic.y = 407; s_playerEmotes.dnArrow.generic.name = PIC_ARROW_DOWN; s_playerEmotes.dnArrow.generic.id = ID_LIST_DN; s_playerEmotes.dnArrow.generic.callback = PlayerEmotes_Event; s_playerEmotes.dnArrow.width = 16; s_playerEmotes.dnArrow.height = 16; s_playerEmotes.dnArrow.color = CT_DKPURPLE1; s_playerEmotes.dnArrow.color2 = CT_LTPURPLE1; s_playerEmotes.dnArrow.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.dnArrow.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.dnArrow.textcolor = CT_BLACK; s_playerEmotes.dnArrow.textcolor2 = CT_WHITE; s_playerEmotes.mainMenu.generic.type = MTYPE_BITMAP; s_playerEmotes.mainMenu.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.mainMenu.generic.x = 482; s_playerEmotes.mainMenu.generic.y = 136; s_playerEmotes.mainMenu.generic.name = BUTTON_GRAPHIC_LONGRIGHT; s_playerEmotes.mainMenu.generic.id = ID_MAINMENU; s_playerEmotes.mainMenu.generic.callback = PlayerEmotes_Event; s_playerEmotes.mainMenu.width = MENU_BUTTON_MED_WIDTH; s_playerEmotes.mainMenu.height = MENU_BUTTON_MED_HEIGHT; s_playerEmotes.mainMenu.color = CT_DKPURPLE1; s_playerEmotes.mainMenu.color2 = CT_LTPURPLE1; s_playerEmotes.mainMenu.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.mainMenu.textY = MENU_BUTTON_TEXT_Y; if (!ingameFlag || !s_playerEmotes.fromConsole) s_playerEmotes.mainMenu.textEnum = MBT_MAINMENU; else s_playerEmotes.mainMenu.textEnum = MBT_INGAMERESUME; s_playerEmotes.mainMenu.textcolor = CT_BLACK; s_playerEmotes.mainMenu.textcolor2 = CT_WHITE; s_playerEmotes.modelOffset.generic.type = MTYPE_FIELD; s_playerEmotes.modelOffset.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.modelOffset.generic.x = 351; s_playerEmotes.modelOffset.generic.y = 225; s_playerEmotes.modelOffset.generic.name = menu_normal_text[MNT_MODELOFFSET]; //TiM : This var was untouched from Q3, so I've modded it for RPG-X functionality s_playerEmotes.modelOffset.field.widthInChars = 14; s_playerEmotes.modelOffset.field.maxchars = 5; s_playerEmotes.modelOffset.field.titleEnum = MBT_MODEL_OFFSET; s_playerEmotes.modelOffset.field.textcolor = CT_WHITE; //CT_DKGOLD1 s_playerEmotes.modelOffset.field.textcolor2 = CT_WHITE; //CT_DKGOLD1 s_playerEmotes.modelOffset.field.style = UI_CENTER | UI_SMALLFONT; //Due to Raven's hacky nature, and my exploiting it therefore, SMALLFONT MUST accompany CENTER s_playerEmotes.emoteBind.generic.type = MTYPE_ACTION; s_playerEmotes.emoteBind.generic.flags = QMF_CENTER_JUSTIFY | QMF_GRAYED | QMF_INACTIVE; s_playerEmotes.emoteBind.generic.x = 351; s_playerEmotes.emoteBind.generic.y = 291; s_playerEmotes.emoteBind.generic.id = ID_BIND_EMOTE; s_playerEmotes.emoteBind.generic.callback = PlayerEmotes_Event; s_playerEmotes.emoteBind.generic.ownerdraw = PlayerEmotes_DrawBinding; s_playerEmotes.emoteBind.textEnum = MBT_KEY_BIND; s_playerEmotes.emoteBind.width = 133; s_playerEmotes.emoteBind.height = 39; s_playerEmotes.emoteBind.textY = 2; s_playerEmotes.addFav.generic.type = MTYPE_BITMAP; s_playerEmotes.addFav.generic.flags = QMF_GRAYED | QMF_INACTIVE; s_playerEmotes.addFav.generic.x = 273; s_playerEmotes.addFav.generic.y = 355; s_playerEmotes.addFav.generic.name = GRAPHIC_SQUARE; s_playerEmotes.addFav.generic.id = ID_FAV_EMOTE; s_playerEmotes.addFav.generic.callback = PlayerEmotes_Event; s_playerEmotes.addFav.width = 157; s_playerEmotes.addFav.height = 19; s_playerEmotes.addFav.color = CT_DKPURPLE1; s_playerEmotes.addFav.color2 = CT_LTPURPLE1; s_playerEmotes.addFav.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.addFav.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.addFav.textEnum = MBT_FAV_EMOTE; s_playerEmotes.addFav.textcolor = CT_BLACK; s_playerEmotes.addFav.textcolor2 = CT_WHITE; s_playerEmotes.playEmote.generic.type = MTYPE_BITMAP; s_playerEmotes.playEmote.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; s_playerEmotes.playEmote.generic.x = 273; s_playerEmotes.playEmote.generic.y = 381; s_playerEmotes.playEmote.generic.name = GRAPHIC_SQUARE; s_playerEmotes.playEmote.generic.id = ID_DO_EMOTE; s_playerEmotes.playEmote.generic.callback = PlayerEmotes_Event; s_playerEmotes.playEmote.width = 157; s_playerEmotes.playEmote.height = 43; s_playerEmotes.playEmote.color = CT_DKPURPLE1; s_playerEmotes.playEmote.color2 = CT_LTPURPLE1; s_playerEmotes.playEmote.textX = MENU_BUTTON_TEXT_X; s_playerEmotes.playEmote.textY = MENU_BUTTON_TEXT_Y; s_playerEmotes.playEmote.textEnum = MBT_DO_EMOTE; s_playerEmotes.playEmote.textcolor = CT_BLACK; s_playerEmotes.playEmote.textcolor2 = CT_WHITE; //Spinbox for player model s_playerEmotes.playerMdl.generic.type = MTYPE_BITMAP; s_playerEmotes.playerMdl.generic.flags = QMF_SILENT; //INACTIVE s_playerEmotes.playerMdl.generic.callback = PlayerEmotes_SpinPlayer; s_playerEmotes.playerMdl.generic.x = 82 + 363; //440 //25 s_playerEmotes.playerMdl.generic.y = 158; //95 s_playerEmotes.playerMdl.width = 164; //32*6.6 //211.2 //246.2 s_playerEmotes.playerMdl.height = 276; //56*6.6 //369.6 //404.6 s_playerEmotes.scrollBar.generic.type = MTYPE_ACTION; s_playerEmotes.scrollBar.generic.flags = QMF_INACTIVE | QMF_HIDDEN; s_playerEmotes.scrollBar.generic.x = 241; s_playerEmotes.scrollBar.generic.y = 204; s_playerEmotes.scrollBar.generic.id = ID_SCROLLBAR; s_playerEmotes.scrollBar.generic.ownerdraw = PlayerEmotes_DrawScrollBar; s_playerEmotes.scrollBar.width = 18; s_playerEmotes.scrollBar.height = MIN_SCROLLHEIGHT; s_playerEmotes.scrollBar.color = CT_DKPURPLE1; s_playerEmotes.scrollBar.color2 = CT_LTPURPLE1; Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.recentFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.favoritesFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.viewAllFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.sittingFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.consoleFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.gestureFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.fullMotionFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.injuredFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.miscFilter); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.upArrow); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.scrollBar); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.dnArrow); for (i = 0; i < MAX_MENULISTITEMS; i++) { Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.emotesMenu[i]); } Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.modelOffset); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.emoteBind); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.addFav); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.playEmote); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.playerMdl); Menu_AddItem(&s_playerEmotes.menu, &s_playerEmotes.mainMenu); //Emote data initialization //trap_Cvar_VariableStringBuffer( "modelOffset", modelOffset, sizeof( modelOffset ) ); s_playerEmotes.prevOffset = (int32_t)trap_Cvar_VariableValue("modelOffset"); Q_strncpyz(s_playerEmotes.modelOffset.field.buffer, va("%i", s_playerEmotes.prevOffset), s_playerEmotes.modelOffset.field.maxchars); s_playerEmotes.selectedEmote = -1; //cheesy hack, but it works. if there's nothing in the recent array, do display all for (i = 1; i <= NUM_CVAR_STORES; i++) { if ((int32_t)trap_Cvar_VariableValue(va("ui_recentEmote%i", i)) >= 0) { showRecent = qtrue; break; } } if (!showRecent) { Menu_SetCursorToItem(&s_playerEmotes.menu, &s_playerEmotes.viewAllFilter); PlayerEmotes_FillEmotesArray(ID_VIEWALL); } else { Menu_SetCursorToItem(&s_playerEmotes.menu, &s_playerEmotes.recentFilter); PlayerEmotes_FillEmotesArray(ID_RECENT); } PlayerEmotes_SetupScrollBar(&s_playerEmotes.scrollBar); PlayerEmotes_UpdateScrollBar(&s_playerEmotes.scrollBar); UI_LogFuncEnd(); } /* =============== UI_EmotesMenu =============== */ void UI_EmotesMenu(qboolean fromConsole) { UI_LogFuncBegin(); memset(&s_playerEmotes, 0, sizeof(s_playerEmotes)); s_playerEmotes.fromConsole = fromConsole; PlayerEmotes_Init(); ingameFlag = qtrue; Mouse_Show(); UI_PushMenu(&s_playerEmotes.menu); UI_LogFuncEnd(); }