static menu_t *CreateCustomizeMenu( const char *name, PlayerSelectMenuData *data, Character *c, struct PlayerData *p) { menu_t *menu = MenuCreateNormal(name, "", MENU_TYPE_NORMAL, 0); data->faceData.c = c; data->faceData.pData = p; data->faceData.menuCount = FACE_COUNT; data->faceData.strFunc = IndexToFaceStr; data->faceData.property = &p->looks.face; MenuAddSubmenu(menu, CreateAppearanceMenu("Face", &data->faceData)); data->skinData.c = c; data->skinData.pData = p; data->skinData.menuCount = SHADE_COUNT; data->skinData.strFunc = IndexToShadeStr; data->skinData.property = &p->looks.skin; MenuAddSubmenu(menu, CreateAppearanceMenu("Skin", &data->skinData)); data->hairData.c = c; data->hairData.pData = p; data->hairData.menuCount = SHADE_COUNT; data->hairData.strFunc = IndexToShadeStr; data->hairData.property = &p->looks.hair; MenuAddSubmenu(menu, CreateAppearanceMenu("Hair", &data->hairData)); data->armsData.c = c; data->armsData.pData = p; data->armsData.menuCount = SHADE_COUNT; data->armsData.strFunc = IndexToShadeStr; data->armsData.property = &p->looks.arm; MenuAddSubmenu(menu, CreateAppearanceMenu("Arms", &data->armsData)); data->bodyData.c = c; data->bodyData.pData = p; data->bodyData.menuCount = SHADE_COUNT; data->bodyData.strFunc = IndexToShadeStr; data->bodyData.property = &p->looks.body; MenuAddSubmenu(menu, CreateAppearanceMenu("Body", &data->bodyData)); data->legsData.c = c; data->legsData.pData = p; data->legsData.menuCount = SHADE_COUNT; data->legsData.strFunc = IndexToShadeStr; data->legsData.property = &p->looks.leg; MenuAddSubmenu(menu, CreateAppearanceMenu("Legs", &data->legsData)); MenuAddSubmenu(menu, MenuCreateSeparator("")); MenuAddSubmenu(menu, MenuCreateBack("Back")); return menu; }
static menu_t *CreateCustomizeMenu( const char *name, PlayerSelectMenuData *data, const int playerUID) { menu_t *menu = MenuCreateNormal(name, "", MENU_TYPE_NORMAL, 0); data->faceData.PlayerUID = playerUID; data->faceData.menuCount = FACE_COUNT; data->faceData.strFunc = IndexToFaceStr; data->faceData.propertyOffset = offsetof(NCharLooks, Face); MenuAddSubmenu(menu, CreateAppearanceMenu("Face", &data->faceData)); data->skinData.PlayerUID = playerUID; data->skinData.menuCount = SHADE_COUNT; data->skinData.strFunc = IndexToShadeStr; data->skinData.propertyOffset = offsetof(NCharLooks, Skin); MenuAddSubmenu(menu, CreateAppearanceMenu("Skin", &data->skinData)); data->hairData.PlayerUID = playerUID; data->hairData.menuCount = SHADE_COUNT; data->hairData.strFunc = IndexToShadeStr; data->hairData.propertyOffset = offsetof(NCharLooks, Hair); MenuAddSubmenu(menu, CreateAppearanceMenu("Hair", &data->hairData)); data->armsData.PlayerUID = playerUID; data->armsData.menuCount = SHADE_COUNT; data->armsData.strFunc = IndexToShadeStr; data->armsData.propertyOffset = offsetof(NCharLooks, Arm); MenuAddSubmenu(menu, CreateAppearanceMenu("Arms", &data->armsData)); data->bodyData.PlayerUID = playerUID; data->bodyData.menuCount = SHADE_COUNT; data->bodyData.strFunc = IndexToShadeStr; data->bodyData.propertyOffset = offsetof(NCharLooks, Body); MenuAddSubmenu(menu, CreateAppearanceMenu("Body", &data->bodyData)); data->legsData.PlayerUID = playerUID; data->legsData.menuCount = SHADE_COUNT; data->legsData.strFunc = IndexToShadeStr; data->legsData.propertyOffset = offsetof(NCharLooks, Leg); MenuAddSubmenu(menu, CreateAppearanceMenu("Legs", &data->legsData)); MenuAddSubmenu(menu, MenuCreateSeparator("")); MenuAddSubmenu(menu, MenuCreateBack("Back")); return menu; }
static menu_t *MenuCreateAllowedWeapons( const char *name, AllowedWeaponsData *data) { // Create a menu to choose allowable weapons for this map // The weapons will be chosen from the available weapons menu_t *m = MenuCreateNormal(name, "Available Weapons:", MENU_TYPE_OPTIONS, 0); m->customPostInputData = data; for (int i = 0; i < (int)data->weapons->size; i++) { const GunDescription **g = CArrayGet(data->weapons, i); MenuAddSubmenu(m, MenuCreateOptionToggle((*g)->name, CArrayGet(&data->allowed, i))); } MenuAddSubmenu(m, MenuCreateSeparator("")); MenuAddSubmenu(m, MenuCreateBack("Done")); return m; }
void PlayerSelectMenusCreate( PlayerSelectMenu *menu, int numPlayers, int player, Character *c, struct PlayerData *pData, EventHandlers *handlers, GraphicsDevice *graphics, InputConfig *inputConfig) { MenuSystem *ms = &menu->ms; PlayerSelectMenuData *data = &menu->data; struct PlayerData *p = pData; Vec2i pos = Vec2iZero(); Vec2i size = Vec2iZero(); int w = graphics->cachedConfig.Res.x; int h = graphics->cachedConfig.Res.y; data->nameMenuSelection = (int)strlen(letters); data->display.c = c; data->display.currentMenu = &ms->current; data->display.pData = pData; data->controls.inputConfig = inputConfig; data->controls.pData = pData; switch (numPlayers) { case 1: // Single menu, entire screen pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; case 2: // Two menus, side by side pos = Vec2iNew(player * w / 2 + w / 4, 0); size = Vec2iNew(w / 4, h); break; case 3: case 4: // Four corners pos = Vec2iNew((player & 1) * w / 2 + w / 4, (player / 2) * h / 2); size = Vec2iNew(w / 4, h / 2); break; default: assert(0 && "not implemented"); break; } MenuSystemInit(ms, handlers, graphics, pos, size); ms->align = MENU_ALIGN_LEFT; ms->root = ms->current = MenuCreateNormal( "", "", MENU_TYPE_NORMAL, 0); MenuAddSubmenu( ms->root, MenuCreateCustom( "Name", DrawNameMenu, HandleInputNameMenu, data)); data->faceData.c = c; data->faceData.pData = p; data->faceData.menuCount = FACE_COUNT; data->faceData.strFunc = IndexToFaceStr; data->faceData.property = &p->looks.face; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Face", &data->faceData)); data->skinData.c = c; data->skinData.pData = p; data->skinData.menuCount = SHADE_COUNT; data->skinData.strFunc = IndexToShadeStr; data->skinData.property = &p->looks.skin; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Skin", &data->skinData)); data->hairData.c = c; data->hairData.pData = p; data->hairData.menuCount = SHADE_COUNT; data->hairData.strFunc = IndexToShadeStr; data->hairData.property = &p->looks.hair; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Hair", &data->hairData)); data->armsData.c = c; data->armsData.pData = p; data->armsData.menuCount = SHADE_COUNT; data->armsData.strFunc = IndexToShadeStr; data->armsData.property = &p->looks.arm; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Arms", &data->armsData)); data->bodyData.c = c; data->bodyData.pData = p; data->bodyData.menuCount = SHADE_COUNT; data->bodyData.strFunc = IndexToShadeStr; data->bodyData.property = &p->looks.body; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Body", &data->bodyData)); data->legsData.c = c; data->legsData.pData = p; data->legsData.menuCount = SHADE_COUNT; data->legsData.strFunc = IndexToShadeStr; data->legsData.property = &p->looks.leg; MenuAddSubmenu(ms->root, CreateAppearanceMenu("Legs", &data->legsData)); MenuAddSubmenu(ms->root, CreateUseTemplateMenu("Load", data)); MenuAddSubmenu(ms->root, CreateSaveTemplateMenu("Save", data)); MenuAddSubmenu(ms->root, MenuCreateSeparator("")); MenuAddSubmenu( ms->root, MenuCreateNormal("Done", "", MENU_TYPE_NORMAL, 0)); MenuAddExitType(ms, MENU_TYPE_RETURN); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayer, data); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayerControls, &data->controls); // Detect when there have been new player templates created, // to re-enable the load menu CheckReenableLoadMenu(ms->root, NULL); MenuSetPostEnterFunc(ms->root, CheckReenableLoadMenu, NULL); SetPlayer(c, pData); }
bool GameOptions(const GameMode gm) { // Create selection menus const int w = gGraphicsDevice.cachedConfig.Res.x; const int h = gGraphicsDevice.cachedConfig.Res.y; MenuSystem ms; MenuSystemInit( &ms, &gEventHandlers, &gGraphicsDevice, Vec2iZero(), Vec2iNew(w, h)); ms.align = MENU_ALIGN_CENTER; ms.allowAborts = true; AllowedWeaponsData awData; AllowedWeaponsDataInit(&awData, &gMission.Weapons); switch (gm) { case GAME_MODE_DEATHMATCH: ms.root = ms.current = MenuCreateNormal( "", "", MENU_TYPE_OPTIONS, 0); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.PlayerHP")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Deathmatch.Lives")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.HealthPickups")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Game.Ammo")); MenuAddSubmenu(ms.current, MenuCreateAllowedWeapons("Weapons...", &awData)); MenuAddSubmenu(ms.current, MenuCreateSeparator("")); MenuAddSubmenu(ms.current, MenuCreateReturn("Done", 0)); break; case GAME_MODE_DOGFIGHT: ms.root = ms.current = MenuCreateNormal( "", "", MENU_TYPE_OPTIONS, 0); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Dogfight.PlayerHP")); MenuAddConfigOptionsItem( ms.current, ConfigGet(&gConfig, "Dogfight.FirstTo")); MenuAddSubmenu(ms.current, MenuCreateAllowedWeapons("Weapons...", &awData)); MenuAddSubmenu(ms.current, MenuCreateSeparator("")); MenuAddSubmenu(ms.current, MenuCreateReturn("Done", 0)); break; default: CASSERT(false, "unknown game mode"); break; } MenuAddExitType(&ms, MENU_TYPE_RETURN); MenuLoop(&ms); const bool ok = !ms.hasAbort; if (ok) { ConfigApply(&gConfig); // Save options for later ConfigSave(&gConfig, GetConfigFilePath(CONFIG_FILE)); // Set allowed weapons // First check if the player has unwittingly disabled all weapons // if so, enable all weapons bool allDisabled = true; for (int i = 0, j = 0; i < (int)awData.allowed.size; i++, j++) { const bool *allowed = CArrayGet(&awData.allowed, i); if (*allowed) { allDisabled = false; break; } } if (!allDisabled) { for (int i = 0, j = 0; i < (int)awData.allowed.size; i++, j++) { const bool *allowed = CArrayGet(&awData.allowed, i); if (!*allowed) { CArrayDelete(&gMission.Weapons, j); j--; } } } } AllowedWeaponsDataTerminate(&awData); MenuSystemTerminate(&ms); return ok; }
void WeaponMenuCreate( WeaponMenu *menu, int numPlayers, int player, const int playerUID, EventHandlers *handlers, GraphicsDevice *graphics) { MenuSystem *ms = &menu->ms; WeaponMenuData *data = &menu->data; Vec2i pos, size; int w = graphics->cachedConfig.Res.x; int h = graphics->cachedConfig.Res.y; data->display.PlayerUID = playerUID; data->display.currentMenu = &ms->current; data->display.Dir = DIRECTION_DOWN; data->PlayerUID = playerUID; switch (numPlayers) { case 1: // Single menu, entire screen pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; case 2: // Two menus, side by side pos = Vec2iNew(player * w / 2 + w / 4, 0); size = Vec2iNew(w / 4, h); break; case 3: case 4: // Four corners pos = Vec2iNew((player & 1) * w / 2 + w / 4, (player / 2) * h / 2); size = Vec2iNew(w / 4, h / 2); break; default: CASSERT(false, "not implemented"); pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; } MenuSystemInit(ms, handlers, graphics, pos, size); ms->align = MENU_ALIGN_LEFT; ms->root = ms->current = MenuCreateNormal( "", "", MENU_TYPE_NORMAL, 0); ms->root->u.normal.maxItems = 11; const CArray *weapons = &gMission.Weapons; for (int i = 0; i < (int)weapons->size; i++) { const GunDescription **g = CArrayGet(weapons, i); menu_t *gunMenu; if ((*g)->Description != NULL) { // Gun description menu gunMenu = MenuCreateNormal((*g)->name, "", MENU_TYPE_NORMAL, 0); char *buf; CMALLOC(buf, strlen((*g)->Description) * 2); FontSplitLines((*g)->Description, buf, size.x * 5 / 6); MenuAddSubmenu(gunMenu, MenuCreateBack(buf)); CFREE(buf); gunMenu->u.normal.isSubmenusAlt = true; MenuSetCustomDisplay(gunMenu, DisplayDescriptionGunIcon, *g); } else { gunMenu = MenuCreate((*g)->name, MENU_TYPE_BASIC); } MenuAddSubmenu(ms->root, gunMenu); } MenuSetPostInputFunc(ms->root, WeaponSelect, &data->display); // Disable menu items where the player already has the weapon PlayerData *pData = PlayerDataGetByUID(playerUID); for (int i = 0; i < pData->weaponCount; i++) { for (int j = 0; j < (int)weapons->size; j++) { const GunDescription **g = CArrayGet(weapons, j); if (pData->weapons[i] == *g) { MenuDisableSubmenu(ms->root, j); } } } MenuAddSubmenu(ms->root, MenuCreateSeparator("")); MenuAddSubmenu( ms->root, MenuCreateNormal("(End)", "", MENU_TYPE_NORMAL, 0)); // Select "(End)" ms->root->u.normal.index = (int)ms->root->u.normal.subMenus.size - 1; // Disable "Done" if no weapons selected if (pData->weaponCount == 0) { MenuDisableSubmenu(ms->root, (int)ms->root->u.normal.subMenus.size - 1); } MenuSetCustomDisplay(ms->root, DisplayGunIcon, NULL); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayer, &data->display); MenuSystemAddCustomDisplay(ms, DisplayEquippedWeapons, data); MenuSystemAddCustomDisplay( ms, MenuDisplayPlayerControls, &data->PlayerUID); }
void PlayerSelectMenusCreate( PlayerSelectMenu *menu, int numPlayers, int player, Character *c, struct PlayerData *pData, EventHandlers *handlers, GraphicsDevice *graphics, InputConfig *inputConfig, const NameGen *ng) { MenuSystem *ms = &menu->ms; PlayerSelectMenuData *data = &menu->data; struct PlayerData *p = pData; Vec2i pos = Vec2iZero(); Vec2i size = Vec2iZero(); int w = graphics->cachedConfig.Res.x; int h = graphics->cachedConfig.Res.y; data->nameMenuSelection = (int)strlen(letters); data->display.c = c; data->display.currentMenu = &ms->current; data->display.pData = pData; data->controls.inputConfig = inputConfig; data->controls.pData = pData; data->nameGenerator = ng; switch (numPlayers) { case 1: // Single menu, entire screen pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; case 2: // Two menus, side by side pos = Vec2iNew(player * w / 2 + w / 4, 0); size = Vec2iNew(w / 4, h); break; case 3: case 4: // Four corners pos = Vec2iNew((player & 1) * w / 2 + w / 4, (player / 2) * h / 2); size = Vec2iNew(w / 4, h / 2); break; default: assert(0 && "not implemented"); break; } MenuSystemInit(ms, handlers, graphics, pos, size); ms->align = MENU_ALIGN_LEFT; ms->root = ms->current = MenuCreateNormal( "", "", MENU_TYPE_NORMAL, 0); MenuAddSubmenu( ms->root, MenuCreateCustom( "Name", DrawNameMenu, HandleInputNameMenu, data)); MenuAddSubmenu(ms->root, CreateCustomizeMenu("Customize...", data, c, p)); MenuAddSubmenu( ms->root, MenuCreateVoidFunc("Shuffle", ShuffleAppearance, data)); MenuAddSubmenu(ms->root, CreateUseTemplateMenu("Load", data)); MenuAddSubmenu(ms->root, CreateSaveTemplateMenu("Save", data)); MenuAddSubmenu(ms->root, MenuCreateSeparator("")); MenuAddSubmenu( ms->root, MenuCreateNormal("Done", "", MENU_TYPE_NORMAL, 0)); MenuAddExitType(ms, MENU_TYPE_RETURN); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayer, data); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayerControls, &data->controls); // Detect when there have been new player templates created, // to re-enable the load menu CheckReenableLoadMenu(ms->root, NULL); MenuSetPostEnterFunc(ms->root, CheckReenableLoadMenu, NULL); SetPlayer(c, pData); }
void PlayerSelectMenusCreate( PlayerSelectMenu *menu, int numPlayers, int player, const int playerUID, EventHandlers *handlers, GraphicsDevice *graphics, const NameGen *ng) { MenuSystem *ms = &menu->ms; PlayerSelectMenuData *data = &menu->data; Vec2i pos, size; int w = graphics->cachedConfig.Res.x; int h = graphics->cachedConfig.Res.y; data->nameMenuSelection = (int)strlen(letters); data->display.PlayerUID = playerUID; data->display.currentMenu = &ms->current; data->PlayerUID = playerUID; data->nameGenerator = ng; switch (numPlayers) { case 1: // Single menu, entire screen pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; case 2: // Two menus, side by side pos = Vec2iNew(player * w / 2 + w / 4, 0); size = Vec2iNew(w / 4, h); break; case 3: case 4: // Four corners pos = Vec2iNew((player & 1) * w / 2 + w / 4, (player / 2) * h / 2); size = Vec2iNew(w / 4, h / 2); break; default: CASSERT(false, "not implemented"); pos = Vec2iNew(w / 2, 0); size = Vec2iNew(w / 2, h); break; } MenuSystemInit(ms, handlers, graphics, pos, size); ms->align = MENU_ALIGN_LEFT; ms->root = ms->current = MenuCreateNormal( "", "", MENU_TYPE_NORMAL, 0); MenuAddSubmenu( ms->root, MenuCreateCustom( "Name", DrawNameMenu, HandleInputNameMenu, data)); MenuAddSubmenu( ms->root, CreateCustomizeMenu("Customize...", data, playerUID)); MenuAddSubmenu( ms->root, MenuCreateVoidFunc("Shuffle", ShuffleAppearance, data)); MenuAddSubmenu(ms->root, CreateUseTemplateMenu("Load", data)); MenuAddSubmenu(ms->root, CreateSaveTemplateMenu("Save", data)); MenuAddSubmenu(ms->root, MenuCreateSeparator("")); MenuAddSubmenu( ms->root, MenuCreateNormal("Done", "", MENU_TYPE_NORMAL, 0)); // Select "Done" ms->root->u.normal.index = (int)ms->root->u.normal.subMenus.size - 1; MenuAddExitType(ms, MENU_TYPE_RETURN); MenuSystemAddCustomDisplay(ms, MenuDisplayPlayer, data); MenuSystemAddCustomDisplay( ms, MenuDisplayPlayerControls, &data->PlayerUID); // Detect when there have been new player templates created, // to re-enable the load menu CheckReenableLoadMenu(ms->root, NULL); MenuSetPostEnterFunc(ms->root, CheckReenableLoadMenu, NULL, false); PlayerData *p = PlayerDataGetByUID(playerUID); CharacterSetColors(&p->Char); }