/* ** g_skill.cpp ** Skill level handling ** **--------------------------------------------------------------------------- ** Copyright 2008-2009 Christoph Oelckers ** Copyright 2008-2009 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** */ #include #include "doomstat.h" #include "g_level.h" #include "g_game.h" #include "gi.h" #include "templates.h" #include "v_font.h" TArray AllSkills; //========================================================================== // // ParseSkill // //========================================================================== void FMapInfoParser::ParseSkill () { FSkillInfo skill; skill.AmmoFactor = FRACUNIT; skill.DoubleAmmoFactor = 2*FRACUNIT; skill.DropAmmoFactor = -1; skill.DamageFactor = FRACUNIT; skill.FastMonsters = false; skill.DisableCheats = false; skill.EasyBossBrain = false; skill.AutoUseHealth = false; skill.RespawnCounter = 0; skill.RespawnLimit = 0; skill.Aggressiveness = FRACUNIT; skill.SpawnFilter = 0; skill.ACSReturn = AllSkills.Size(); skill.MenuNameIsLump = false; skill.MustConfirm = false; skill.Shortcut = 0; skill.TextColor = ""; sc.MustGetString(); skill.Name = sc.String; ParseOpenBrace(); while (sc.GetString ()) { if (sc.Compare ("ammofactor")) { ParseAssign(); sc.MustGetFloat (); skill.AmmoFactor = FLOAT2FIXED(sc.Float); } else if (sc.Compare ("doubleammofactor")) { ParseAssign(); sc.MustGetFloat (); skill.DoubleAmmoFactor = FLOAT2FIXED(sc.Float); } else if (sc.Compare ("dropammofactor")) { ParseAssign(); sc.MustGetFloat (); skill.DropAmmoFactor = FLOAT2FIXED(sc.Float); } else if (sc.Compare ("damagefactor")) { ParseAssign(); sc.MustGetFloat (); skill.DamageFactor = FLOAT2FIXED(sc.Float); } else if (sc.Compare ("fastmonsters")) { skill.FastMonsters = true; } else if (sc.Compare ("disablecheats")) { skill.DisableCheats = true; } else if (sc.Compare ("easybossbrain")) { skill.EasyBossBrain = true; } else if (sc.Compare("autousehealth")) { skill.AutoUseHealth = true; } else if (sc.Compare("respawntime")) { ParseAssign(); sc.MustGetFloat (); skill.RespawnCounter = int(sc.Float*TICRATE); } else if (sc.Compare("respawnlimit")) { ParseAssign(); sc.MustGetNumber (); skill.RespawnLimit = sc.Number; } else if (sc.Compare("Aggressiveness")) { ParseAssign(); sc.MustGetFloat (); skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp(sc.Float, 0.,1.)); } else if (sc.Compare("SpawnFilter")) { ParseAssign(); if (sc.CheckNumber()) { if (sc.Number > 0) skill.SpawnFilter |= (1<<(sc.Number-1)); } else { sc.MustGetString (); if (sc.Compare("baby")) skill.SpawnFilter |= 1; else if (sc.Compare("easy")) skill.SpawnFilter |= 2; else if (sc.Compare("normal")) skill.SpawnFilter |= 4; else if (sc.Compare("hard")) skill.SpawnFilter |= 8; else if (sc.Compare("nightmare")) skill.SpawnFilter |= 16; } } else if (sc.Compare("ACSReturn")) { ParseAssign(); sc.MustGetNumber (); skill.ACSReturn = sc.Number; } else if (sc.Compare("Name")) { ParseAssign(); sc.MustGetString (); skill.MenuName = sc.String; skill.MenuNameIsLump = false; } else if (sc.Compare("PlayerClassName")) { ParseAssign(); sc.MustGetString (); FName pc = sc.String; ParseComma(); sc.MustGetString (); skill.MenuNamesForPlayerClass[pc]=sc.String; } else if (sc.Compare("PicName")) { ParseAssign(); sc.MustGetString (); skill.MenuName = sc.String; skill.MenuNameIsLump = true; } else if (sc.Compare("MustConfirm")) { ParseAssign(); skill.MustConfirm = true; if (sc.CheckToken(TK_StringConst)) { skill.MustConfirmText = sc.String; } } else if (sc.Compare("Key")) { ParseAssign(); sc.MustGetString(); skill.Shortcut = tolower(sc.String[0]); } else if (sc.Compare("TextColor")) { ParseAssign(); sc.MustGetString(); skill.TextColor.Format("[%s]", sc.String); } else if (!ParseCloseBrace()) { // Unknown sc.ScriptMessage("Unknown property '%s' found in skill definition\n", sc.String); SkipToNext(); } else { break; } } for(unsigned int i = 0; i < AllSkills.Size(); i++) { if (AllSkills[i].Name == skill.Name) { AllSkills[i] = skill; return; } } AllSkills.Push(skill); } //========================================================================== // // // //========================================================================== int G_SkillProperty(ESkillProperty prop) { if (AllSkills.Size() > 0) { switch(prop) { case SKILLP_AmmoFactor: if (dmflags2 & DF2_YES_DOUBLEAMMO) { return AllSkills[gameskill].DoubleAmmoFactor; } return AllSkills[gameskill].AmmoFactor; case SKILLP_DropAmmoFactor: return AllSkills[gameskill].DropAmmoFactor; case SKILLP_DamageFactor: return AllSkills[gameskill].DamageFactor; case SKILLP_FastMonsters: return AllSkills[gameskill].FastMonsters || (dmflags & DF_FAST_MONSTERS); case SKILLP_Respawn: if (dmflags & DF_MONSTERS_RESPAWN && AllSkills[gameskill].RespawnCounter==0) return TICRATE * (gameinfo.gametype != GAME_Strife ? 12 : 16); return AllSkills[gameskill].RespawnCounter; case SKILLP_RespawnLimit: return AllSkills[gameskill].RespawnLimit; case SKILLP_Aggressiveness: return AllSkills[gameskill].Aggressiveness; case SKILLP_DisableCheats: return AllSkills[gameskill].DisableCheats; case SKILLP_AutoUseHealth: return AllSkills[gameskill].AutoUseHealth; case SKILLP_EasyBossBrain: return AllSkills[gameskill].EasyBossBrain; case SKILLP_SpawnFilter: return AllSkills[gameskill].SpawnFilter; case SKILLP_ACSReturn: return AllSkills[gameskill].ACSReturn; } } return 0; } //========================================================================== // // // //========================================================================== void G_VerifySkill() { if (gameskill >= (int)AllSkills.Size()) gameskill = AllSkills.Size()-1; else if (gameskill < 0) gameskill = 0; } //========================================================================== // // // //========================================================================== FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other) { Name = other.Name; AmmoFactor = other.AmmoFactor; DoubleAmmoFactor = other.DoubleAmmoFactor; DropAmmoFactor = other.DropAmmoFactor; DamageFactor = other.DamageFactor; FastMonsters = other.FastMonsters; DisableCheats = other.DisableCheats; AutoUseHealth = other.AutoUseHealth; EasyBossBrain = other.EasyBossBrain; RespawnCounter= other.RespawnCounter; RespawnLimit= other.RespawnLimit; Aggressiveness= other.Aggressiveness; SpawnFilter = other.SpawnFilter; ACSReturn = other.ACSReturn; MenuName = other.MenuName; MenuNamesForPlayerClass = other.MenuNamesForPlayerClass; MenuNameIsLump = other.MenuNameIsLump; MustConfirm = other.MustConfirm; MustConfirmText = other.MustConfirmText; Shortcut = other.Shortcut; TextColor = other.TextColor; return *this; } //========================================================================== // // // //========================================================================== int FSkillInfo::GetTextColor() const { if (TextColor.IsEmpty()) { return CR_UNTRANSLATED; } const BYTE *cp = (const BYTE *)TextColor.GetChars(); int color = V_ParseFontColor(cp, 0, 0); if (color == CR_UNDEFINED) { Printf("Undefined color '%s' in definition of skill %s\n", TextColor.GetChars(), Name.GetChars()); color = CR_UNTRANSLATED; } return color; }