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.
587 lines
14 KiB
587 lines
14 KiB
#include "../../types.h" |
|
|
|
int HeroChosen = 0; |
|
bool StartNewGame = false; |
|
bool timestart = false; |
|
bool CreateSinglePlayerChar = false; |
|
char chr_name_str[16]; |
|
int NewHeroNameIndex = 0; |
|
|
|
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, char *str, char *mag, char *dex, char *vit) |
|
{ |
|
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 RenderDefaultStats(int HeroClass) |
|
{ |
|
switch (HeroClass) { |
|
case UI_WARRIOR: |
|
RenderStats("1", "30", "10", "20", "25"); |
|
break; |
|
case UI_ROGUE: |
|
RenderStats("1", "20", "15", "30", "20"); |
|
break; |
|
case UI_SORCERER: |
|
RenderStats("1", "15", "35", "15", "20"); |
|
break; |
|
} |
|
} |
|
|
|
void selhero_Render() |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 3, pPcxHeroImage); |
|
|
|
PrintText30Silver(-1, 161, "Single Player Characters", JustCentre); |
|
|
|
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 < 0; i++) { |
|
PrintText24Gold(x - 1, y, "Hero name", JustCentre, w); |
|
y += 26; |
|
} |
|
PrintText24Gold(x - 1, y, "New Hero", JustCentre, w); |
|
|
|
DrawSelector16(x, selectorTop + 3, w, 32, 26); |
|
|
|
RenderStats("--", "--", "--", "--", "--"); |
|
|
|
PrintText30Gold(279, 429, "OK"); |
|
PrintText30Gold(378, 429, "Delete"); |
|
PrintText30Gold(501, 429, "Cancel"); |
|
} |
|
|
|
void selhero_Render_DifficultySelection(int HeroClass, int ShowClasses) |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage); |
|
|
|
RenderStats("1", "30", "10", "20", "25"); |
|
|
|
char *GameOptions[3] = { "Normal", "Nightmare", "Hell" }; |
|
|
|
// this should not be hard coded. |
|
int x = 280; |
|
int y = 256; |
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage); |
|
|
|
if (ShowClasses == 1) { |
|
for (int i = 0; i < 3; i++) { |
|
y += 40; |
|
PrintText16Silver(x, y, GameOptions[i]); |
|
} |
|
} |
|
|
|
RenderDefaultStats(HeroClass); |
|
} |
|
|
|
void selhero_Render_GameType(int HeroClass, int ShowClasses) |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage); |
|
|
|
char *GameOptions[2] = { "New Game", "Load Game" }; |
|
|
|
// this should not be hard coded. |
|
int x = 280; |
|
int y = 256; |
|
|
|
if (ShowClasses == 1) { |
|
for (int i = 0; i < 2; i++) { |
|
y += 40; |
|
PrintText16Silver(x, y, GameOptions[i]); |
|
} |
|
} |
|
|
|
RenderDefaultStats(HeroClass); |
|
} |
|
|
|
void selhero_Render_Name(int HeroClass) |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage); |
|
|
|
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); |
|
|
|
RenderDefaultStats(HeroClass); |
|
|
|
DrawSelector(x, y - 2, w, 39, 26); |
|
PrintText24Gold(x + 67, y, (char *)HeroUndecidedName); // 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, SelectedItem - 1, pPcxHeroImage); |
|
|
|
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); |
|
|
|
RenderDefaultStats(SelectedItem - 1); |
|
|
|
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"); |
|
} |
|
|
|
void selhero_Loade() |
|
{ |
|
LoadTitelArt("ui_art\\selhero.pcx"); |
|
} |
|
|
|
void selhero_Free() |
|
{ |
|
mem_free_dbg(pPcxTitleImage); |
|
pPcxTitleImage = NULL; |
|
} |
|
|
|
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(); |
|
|
|
submenu = SINGLEPLAYER_LOAD; |
|
if (!TotalPlayers) { |
|
PreviousItem[SINGLEPLAYER_CLASSES] = 0; |
|
submenu = SINGLEPLAYER_CLASSES; |
|
} |
|
|
|
SelectedItem = 1; |
|
SelectedItemMax = MenuItem[submenu]; |
|
SDL_Event event; |
|
int x, y; |
|
|
|
bool endMenu = false; |
|
while (!endMenu) { |
|
switch (submenu) { |
|
case SINGLEPLAYER_LOAD: |
|
selhero_Render(); |
|
break; |
|
case SINGLEPLAYER_CLASSES: |
|
selhero_Render_ClassSelector(); |
|
break; |
|
case SINGLEPLAYER_NAME: |
|
selhero_Render_Name(HeroChosen); |
|
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 = 4; |
|
endMenu = true; |
|
break; |
|
case SDLK_BACKSPACE: |
|
if (NewHeroNameIndex > 0) { |
|
HeroUndecidedName[NewHeroNameIndex - 1] = 0; |
|
NewHeroNameIndex--; |
|
} |
|
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) { |
|
SetMenu(SINGLEPLAYER_CLASSES); |
|
} |
|
break; |
|
case SINGLEPLAYER_CLASSES: |
|
HeroChosen = SelectedItem - 1; |
|
for (int i = 0; i < 17; i++) |
|
HeroUndecidedName[i] = 0; |
|
NewHeroNameIndex = 0; |
|
SetMenu(SINGLEPLAYER_NAME); |
|
break; |
|
case SINGLEPLAYER_NAME: |
|
CreateSinglePlayerChar = 1; |
|
const char *test_name = HeroUndecidedName; |
|
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) |
|
|
|
if (NewHeroNameIndex < 17) { |
|
HeroUndecidedName[NewHeroNameIndex] = letter; |
|
NewHeroNameIndex++; |
|
} |
|
break; |
|
} |
|
break; |
|
case SDL_MOUSEBUTTONDOWN: |
|
if (event.button.button == SDL_BUTTON_LEFT) { |
|
x = event.button.x; |
|
y = event.button.y; |
|
printf("X %d , Y %d\n", x, y); |
|
|
|
SDL_Rect CreateHeroCancelBox; |
|
CreateHeroCancelBox.y = 550; |
|
CreateHeroCancelBox.x = 675; |
|
CreateHeroCancelBox.w = 100; |
|
CreateHeroCancelBox.h = 30; |
|
|
|
clock_t start, end; |
|
double cpu_time_used; |
|
|
|
switch (submenu) { |
|
case SINGLEPLAYER_NAME: |
|
if (IsInsideRect(&event, &CreateHeroCancelBox)) { |
|
memset(HeroUndecidedName, 0, 17); |
|
NewHeroNameIndex = 0; |
|
SetMenu(SINGLEPLAYER_CLASSES); |
|
} |
|
break; |
|
} |
|
} |
|
break; |
|
case SDL_QUIT: |
|
exit(0); |
|
} |
|
} |
|
|
|
CapFPS(); |
|
} |
|
BlackPalette(); |
|
|
|
if (*dlgresult != 4) { |
|
hero_infos.clear(); |
|
fninfo(&ui_add_hero_info); |
|
|
|
if (CreateSinglePlayerChar) { |
|
const char *test_name = HeroUndecidedName; |
|
DUMMY_PRINT("create hero: %s", test_name); |
|
strcpy(name, test_name); |
|
|
|
_uiheroinfo hero_info = { 1 }; |
|
strcpy(hero_info.name, test_name); |
|
hero_info.heroclass = HeroChosen; |
|
|
|
fncreate(&hero_info); |
|
} else { |
|
*difficulty = gnDifficulty; // BUGFIX this replicates a bug that allowed setting deficulity in SP |
|
printf("Difficulty : %d \n", *difficulty); |
|
|
|
const char *test_name = chr_name_str; |
|
if (!StartNewGame) { |
|
*dlgresult = 2; // This means load game |
|
} |
|
strcpy(name, test_name); |
|
} |
|
} |
|
|
|
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(); |
|
|
|
DUMMY(); |
|
submenu = MULTIPLAYER_LOBBY; |
|
|
|
SelectedItem = 1; |
|
SelectedItemMax = MenuItem[submenu]; |
|
SDL_Event event; |
|
|
|
int endMenu = false; |
|
while (endMenu == false) { |
|
switch (submenu) { |
|
case MULTIPLAYER_LOBBY: |
|
selhero_Render_GameType(HeroChosen, 1); |
|
break; |
|
case MULTIPLAYER_DIFFICULTY: |
|
selhero_Render_DifficultySelection(HeroChosen, 1); |
|
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 = 4; |
|
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: |
|
CreateSinglePlayerChar = 1; |
|
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; |
|
|
|
clock_t start, end; |
|
double cpu_time_used; |
|
|
|
switch (submenu) { |
|
case 5: |
|
if (timestart == 0) { |
|
start = clock(); |
|
timestart = 1; |
|
} |
|
|
|
end = clock(); |
|
|
|
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; |
|
|
|
printf("TIEM DELAY %f\n", cpu_time_used); |
|
|
|
SDL_Rect NewGameBox; |
|
NewGameBox.y = 350; |
|
NewGameBox.x = 280; |
|
NewGameBox.w = 300; |
|
NewGameBox.h = 30; |
|
|
|
SDL_Rect LoadGameBox; |
|
LoadGameBox.y = 392; |
|
LoadGameBox.x = 280; |
|
LoadGameBox.w = 300; |
|
LoadGameBox.h = 30; |
|
|
|
if (cpu_time_used > 0.5 && IsInsideRect(&event, &NewGameBox)) { |
|
printf(" New Game I was hit\n\n\n"); |
|
SetMenu(MULTIPLAYER_DIFFICULTY); |
|
cpu_time_used = 0; |
|
timestart = 0; |
|
start = 0; |
|
} else if (cpu_time_used > 0.5 && IsInsideRect(&event, &LoadGameBox)) { |
|
|
|
printf(" Load Game I was hit\n\n\n"); |
|
break; |
|
} else if (IsInsideRect(&event, &CreateHeroCancelBox)) { |
|
timestart = 0; |
|
cpu_time_used = 0; |
|
start = 0; |
|
end = 0; |
|
cpu_time_used = 0; |
|
|
|
SetMenu(SINGLEPLAYER_CLASSES); // TODO skip to main menu if no valid saves |
|
} |
|
break; |
|
case MULTIPLAYER_DIFFICULTY: |
|
if (timestart == 0) { |
|
start = clock(); |
|
timestart = 1; |
|
} |
|
|
|
end = clock(); |
|
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; |
|
|
|
SDL_Rect NormalSelectBox; |
|
NormalSelectBox.x = 280; |
|
NormalSelectBox.y = 350; |
|
NormalSelectBox.w = 300; |
|
NormalSelectBox.h = 30; |
|
|
|
SDL_Rect NightmareSelectBox; |
|
NightmareSelectBox.x = 280; |
|
NightmareSelectBox.y = 392; |
|
NightmareSelectBox.w = 300; |
|
NightmareSelectBox.h = 30; |
|
|
|
SDL_Rect HellSelectBox; |
|
HellSelectBox.x = 280; |
|
HellSelectBox.y = 428; |
|
HellSelectBox.w = 300; |
|
HellSelectBox.h = 30; |
|
|
|
if (cpu_time_used > 0.5 && IsInsideRect(&event, &NormalSelectBox)) { |
|
StartNewGame = 1; |
|
gnDifficulty = DIFF_NORMAL; |
|
break; |
|
} else if (cpu_time_used > 0.5 && IsInsideRect(&event, &NightmareSelectBox)) { |
|
StartNewGame = 1; |
|
gnDifficulty = DIFF_NIGHTMARE; |
|
break; |
|
} else if (cpu_time_used > 1 && IsInsideRect(&event, &HellSelectBox)) { |
|
gnDifficulty = DIFF_HELL; |
|
StartNewGame = 1; |
|
break; |
|
} else if (IsInsideRect(&event, &CreateHeroCancelBox)) { |
|
timestart = 0; |
|
cpu_time_used = 0; |
|
start = 0; |
|
end = 0; |
|
cpu_time_used = 0; |
|
|
|
printf("Cancel\n\n\n"); |
|
SetMenu(MULTIPLAYER_LOBBY); |
|
} |
|
break; |
|
} |
|
} |
|
break; |
|
case SDL_QUIT: |
|
exit(0); |
|
} |
|
} |
|
|
|
CapFPS(); |
|
} |
|
BlackPalette(); |
|
|
|
hero_infos.clear(); |
|
fninfo(&ui_add_hero_info); |
|
|
|
if (CreateSinglePlayerChar) { |
|
strcpy(name, "testname"); |
|
DUMMY_PRINT("create hero: %s", name); |
|
|
|
_uiheroinfo hero_info = { 1 }; |
|
strcpy(hero_info.name, name); |
|
hero_info.heroclass = HeroChosen; |
|
|
|
fncreate(&hero_info); |
|
} |
|
|
|
selhero_Free(); |
|
|
|
return TRUE; |
|
}
|
|
|