You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

476 lines
11 KiB

#include "../../types.h"
int selhero_SaveCount = 0;
_uiheroinfo heros[MAX_CHARACTERS];
_uiheroinfo heroInfo;
static std::vector<_uiheroinfo> hero_infos;
static BOOL __stdcall ui_add_hero_info(_uiheroinfo *info)
{
hero_infos.emplace_back(*info);
return TRUE;
}
void RenderStats()
{
char lvl[3] = "--";
char str[3] = "--";
char mag[3] = "--";
char dex[3] = "--";
char vit[3] = "--";
if (heroInfo.heroclass != UI_NUM_CLASSES) {
sprintf(lvl, "%d", heroInfo.level);
sprintf(str, "%d", heroInfo.strength);
sprintf(mag, "%d", heroInfo.magic);
sprintf(dex, "%d", heroInfo.dexterity);
sprintf(vit, "%d", heroInfo.vitality);
}
PrintText16Silver(31, 323, "Level:", JustRight, 118);
PrintText16Silver(149, 323, lvl, JustCentre, 61);
PrintText16Silver(31, 358, "Strength:", JustRight, 118);
PrintText16Silver(149, 358, str, JustCentre, 61);
PrintText16Silver(31, 380, "Magic:", JustRight, 118);
PrintText16Silver(149, 380, mag, JustCentre, 61);
PrintText16Silver(31, 401, "Dexterity:", JustRight, 118);
PrintText16Silver(149, 401, dex, JustCentre, 61);
PrintText16Silver(31, 422, "Vitality:", JustRight, 118);
PrintText16Silver(149, 422, vit, JustCentre, 61);
}
void selhero_Render()
{
heroInfo.heroclass = UI_NUM_CLASSES;
if (SelectedItem <= selhero_SaveCount) {
memcpy(&heroInfo, &heros[SelectedItem - 1], sizeof(heroInfo));
}
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
PrintText30Silver(-1, 161, "Single Player Characters", JustCentre);
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage);
RenderStats();
int w = 369;
int x = 241;
PrintText30Silver(x - 1, 211, "Select Hero", JustCentre, w);
int selectorTop = 256;
int y = selectorTop;
for (int i = 0; i < selhero_SaveCount; i++) {
PrintText24Gold(x - 1, y, heros[i].name, JustCentre, w);
y += 26;
}
PrintText24Gold(x - 1, y, "New Hero", JustCentre, w);
DrawSelector16(x, selectorTop + 3, w, 32, 26);
PrintText30Gold(279, 429, "OK");
PrintText30Gold(378, 429, "Delete");
PrintText30Gold(501, 429, "Cancel");
}
void selhero_Render_DifficultySelection()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage);
RenderStats();
char *GameOptions[3] = { "Normal", "Nightmare", "Hell" };
// this should not be hard coded.
int x = 280;
int y = 256;
for (int i = 0; i < 3; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
}
}
void selhero_Render_GameType()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage);
RenderStats();
char *GameOptions[2] = { "New Game", "Load Game" };
// this should not be hard coded.
int x = 280;
int y = 256;
for (int i = 0; i < 2; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
}
}
void selhero_Render_Name()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage);
RenderStats();
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 318;
PrintText30Silver(x - 1, 211, "Enter Name", JustCentre, w);
DrawSelector(x, y - 2, w, 39, 26);
char lable[16];
strcpy(lable, heroInfo.name);
if (GetAnimationFrame(2, 500)) {
lable[strlen(lable)] = '|';
}
PrintText24Gold(x + 67, y, lable); // todo add blinking "|"
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "Cancel");
}
// Have this load the function above and then render it in the main menu.
// Cnacel box is also needed.
void selhero_Render_ClassSelector()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage);
RenderStats();
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 285;
PrintText30Silver(x - 1, 211, "Choose Class", JustCentre, w);
char *heroclasses[3] = { "Warrior", "Rogue", "Sorcerer" };
int selectorTop = y;
for (int i = 0; i < 3; i++) {
if (i > 1) {
y += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
PrintText24Gold(x - 1, y, heroclasses[i], JustCentre, w);
y += 33;
}
if (SelectedItem > 1) {
selectorTop += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
DrawSelector(x, selectorTop - 2, w, 39, 33);
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "Cancel");
}
BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo)
{
heros[selhero_SaveCount] = *pInfo;
selhero_SaveCount++;
return TRUE;
}
void selhero_Loade(BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)))
{
LoadTitelArt("ui_art\\selhero.pcx");
hero_infos.clear();
fninfo(ui_add_hero_info);
selhero_SaveCount = 0;
fninfo(SelHero_GetHeroInfo);
//memset(heroInfo, 0, sizeof(_uiheroinfo));
heroInfo.heroclass = UI_NUM_CLASSES;
}
void selhero_Free()
{
mem_free_dbg(pPcxTitleImage);
pPcxTitleImage = NULL;
}
void selhero_setDefaultStats(BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *))
{
_uidefaultstats defaults;
fnstats(SelectedItem - 1, &defaults);
heroInfo.heroclass = SelectedItem - 1;
heroInfo.strength = defaults.strength;
heroInfo.magic = defaults.magic;
heroInfo.dexterity = defaults.dexterity;
heroInfo.vitality = defaults.vitality;
}
BOOL __stdcall UiSelHeroSingDialog(
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)),
BOOL(__stdcall *fncreate)(_uiheroinfo *),
BOOL(__stdcall *fnremove)(_uiheroinfo *),
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult,
char *name,
int *difficulty)
{
selhero_Loade(fninfo);
MenuItem[SINGLEPLAYER_LOAD] = 1 + selhero_SaveCount;
submenu = SINGLEPLAYER_LOAD;
if (!selhero_SaveCount) {
PreviousItem[SINGLEPLAYER_CLASSES] = 0;
submenu = SINGLEPLAYER_CLASSES;
}
SelectedItem = 1;
SelectedItemMax = MenuItem[submenu];
int nameLen;
SDL_Event event;
int x, y;
*difficulty = gnDifficulty; // BUGFIX this replicates a bug that allowed setting deficulity in SP
bool endMenu = false;
while (!endMenu) {
CapFPS();
switch (submenu) {
case SINGLEPLAYER_LOAD:
selhero_Render();
break;
case SINGLEPLAYER_CLASSES:
selhero_setDefaultStats(fnstats);
selhero_Render_ClassSelector();
break;
case SINGLEPLAYER_NAME:
selhero_Render_Name();
break;
}
DrawMouse();
UiFadeIn();
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
if (PreviousItem[submenu]) {
SetMenu(PreviousItem[submenu]);
break;
}
*dlgresult = EXIT_MENU;
endMenu = true;
break;
case SDLK_BACKSPACE:
nameLen = strlen(heroInfo.name);
if (nameLen > 0) {
heroInfo.name[nameLen-1] = '\0';
}
break;
case SDLK_UP:
SelectedItem--;
if (SelectedItem < 1) {
SelectedItem = SelectedItemMax ? SelectedItemMax : 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_DOWN:
SelectedItem++;
if (SelectedItem > SelectedItemMax) {
SelectedItem = 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
case SDLK_SPACE:
switch (submenu) {
case SINGLEPLAYER_LOAD:
if (SelectedItem == SelectedItemMax) {
memset(&heroInfo.name, 0, sizeof(heroInfo.name));
SetMenu(SINGLEPLAYER_CLASSES);
break;
}
strcpy(name, heroInfo.name);
*dlgresult = LOAD_GAME;
endMenu = true;
break;
case SINGLEPLAYER_CLASSES:
SetMenu(SINGLEPLAYER_NAME);
break;
case SINGLEPLAYER_NAME:
if (!heroInfo.hassaved) {
fncreate(&heroInfo);
}
strcpy(name, heroInfo.name);
endMenu = true;
break;
}
break;
default:
if (submenu != SINGLEPLAYER_NAME) {
break;
}
char letter = event.key.keysym.sym;
if (int(letter) > 96 && int(letter) < 123 || int(letter) == 32)
nameLen = strlen(heroInfo.name);
if (nameLen < 15) {
heroInfo.name[nameLen] = letter;
}
break;
}
break;
case SDL_QUIT:
exit(0);
}
}
}
BlackPalette();
selhero_Free();
return TRUE;
}
BOOL __stdcall UiSelHeroMultDialog(
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)),
BOOL(__stdcall *fncreate)(_uiheroinfo *),
BOOL(__stdcall *fnremove)(_uiheroinfo *),
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult,
int *hero_is_created,
char *name)
{
selhero_Loade(fninfo);
DUMMY();
submenu = MULTIPLAYER_LOBBY;
SelectedItem = 1;
SelectedItemMax = MenuItem[submenu];
SDL_Event event;
int endMenu = false;
while (endMenu == false) {
CapFPS();
switch (submenu) {
case MULTIPLAYER_LOBBY:
selhero_Render_GameType();
break;
case MULTIPLAYER_DIFFICULTY:
selhero_Render_DifficultySelection();
break;
}
DrawMouse();
UiFadeIn();
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
if (PreviousItem[submenu]) {
SetMenu(PreviousItem[submenu]);
break;
}
*dlgresult = EXIT_MENU;
return TRUE;
case SDLK_UP:
SelectedItem--;
if (SelectedItem < 1) {
SelectedItem = SelectedItemMax ? SelectedItemMax : 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_DOWN:
SelectedItem++;
if (SelectedItem > SelectedItemMax) {
SelectedItem = 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
case SDLK_SPACE:
switch (submenu) {
case MULTIPLAYER_LOBBY:
SetMenu(MULTIPLAYER_DIFFICULTY);
break;
case MULTIPLAYER_DIFFICULTY:
strcpy(heroInfo.name, "testname");
strcpy(name, heroInfo.name);
if (!heroInfo.hassaved) {
fncreate(&heroInfo);
}
*dlgresult = NEW_GAME;
endMenu = true;
break;
}
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
SDL_Rect CreateHeroCancelBox;
CreateHeroCancelBox.y = 550;
CreateHeroCancelBox.x = 675;
CreateHeroCancelBox.w = 100;
CreateHeroCancelBox.h = 30;
switch (submenu) {
case MULTIPLAYER_DIFFICULTY:
SDL_Rect NormalSelectBox;
NormalSelectBox.x = 280;
NormalSelectBox.y = 350;
NormalSelectBox.w = 300;
NormalSelectBox.h = 30;
if (IsInsideRect(&event, &NormalSelectBox)) {
strcpy(name, heroInfo.name);
gnDifficulty = DIFF_NORMAL;
*dlgresult = LOAD_GAME;
}
break;
}
}
break;
case SDL_QUIT:
exit(0);
}
}
}
BlackPalette();
selhero_Free();
return TRUE;
}