diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index d1969a717..37ed22270 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -552,6 +552,9 @@ const char *keyw[] = "screensound", // 372 "getmusicposition", // 373 "setmusicposition", // 374 + "undefinevolume", // 375 + "undefineskill", // 376 + "undefinelevel", // 377 "" }; #endif @@ -2219,6 +2222,59 @@ void C_DefineGameType(int32_t idx, int32_t flags, const char *name) } #endif +void C_UndefineVolume(int32_t vol) +{ + Bassert((unsigned)vol < MAXVOLUMES); + + EpisodeNames[vol][0] = '\0'; + + g_numVolumes = 0; + for (int32_t i = MAXVOLUMES-1; i >= 0; i--) + { + if (EpisodeNames[i][0]) + { + g_numVolumes = i+1; + break; + } + } +} + +void C_UndefineSkill(int32_t skill) +{ + Bassert((unsigned)skill < MAXSKILLS); + + SkillNames[skill][0] = '\0'; + + g_numSkills = 0; + for (int32_t i = MAXSKILLS-1; i >= 0; i--) + { + if (SkillNames[i][0]) + { + g_numSkills = i+1; + break; + } + } +} + +void C_UndefineLevel(int32_t vol, int32_t lev) +{ + Bassert((unsigned)vol < MAXVOLUMES); + Bassert((unsigned)lev < MAXLEVELS); + + { + map_t *const map = &MapInfo[(MAXLEVELS*vol)+lev]; + + Bfree(map->filename); + map->filename = NULL; + + Bfree(map->name); + map->name = NULL; + + map->partime = 0; + map->designertime = 0; + } +} + LUNATIC_EXTERN int32_t C_SetDefName(const char *name) { clearDefNamePtr(); @@ -5242,6 +5298,72 @@ repeatcase: C_NextLine(); continue; + + case CON_UNDEFINELEVEL: + g_scriptPtr--; + C_GetNextValue(LABEL_DEFINE); + g_scriptPtr--; + j = *g_scriptPtr; + C_GetNextValue(LABEL_DEFINE); + g_scriptPtr--; + k = *g_scriptPtr; + + if (EDUKE32_PREDICT_FALSE((unsigned)j > MAXVOLUMES-1)) + { + initprintf("%s:%d: error: volume number exceeds maximum volume count.\n",g_szScriptFileName,g_lineNumber); + g_numCompilerErrors++; + C_NextLine(); + continue; + } + if (EDUKE32_PREDICT_FALSE((unsigned)k > MAXLEVELS-1)) + { + initprintf("%s:%d: error: level number exceeds maximum number of levels per episode.\n",g_szScriptFileName,g_lineNumber); + g_numCompilerErrors++; + C_NextLine(); + continue; + } + + C_UndefineLevel(j, k); + continue; + + case CON_UNDEFINESKILL: + g_scriptPtr--; + + C_GetNextValue(LABEL_DEFINE); + g_scriptPtr--; + j = *g_scriptPtr; + + if (EDUKE32_PREDICT_FALSE((unsigned)j >= MAXSKILLS)) + { + initprintf("%s:%d: error: skill number exceeds maximum skill count %d.\n", + g_szScriptFileName,g_lineNumber, MAXSKILLS); + g_numCompilerErrors++; + C_NextLine(); + continue; + } + + C_UndefineSkill(j); + continue; + + case CON_UNDEFINEVOLUME: + g_scriptPtr--; + + C_GetNextValue(LABEL_DEFINE); + g_scriptPtr--; + j = *g_scriptPtr; + + if (EDUKE32_PREDICT_FALSE((unsigned)j > MAXVOLUMES-1)) + { + initprintf("%s:%d: error: volume number exceeds maximum volume count.\n", + g_szScriptFileName,g_lineNumber); + g_numCompilerErrors++; + C_NextLine(); + continue; + } + + C_UndefineVolume(j); + continue; + case CON_DEFINEVOLUMENAME: g_scriptPtr--; diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h index 3b9df58e5..3e35fda6d 100644 --- a/polymer/eduke32/source/gamedef.h +++ b/polymer/eduke32/source/gamedef.h @@ -115,10 +115,13 @@ void C_DefineMusic(int32_t vol, int32_t lev, const char *fn); void C_DefineSound(int32_t sndidx, const char *fn, int32_t args[5]); void C_DefineQuote(int32_t qnum, const char *qstr); void C_DefineVolumeName(int32_t vol, const char *name); +void C_UndefineVolume(int32_t vol); void C_DefineSkillName(int32_t skill, const char *name); +void C_UndefineSkill(int32_t skill); void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, int32_t partime, int32_t designertime, const char *levelname); +void C_UndefineLevel(int32_t vol, int32_t lev); void C_DefineGameFuncName(int32_t idx, const char *name); void C_DefineGameType(int32_t idx, int32_t flags, const char *name); int32_t C_SetDefName(const char *name); @@ -976,6 +979,9 @@ enum ScriptKeywords_t CON_SCREENSOUND, // 372 CON_GETMUSICPOSITION, // 373 CON_SETMUSICPOSITION, // 374 + CON_UNDEFINEVOLUME, // 375 + CON_UNDEFINESKILL, // 376 + CON_UNDEFINELEVEL, // 377 CON_END }; // KEEPINSYNC with the keyword list in lunatic/con_lang.lua diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index f1077339e..838525561 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -937,6 +937,9 @@ lpeg.P(false) + "useractor" + "updatesectorz" + "updatesector" + +"undefinevolume" + +"undefineskill" + +"undefinelevel" + "tossweapon" + "tip" + "time" + diff --git a/polymer/eduke32/source/lunatic/defs.ilua b/polymer/eduke32/source/lunatic/defs.ilua index 9d3b397e9..62c0ca626 100644 --- a/polymer/eduke32/source/lunatic/defs.ilua +++ b/polymer/eduke32/source/lunatic/defs.ilua @@ -742,10 +742,13 @@ int32_t C_DefineSound(int32_t sndidx, const char *fn, int32_t args [5]); void C_DefineMusic(int32_t vol, int32_t lev, const char *fn); void C_DefineQuote(int32_t qnum, const char *qstr); void C_DefineVolumeName(int32_t vol, const char *name); +void C_UndefineVolume(int32_t vol); void C_DefineSkillName(int32_t skill, const char *name); +void C_UndefineSkill(int32_t skill); void C_DefineLevelName(int32_t vol, int32_t lev, const char *fn, int32_t partime, int32_t designertime, const char *levelname); +void C_UndefineLevel(int32_t vol, int32_t lev); void C_DefineProjectile(int32_t j, int32_t what, int32_t val); void C_DefineGameFuncName(int32_t idx, const char *name); void C_DefineGameType(int32_t idx, int32_t flags, const char *name); diff --git a/polymer/eduke32/source/lunatic/dynsymlist b/polymer/eduke32/source/lunatic/dynsymlist index 7ef619ad9..7438474d5 100644 --- a/polymer/eduke32/source/lunatic/dynsymlist +++ b/polymer/eduke32/source/lunatic/dynsymlist @@ -143,8 +143,11 @@ C_DefineSound; C_DefineMusic; C_DefineQuote; C_DefineVolumeName; +C_UndefineVolume; C_DefineSkillName; +C_UndefineSkill; C_DefineLevelName; +C_UndefineLevel; C_DefineProjectile; C_DefineGameFuncName; C_DefineGameType; diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 655c1516c..96284399c 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1215,8 +1215,23 @@ function Cmd.definelevelname(vol, lev, fn, ptstr, dtstr, levname) g_data.level[EPMUL*vol+lev] = map end +function Cmd.undefinelevel(vol, lev) + if (not (vol >= 0 and vol < conl.MAXVOLUMES)) then + errprintf("volume number exceeds maximum volume count.") + return + end + + if (not (lev >= 0 and lev < conl.MAXLEVELS)) then + errprintf("level number exceeds maximum number of levels per episode.") + return + end + + if (ffi) then + ffiC.C_UndefineLevel(vol, lev) + end +end + local function defineXname(what, ffiCfuncname, X, name) - name = name:upper() if (ffi) then ffiC[ffiCfuncname](X, name) if (#name > 32) then @@ -1236,6 +1251,17 @@ function Cmd.defineskillname(skillnum, name) g_data.skillname[skillnum] = name end +function Cmd.undefineskill(skillnum) + if (not (skillnum >= 0 and skillnum < conl.MAXSKILLS)) then + errprintf("skill number is negative or exceeds maximum skill count.") + return + end + + if (ffi) then + ffiC.C_UndefineSkill(skillnum) + end +end + function Cmd.definevolumename(vol, name) if (not (vol >= 0 and vol < conl.MAXVOLUMES)) then errprintf("volume number is negative or exceeds maximum volume count.") @@ -1246,6 +1272,17 @@ function Cmd.definevolumename(vol, name) g_data.volname[vol] = name end +function Cmd.undefinevolume(vol) + if (not (vol >= 0 and vol < conl.MAXVOLUMES)) then + errprintf("volume number is negative or exceeds maximum volume count.") + return + end + + if (ffi) then + ffiC.C_UndefineVolume(vol) + end +end + function Cmd.definegamefuncname(idx, name) local NUMGAMEFUNCTIONS = (ffi and ffiC.NUMGAMEFUNCTIONS or 56) if (not (idx >= 0 and idx < NUMGAMEFUNCTIONS)) then @@ -1861,6 +1898,13 @@ local Couter = { music = sp1 * tok.define * match_until(sp1 * tok.filename, sp1 * conl.keyword * sp1) / Cmd.music, + undefinelevel = cmd(D,D) + / Cmd.undefinelevel, + undefineskill = cmd(D) + / Cmd.undefineskill, + undefinevolume = cmd(D) + / Cmd.undefinevolume, + --- 3. Game Settings -- gamestartup has 26/30 fixed defines, depending on 1.3D/1.5 version: gamestartup = (sp1 * tok.define)^26 diff --git a/polymer/eduke32/source/menus.c b/polymer/eduke32/source/menus.c index 87c49ad14..271ad7559 100644 --- a/polymer/eduke32/source/menus.c +++ b/polymer/eduke32/source/menus.c @@ -1237,6 +1237,8 @@ void M_Init(void) MEOS_NETOPTIONS_EPISODE.numOptions = g_numVolumes + 1; // k+1; MEOSN_NetEpisodes[g_numVolumes] = MenuUserMap; MMF_Top_Episode.pos.y = (48-(g_numVolumes*2))<<16; + if (g_numSkills == 0) + MEO_EPISODE.linkID = MENU_NULL; // prepare skills k = -1; @@ -2218,6 +2220,24 @@ static void M_MenuEntryFocus(/*MenuEntry_t *entry*/) } } +static void M_StartGameWithoutSkill(void) +{ + ud.m_player_skill = M_SKILL.currentEntry+1; + + g_skillSoundVoice = S_PlaySound(PISTOL_BODYHIT); + + ud.m_respawn_monsters = 0; + + ud.m_monsters_off = ud.monsters_off = 0; + + ud.m_respawn_items = 0; + ud.m_respawn_inventory = 0; + + ud.multimode = 1; + + G_NewGame_EnterLevel(); +} + /* Functions where a "newValue" or similar is passed are run *before* the linked variable is actually changed. That way you can compare the new and old values and potentially block the change. @@ -2231,12 +2251,15 @@ static void M_MenuEntryLinkActivate(MenuEntry_t *entry) { ud.m_volume_number = M_EPISODE.currentEntry; ud.m_level_number = 0; + + if (g_numSkills == 0) + M_StartGameWithoutSkill(); } break; case MENU_SKILL: { - int32_t skillsound = 0; + int32_t skillsound = PISTOL_BODYHIT; switch (M_SKILL.currentEntry) { @@ -2254,9 +2277,10 @@ static void M_MenuEntryLinkActivate(MenuEntry_t *entry) break; } + ud.m_player_skill = M_SKILL.currentEntry+1; + g_skillSoundVoice = S_PlaySound(skillsound); - ud.m_player_skill = M_SKILL.currentEntry+1; if (M_SKILL.currentEntry == 3) ud.m_respawn_monsters = 1; else ud.m_respawn_monsters = 0; @@ -2881,7 +2905,11 @@ static void M_MenuFileSelect(int32_t input) { ud.m_volume_number = 0; ud.m_level_number = 7; - M_ChangeMenuAnimate(MENU_SKILL, MA_Advance); + + if (g_numSkills > 0) + M_ChangeMenuAnimate(MENU_SKILL, MA_Advance); + else + M_StartGameWithoutSkill(); } break; @@ -3077,9 +3105,23 @@ void M_ChangeMenu(MenuID_t cm) M_MenuFileSelectInit((MenuFileSelect_t*)m_currentMenu->object); else if (m_currentMenu->type == Menu) { - // MenuMenu_t *menu = (MenuMenu_t*)m_currentMenu->object; + MenuMenu_t *menu = (MenuMenu_t*)m_currentMenu->object; // MenuEntry_t* currentry = menu->entrylist[menu->currentEntry]; + // need this for MENU_SKILL + if (menu->currentEntry >= menu->numEntries) + menu->currentEntry = 0; + + i = menu->currentEntry; + while (!menu->entrylist[menu->currentEntry] || ((MenuEntry_t*)menu->entrylist[menu->currentEntry])->type == Spacer) + { + menu->currentEntry++; + if (menu->currentEntry >= menu->numEntries) + menu->currentEntry = 0; + if (menu->currentEntry == i) + G_GameExit("M_ChangeMenu: Attempted to change to a menu with no entries."); + } + M_MenuEntryFocus(/*currentry*/); } }