bool CustomJewels::Apply(LPOBJ lpObj, int source, int target) { char sbuf[1024]={0}; int TIndex = lpObj->pInventory[target].m_Type; int SIndex = lpObj->pInventory[source].m_Type; if(source < 0 || source > ReadConfig.MAIN_INVENTORY_SIZE(lpObj->m_Index,false)-1 ) { return false; } if(target < 0 || target > ReadConfig.MAIN_INVENTORY_SIZE(lpObj->m_Index,false)-1 ) { return false; } if(lpObj->pInventory[source].IsItem() == 0) { return false; } if(lpObj->pInventory[target].IsItem() == 0) { return false; } if (lpObj->pInventory[target].m_Type >= ITEMGET(12,0)) { GCServerMsgStringSend("Can not aply this jewel to this item!",lpObj->m_Index, 0x01); return false; } if (!gObjJewelUpHackCheck(lpObj,target)) { GCServerMsgStringSend("[Anti-Hack] Shadow Bug Attempt!",lpObj->m_Index, 0x01); if(ReadConfig.AHLog == TRUE) { ANTI_HACK_LOG.Output("[Anti-Hack][Custom Jewel][%s][%s] Shadow Bug Attempt, Item: %d", lpObj->AccountID,lpObj->Name,lpObj->pInventory[target].m_Type); } return false; } BYTE jPos = IsJewel(SIndex); BYTE jSuccess = GetSuccessPosition(SIndex); BYTE jFail = GetFailPosition(SIndex); if(jPos == -1) { LogAddTD("[CJewel] Could not find jewel property with id: %d", SIndex); GCServerMsgStringSend("JEWEL ERROR, contact GM!",lpObj->m_Index, 0x01); return false; } if(jSuccess == -1) { LogAddTD("[CJewel] Could not find jewel success with id: %d", SIndex); GCServerMsgStringSend("JEWEL ERROR, contact GM!",lpObj->m_Index, 0x01); return false; } if(jFail == -1) { LogAddTD("[CJewel] Could not find jewel fail with id: %d", SIndex); GCServerMsgStringSend("JEWEL ERROR, contact GM!",lpObj->m_Index, 0x01); return false; } if(lpObj->pInventory[target].m_Level < this->Property[jPos].MinLevel) { wsprintf(sbuf,"Item level must be higher than %d!",this->Property[jPos].MinLevel); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } if(lpObj->pInventory[target].m_Level > this->Property[jPos].MaxLevel) { wsprintf(sbuf,"Item level must be lower than %d!",this->Property[jPos].MaxLevel); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } if(lpObj->pInventory[target].m_Z28Option < this->Property[jPos].MinZ28Option) { wsprintf(sbuf,"Item JOL option minimum is +%d",(this->Property[jPos].MinZ28Option*4)); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } if(this->Property[jPos].hasToHaveLuck == -1) { if (lpObj->pInventory[target].m_LuckOption != 0) { GCServerMsgStringSend("Item can not have Luck!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToHaveLuck > 0) { if (lpObj->pInventory[target].m_LuckOption == 0) { GCServerMsgStringSend("Item has to have Luck!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToHaveSkill == -1) { if (lpObj->pInventory[target].m_SkillOption != 0) { GCServerMsgStringSend("Item can not have Skill!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToHaveSkill > 0) { if (lpObj->pInventory[target].m_SkillOption == 0) { GCServerMsgStringSend("Item has to have Skill!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeAncient == -1) { if (lpObj->pInventory[target].m_SetOption != 0) { GCServerMsgStringSend("Item can not be Ancient!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeAncient > 0) { if (lpObj->pInventory[target].m_SetOption == 0) { GCServerMsgStringSend("Item must be Ancient!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeExcellent == -1) { if (lpObj->pInventory[target].m_NewOption != 0) { GCServerMsgStringSend("Item can not be Excellent!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeExcellent > 0) { if (lpObj->pInventory[target].m_NewOption == 0) { GCServerMsgStringSend("Item must be Excellent!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].MaxExc != 0) { if(NumOfExcOptions(lpObj->pInventory[target].m_NewOption) >= this->Property[jPos].MaxExc) { wsprintf(sbuf,"Cant add jewel, you have a lot of excellent options, max opt are %d!",this->Property[jPos].MaxExc); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeSoketItem == -1) { if(IsSlotItem(lpObj->pInventory[target].m_Type)==1) { GCServerMsgStringSend("Item can not be socket item!",lpObj->m_Index, 0x01); return false; } } if(this->Property[jPos].hasToBeSoketItem == 1) { if(IsSlotItem(lpObj->pInventory[target].m_Type)==0) { GCServerMsgStringSend("This item has to be socket item!",lpObj->m_Index, 0x01); return false; } else { if(this->Property[jPos].MinNumberSokets > 0) { BYTE counter = 0; if (lpObj->pInventory[target].m_ItemSlot1 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot2 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot3 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot4 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot5 > 0) counter += 1; if (this->Property[jPos].MinNumberSokets > counter) { wsprintf(sbuf,"Item minimum socket count is %d",this->Property[jPos].MinNumberSokets); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } } } } if(this->Property[jPos].MaxNumberSokets != 0) { BYTE counter = 0; if (lpObj->pInventory[target].m_ItemSlot1 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot2 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot3 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot4 > 0) counter += 1; if (lpObj->pInventory[target].m_ItemSlot5 > 0) counter += 1; if(counter >= this->Property[jPos].MaxNumberSokets) { wsprintf(sbuf,"Cant add jewel, you have a lot of socket slots, max slot are %d!",this->Property[jPos].MaxNumberSokets); GCServerMsgStringSend(sbuf,lpObj->m_Index, 0x01); return false; } } //if(MuItemShop.IsCShopItem(aIndex,target) == true) //{ // GCServerMsgStringSend("You can not use the jewel in this item!",lpObj->m_Index, 0x01); // return true; //} LogAddTD("[CJewel][%s][%s] Use %s on item %s (%d)", lpObj->AccountID,lpObj->Name,lpObj->pInventory[source].GetName(),lpObj->pInventory[target].GetName(), lpObj->pInventory[target].m_Number); int _r = rand()%100; if(_r < this->Property[jPos].Rate ) { //Success GCServerMsgStringSend("Jewel Succeded!",lpObj->m_Index, 0x01); LogAddTD("[CJewel][%s][%s] Success %s on item %s (%d) [%d][%d,%d]", lpObj->AccountID,lpObj->Name,lpObj->pInventory[source].GetName(),lpObj->pInventory[target].GetName(), lpObj->pInventory[target].m_Number, TIndex,_r,this->Property[jPos].Rate); if(this->Success[jSuccess].Luck == 1) { lpObj->pInventory[target].m_LuckOption = 1; } if(this->Success[jSuccess].Skill == 1) { lpObj->pInventory[target].m_SkillOption = 1; } if(this->Success[jSuccess].SetItem == 1) { lpObj->pInventory[target].m_SetOption = gSetItemOption.GenSetOption(lpObj->pInventory[target].m_Type); } if(this->Success[jSuccess].Excellent != 63) { if(this->Success[jSuccess].Excellent > 0) { lpObj->pInventory[target].m_NewOption |= this->Success[jSuccess].Excellent; } }else { lpObj->pInventory[target].m_NewOption = 63; } if(this->Success[jSuccess].Level > 0) { if((lpObj->pInventory[target].m_Level + this->Success[jSuccess].Level) > MAX_ITEM_LEVEL) { lpObj->pInventory[target].m_Level = MAX_ITEM_LEVEL; }else { lpObj->pInventory[target].m_Level += this->Success[jSuccess].Level; } } if(this->Success[jSuccess].Sokets > 0) { if ( IsSlotItem(lpObj->pInventory[target].m_Type) ) { for(int k=0;k<this->Success[jSuccess].Sokets;k++) { if (lpObj->pInventory[target].m_ItemSlot1 == 0) lpObj->pInventory[target].m_ItemSlot1 = 0xFF; else if (lpObj->pInventory[target].m_ItemSlot2 == 0) lpObj->pInventory[target].m_ItemSlot2 = 0xFF; else if (lpObj->pInventory[target].m_ItemSlot3 == 0) lpObj->pInventory[target].m_ItemSlot3 = 0xFF; else if (lpObj->pInventory[target].m_ItemSlot4 == 0) lpObj->pInventory[target].m_ItemSlot4 = 0xFF; else if (lpObj->pInventory[target].m_ItemSlot5 == 0) lpObj->pInventory[target].m_ItemSlot5 = 0xFF; } } } if(this->Success[jSuccess].Option > 0) { if((lpObj->pInventory[target].m_Z28Option + this->Success[jSuccess].Option) > 7) { lpObj->pInventory[target].m_Z28Option = 7; }else { lpObj->pInventory[target].m_Z28Option += this->Success[jSuccess].Option; } } } else { //Fail GCServerMsgStringSend("Jewel Failed!",lpObj->m_Index, 0x01); LogAddTD("[CJewel][%s][%s] Fail %s on item %s (%d) [%d][%d,%d]", lpObj->AccountID,lpObj->Name,lpObj->pInventory[source].GetName(),lpObj->pInventory[target].GetName(), lpObj->pInventory[target].m_Number, TIndex,_r,this->Property[jPos].Rate); if(this->Fail[jFail].Destroy == 1) { gObjInventoryItemSet(lpObj->m_Index, target, -1); lpObj->pInventory[target].Clear(); GCInventoryItemDeleteSend(lpObj->m_Index, target, 1); return true; } if(this->Fail[jFail].Luck == -1) { lpObj->pInventory[target].m_LuckOption = 0; } if(this->Fail[jFail].Skill == -1) { lpObj->pInventory[target].m_SkillOption = 0; } if(this->Fail[jFail].SetItem == -1) { lpObj->pInventory[target].m_SetOption = 0; } if(this->Fail[jFail].Excellent < 0) { if(this->Fail[jFail].Excellent == -63) lpObj->pInventory[target].m_NewOption = 0; else if( (lpObj->pInventory[target].m_NewOption&(this->Fail[jFail].Excellent)) ) lpObj->pInventory[target].m_NewOption += (this->Fail[jFail].Excellent); if(lpObj->pInventory[target].m_NewOption < 0) lpObj->pInventory[target].m_NewOption = 0; } if(this->Fail[jFail].Level < 0) { if((lpObj->pInventory[target].m_Level + (this->Fail[jFail].Level)) < 0) { lpObj->pInventory[target].m_Level = 0; }else { lpObj->pInventory[target].m_Level += (this->Fail[jFail].Level); } } if(this->Fail[jFail].Sokets < 0) { if ( IsSlotItem(lpObj->pInventory[target].m_Type) ) { for(int k=0;k<(this->Fail[jFail].Sokets);k++) { if (lpObj->pInventory[target].m_ItemSlot5 > 0) lpObj->pInventory[target].m_ItemSlot5 = 0x00; else if (lpObj->pInventory[target].m_ItemSlot4 > 0) lpObj->pInventory[target].m_ItemSlot4 = 0x00; else if (lpObj->pInventory[target].m_ItemSlot3 > 0) lpObj->pInventory[target].m_ItemSlot3 = 0x00; else if (lpObj->pInventory[target].m_ItemSlot2 > 0) lpObj->pInventory[target].m_ItemSlot2 = 0x00; else if (lpObj->pInventory[target].m_ItemSlot1 > 0) lpObj->pInventory[target].m_ItemSlot1 = 0x00; } } } if(this->Fail[jFail].Option < 0) { if((lpObj->pInventory[target].m_Z28Option + (this->Fail[jFail].Option)) < 0) { lpObj->pInventory[target].m_Z28Option = 0; }else { lpObj->pInventory[target].m_Z28Option += (this->Fail[jFail].Option); } } } float levelitemdur = ItemGetDurability(lpObj->pInventory[target].m_Type,lpObj->pInventory[target].m_Level,lpObj->pInventory[target].IsExtItem(),lpObj->pInventory[target].IsSetItem()); lpObj->pInventory[target].m_Durability = levelitemdur * lpObj->pInventory[target].m_Durability / lpObj->pInventory[target].m_BaseDurability; lpObj->pInventory[target].Convert( lpObj->pInventory[target].m_Type, lpObj->pInventory[target].m_SkillOption, lpObj->pInventory[target].m_LuckOption, lpObj->pInventory[target].m_Z28Option, lpObj->pInventory[target].m_NewOption, lpObj->pInventory[target].m_SetOption, lpObj->pInventory[target].m_ItemOptionEx, CURRENT_DB_VERSION); if(g_kJewelOfHarmonySystem.IsStrengthenByJewelOfHarmony(&lpObj->pInventory[target])== 1) { if(g_kJewelOfHarmonySystem.IsActive(&lpObj->pInventory[target]) == 0) { GCServerMsgStringSend(lMsg.Get(3370),lpObj->m_Index,1); } } return true; }
IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder order) { IBaseMenu *menu = md.menu; if (!menu) { return NULL; } struct { unsigned int position; ItemDrawInfo draw; } drawItems[10]; /* Figure out how many items to draw */ IMenuStyle *style = menu->GetDrawStyle(); unsigned int pgn = menu->GetPagination(); unsigned int maxItems = style->GetMaxPageItems(); bool exitButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT; bool novoteButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_NOVOTE) == MENUFLAG_BUTTON_NOVOTE; if (pgn != MENU_NO_PAGINATION) { maxItems = pgn; } else if (exitButton) { maxItems--; } if (novoteButton) { maxItems--; } /* This is very not allowed! */ if (maxItems < 2) { return NULL; } unsigned int totalItems = menu->GetItemCount(); unsigned int startItem = 0; /* For pagination, find the starting point. */ if (pgn != MENU_NO_PAGINATION) { if (order == ItemOrder_Ascending) { startItem = md.lastItem; /* This shouldn't happen with well-coded menus. * If the item is out of bounds, switch the order to * Items_Descending and make us start from the top. */ if (startItem >= totalItems) { startItem = totalItems - 1; order = ItemOrder_Descending; } } else if (order == ItemOrder_Descending) { startItem = md.firstItem; /* This shouldn't happen with well-coded menus. * If searching backwards doesn't give us enough room, * start from the beginning and change to ascending. */ if (startItem <= maxItems) { startItem = 0; order = ItemOrder_Ascending; } } } /* Get our Display pointer and initialize some crap */ IMenuPanel *panel = menu->CreatePanel(); IMenuHandler *mh = md.mh; bool foundExtra = false; unsigned int extraItem = 0; if (panel == NULL) { return NULL; } /** * We keep searching until: * 1) There are no more items * 2) We reach one OVER the maximum number of slot items * 3) We have reached maxItems and pagination is MENU_NO_PAGINATION */ unsigned int i = startItem; unsigned int foundItems = 0; while (totalItems) { ItemDrawInfo &dr = drawItems[foundItems].draw; /* Is the item valid? */ if (menu->GetItemInfo(i, &dr) != NULL) { /* Ask the user to change the style, if necessary */ mh->OnMenuDrawItem(menu, client, i, dr.style); /* Check if it's renderable */ if (IsSlotItem(panel, dr.style)) { /* If we've already found the max number of items, * This means we should just cancel out and log our * "last item." */ if (foundItems >= maxItems) { foundExtra = true; extraItem = i; break; } drawItems[foundItems++].position = i; } } /* If there's no pagination, stop once the menu is full. */ if (pgn == MENU_NO_PAGINATION) { /* If we've filled up, then stop */ if (foundItems >= maxItems) { break; } } /* If we're descending and this is the first item, stop */ if (order == ItemOrder_Descending) { if (i == 0) { break; } i--; } /* If we're ascending and this is the last item, stop */ else if (order == ItemOrder_Ascending) { if (i >= totalItems - 1) { break; } i++; } } /* There were no items to draw! */ if (!foundItems) { panel->DeleteThis(); return NULL; } bool displayPrev = false; bool displayNext = false; /* This is an annoying process. * Skip it for non-paginated menus, which get special treatment. */ if (pgn != MENU_NO_PAGINATION) { if (foundExtra) { if (order == ItemOrder_Descending) { displayPrev = true; md.firstItem = extraItem; } else if (order == ItemOrder_Ascending) { displayNext = true; md.lastItem = extraItem; } } unsigned int lastItem = 0; ItemDrawInfo dr; /* Find the last feasible item to search from. */ if (order == ItemOrder_Descending) { lastItem = drawItems[0].position; if (lastItem >= totalItems - 1) { goto skip_search; } while (++lastItem < totalItems) { if (menu->GetItemInfo(lastItem, &dr) != NULL) { mh->OnMenuDrawItem(menu, client, lastItem, dr.style); if (IsSlotItem(panel, dr.style)) { displayNext = true; md.lastItem = lastItem; break; } } } } else if (order == ItemOrder_Ascending) { lastItem = drawItems[0].position; if (lastItem == 0) { goto skip_search; } lastItem--; while (lastItem != 0) { if (menu->GetItemInfo(lastItem, &dr) != NULL) { mh->OnMenuDrawItem(menu, client, lastItem, dr.style); if (IsSlotItem(panel, dr.style)) { displayPrev = true; md.firstItem = lastItem; break; } } lastItem--; } } } skip_search: /* Draw the item according to the order */ menu_slots_t *slots = md.slots; unsigned int position = 0; /* Keep track of the last position */ if (novoteButton) { char text[50]; if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "No Vote", &client)) { UTIL_Format(text, sizeof(text), "No Vote"); } ItemDrawInfo dr(text, 0); position = panel->DrawItem(dr); slots[position].type = ItemSel_Exit; position++; } if (order == ItemOrder_Ascending) { md.item_on_page = drawItems[0].position; for (unsigned int i = 0; i < foundItems; i++) { ItemDrawInfo &dr = drawItems[i].draw; if ((position = mh->OnMenuDisplayItem(menu, client, panel, drawItems[i].position, dr)) == 0) { position = panel->DrawItem(dr); } if (position != 0) { slots[position].item = drawItems[i].position; if ((dr.style & ITEMDRAW_DISABLED) == ITEMDRAW_DISABLED) { slots[position].type = ItemSel_None; } else { slots[position].type = ItemSel_Item; } } } } else if (order == ItemOrder_Descending) { unsigned int i = foundItems; /* NOTE: There will always be at least one item because * of the check earlier. */ md.item_on_page = drawItems[foundItems - 1].position; while (i--) { ItemDrawInfo &dr = drawItems[i].draw; if ((position = mh->OnMenuDisplayItem(menu, client, panel, drawItems[i].position, dr)) == 0) { position = panel->DrawItem(dr); } if (position != 0) { slots[position].item = drawItems[i].position; if ((dr.style & ITEMDRAW_DISABLED) == ITEMDRAW_DISABLED) { slots[position].type = ItemSel_None; } else { slots[position].type = ItemSel_Item; } } } } /* Now, we need to check if we need to add anything extra */ if (pgn != MENU_NO_PAGINATION || exitButton) { bool canDrawDisabled = panel->CanDrawItem(ITEMDRAW_DISABLED|ITEMDRAW_CONTROL); bool exitBackButton = false; char text[50]; if (pgn != MENU_NO_PAGINATION && (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXITBACK) == MENUFLAG_BUTTON_EXITBACK) { exitBackButton = true; } /* Calculate how many items we are allowed for control stuff */ unsigned int padding = style->GetMaxPageItems() - maxItems; /* Add the number of available slots */ padding += (maxItems - foundItems); /* Someday, if we are able to re-enable this, we will be very lucky men. */ #if 0 if (!style->FeatureExists(MenuStyleFeature_ImplicitExit)) { #endif /* Even if we don't draw an exit button, we invalidate the slot. */ padding--; #if 0 } else { /* Otherwise, we don't draw anything and leave the slot available */ exitButton = false; } #endif if (pgn != MENU_NO_PAGINATION) { /* Subtract two slots for the displayNext/displayPrev padding */ padding -= 2; } /* If we have an "Exit Back" button and the space to draw it, do so. */ if (exitBackButton) { if (!displayPrev) { displayPrev = true; } else { exitBackButton = false; } } /** * We allow next/prev to be undrawn if neither exists. * Thus, we only need padding if one of them will be drawn, * or the exit button will be drawn. */ ItemDrawInfo padItem(NULL, ITEMDRAW_SPACER); if (exitButton || (displayNext || displayPrev)) { /* If there are no control options, * Instead just pad with invisible slots. */ if (!displayPrev && !displayPrev) { padItem.style = ITEMDRAW_NOTEXT; } /* Add spacers so we can pad to the end */ for (unsigned int i=0; i<padding; i++) { position = panel->DrawItem(padItem); slots[position].type = ItemSel_None; } } /* Put a fake spacer before control stuff, if possible */ if ((displayPrev || displayNext) || exitButton) { ItemDrawInfo draw("", ITEMDRAW_RAWLINE|ITEMDRAW_SPACER); panel->DrawItem(draw); } ItemDrawInfo dr(text, 0); /** * If we have one or the other, we need to have spacers for both. */ if (pgn != MENU_NO_PAGINATION) { if (displayPrev || displayNext) { /* PREVIOUS */ ItemDrawInfo padCtrlItem(NULL, ITEMDRAW_SPACER|ITEMDRAW_CONTROL); if (displayPrev || canDrawDisabled) { if (exitBackButton) { if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client)) { UTIL_Format(text, sizeof(text), "Back"); } dr.style = ITEMDRAW_CONTROL; position = panel->DrawItem(dr); slots[position].type = ItemSel_ExitBack; } else { if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client)) { UTIL_Format(text, sizeof(text), "Previous"); } dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; position = panel->DrawItem(dr); slots[position].type = ItemSel_Back; } } else if (displayNext || exitButton) { /* If we can't display this, and there is an exit button, * we need to pad! */ position = panel->DrawItem(padCtrlItem); slots[position].type = ItemSel_None; } /* NEXT */ if (displayNext || canDrawDisabled) { if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client)) { UTIL_Format(text, sizeof(text), "Next"); } dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; position = panel->DrawItem(dr); slots[position].type = ItemSel_Next; } else if (exitButton) { /* If we can't display this, * but there is an "exit" button, we need to pad! */ position = panel->DrawItem(padCtrlItem); slots[position].type = ItemSel_None; } } else { /* Otherwise, bump to two slots! */ ItemDrawInfo numBump(NULL, ITEMDRAW_NOTEXT); position = panel->DrawItem(numBump); slots[position].type = ItemSel_None; position = panel->DrawItem(numBump); slots[position].type = ItemSel_None; } } /* EXIT */ if (exitButton) { if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client)) { UTIL_Format(text, sizeof(text), "Exit"); } dr.style = ITEMDRAW_CONTROL; position = panel->DrawItem(dr); slots[position].type = ItemSel_Exit; } } /* Lastly, fill in any slots we could have missed */ for (unsigned int i = position + 1; i < 10; i++) { slots[i].type = ItemSel_None; } /* Do title stuff */ mh->OnMenuDisplay(menu, client, panel); panel->DrawTitle(menu->GetDefaultTitle(), true); return panel; }