public static int LastSpaceBeforeWrap(this colorstring cs, int wrap_index) { string s = ""; foreach (cstr c in cs.strings) { s += c.s; } return(s.LastSpaceBeforeWrap(wrap_index)); }
public static void WriteMapString(int r, int c, colorstring cs) { if (cs.Length() > 0) { r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; int cpos = c; foreach (cstr s1 in cs.strings) { cstr s = new cstr(s1.s, s1.color, s1.bgcolor); if (cpos - Global.MAP_OFFSET_COLS + s.s.Length > Global.COLS) { s.s = s.s.Substring(0, Global.COLS - (cpos - Global.MAP_OFFSET_COLS)); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /* cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, cpos + i].Equals(cch)) { memory[r, cpos + i] = cch; changed = true; } ++i; } if (changed) { Game.Console.SetCursorPosition(cpos, r); Game.Console.Write(s.s); } cpos += s.s.Length; } /*if(cpos-Global.MAP_OFFSET_COLS < Global.COLS){ * WriteString(r,cpos,"".PadRight(Global.COLS-(cpos-Global.MAP_OFFSET_COLS))); * }*/ } }
public static colorstring operator +(colorstring one, colorstring two) { colorstring result = new colorstring(); foreach (cstr s in one.strings) { result.strings.Add(s); } foreach (cstr s in two.strings) { result.strings.Add(s); } return(result); }
public static void WriteString(int r, int c, colorstring cs) { if (cs.Length() > 0) { int pos = c; foreach (cstr s1 in cs.strings) { cstr s = new cstr(s1.s, s1.color, s1.bgcolor); if (s.s.Length + pos > Global.SCREEN_W) { s.s = s.s.Substring(0, Global.SCREEN_W - pos); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, pos + i].Equals(cch)) { memory[r, pos + i] = cch; changed = true; } ++i; } if (changed) { Game.Console.SetCursorPosition(pos, r); Game.Console.Write(s.s); } pos += s.s.Length; } } }
public static colorstring GetColorString(this string s, Color color) { if (s.Search(new Regex(@"\[")) > -1) { string temp = s; colorstring result = new colorstring(); while (temp.Search(new Regex(@"\[")) > -1) { int open = temp.IndexOf("["); int close = temp.IndexOf("]"); if (close == -1) { result.strings.Add(new cstr(temp, color)); temp = ""; } else { int hyphen = temp.IndexOf("-"); if (hyphen != -1 && hyphen > open && hyphen < close) { result.strings.Add(new cstr(temp.Substring(0, open + 1), color)); //result.strings.Add(new cstr(temp.Substring(open+1,(close-open)-1),Color.Cyan)); result.strings.Add(new cstr(temp.Substring(open + 1, hyphen), Color.Cyan)); //was hyphen - open result.strings.Add(new cstr("-", color)); result.strings.Add(new cstr(temp.Substring(hyphen + 1, (close)), Color.Cyan)); // was close - hyphen result.strings.Add(new cstr("]", color)); temp = temp.Substring(close + 1); } else { result.strings.Add(new cstr(temp.Substring(0, open + 1), color)); result.strings.Add(new cstr(temp.Substring(open + 1, (close)), Color.Cyan)); // was close-open result.strings.Add(new cstr("]", color)); temp = temp.Substring(close + 1); } } } if (temp != "") { result.strings.Add(new cstr(temp, color)); } return(result); } else { return(new colorstring(s, color)); } }
public static colorstring GetColorString(this string s, Color text_color, Color key_color) { if (s.Contains("[")) { string temp = s; colorstring result = new colorstring(); while (temp.Contains("[")) { int open = temp.IndexOf('['); int close = temp.IndexOf(']'); if (close == -1) { result.strings.Add(new cstr(temp, text_color)); temp = ""; } else { int hyphen = temp.IndexOf('-'); if (hyphen != -1 && hyphen > open && hyphen < close) { result.strings.Add(new cstr(temp.Substring(0, open + 1), text_color)); //result.strings.Add(new cstr(temp.Substring(open+1,(close-open)-1),Color.Cyan)); result.strings.Add(new cstr(temp.Substring(open + 1, (hyphen - open) - 1), key_color)); result.strings.Add(new cstr("-", text_color)); result.strings.Add(new cstr(temp.Substring(hyphen + 1, (close - hyphen) - 1), key_color)); result.strings.Add(new cstr("]", text_color)); temp = temp.Substring(close + 1); } else { result.strings.Add(new cstr(temp.Substring(0, open + 1), text_color)); result.strings.Add(new cstr(temp.Substring(open + 1, (close - open) - 1), key_color)); result.strings.Add(new cstr("]", text_color)); temp = temp.Substring(close + 1); } } } if (temp != "") { result.strings.Add(new cstr(temp, text_color)); } return(result); } else { return(new colorstring(s, text_color)); } }
public void IncreaseSkill(SkillType skill) { List<string> learned = new List<string>(); skills[skill]++; bool active_feat_learned = false; B.Add("You feel a rush of power. "); B.PrintAll(); ConsoleKeyInfo command; bool gain_feat = false; if(!M.feat_gained_this_level){ if(Feat.NumberOfFeats(skill,feats_in_order) < 4){ List<List<SkillType>> skill_groups = new List<List<SkillType>>{new List<SkillType>{tile().type.GetAssociatedSkill()}}; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(M.tile[i,j].IsShrine() && M.tile[i,j].type != TileType.SPELL_EXCHANGE_SHRINE && this.DistanceFrom(i,j) > 2){ foreach(var list in skill_groups){ foreach(SkillType s in list){ if(s == M.tile[i,j].type.GetAssociatedSkill()){ goto NoAdd; } } } List<SkillType> newlist = new List<SkillType>(); foreach(Tile t in M.tile[i,j].TilesWithinDistance(2)){ if(t.IsShrine() && t.type != TileType.SPELL_EXCHANGE_SHRINE){ SkillType newskill = t.type.GetAssociatedSkill(); if(Feat.NumberOfFeats(newskill,feats_in_order) >= 4){ goto NoAdd; } newlist.Add(newskill); } } skill_groups.Add(newlist); NoAdd: continue; } } } if(M.nextLevelShrines?.Count > 0){ List<SchismDungeonGenerator.CellType> nextShrines = new List<SchismDungeonGenerator.CellType>(M.nextLevelShrines); while(nextShrines.Count > 0){ List<SkillType> newlist = new List<SkillType>(); newlist.Add(nextShrines.RemoveFirst().GetAssociatedSkill()); if(nextShrines.Count > 0){ newlist.Add(nextShrines.RemoveFirst().GetAssociatedSkill()); } foreach(SkillType newskill in newlist){ if(Feat.NumberOfFeats(newskill,feats_in_order) >= 4){ goto NoAdd; } } skill_groups.Add(newlist); NoAdd: continue; } } if(skill_groups.Random().Contains(skill)){ gain_feat = true; } } } if(gain_feat){ M.feat_gained_this_level = true; FeatType feat_chosen = FeatType.NO_FEAT; bool done = false; MouseUI.PushButtonMap(); for(int i=0;i<4;++i){ MouseUI.CreateMapButton((ConsoleKey)(ConsoleKey.A + i),false,1 + i*5,5); } MouseUI.CreateButton(ConsoleKey.Oem2,true,Global.MAP_OFFSET_ROWS + ROWS-1,Global.MAP_OFFSET_COLS + 32,1,12); while(!done){ Screen.ResetColors(); Screen.WriteMapString(0,0,"".PadRight(COLS,'-')); for(int i=0;i<4;++i){ FeatType ft = Feat.OfSkill(skill,i); Color featcolor = (feat_chosen == ft)? Color.Green : Color.Gray; Color lettercolor = Color.Cyan; if(HasFeat(ft)){ featcolor = Color.Magenta; lettercolor = Color.DarkRed; } Screen.WriteMapString(1+i*5,0,("["+(char)(i+97)+"] ")); Screen.WriteMapChar(1+i*5,1,(char)(i+97),lettercolor); Screen.WriteMapString(1+i*5,4,Feat.Name(ft).PadRight(30),featcolor); if(Feat.IsActivated(ft)){ Screen.WriteMapString(1+i*5,30," Active".PadToMapSize(),featcolor); } else{ Screen.WriteMapString(1+i*5,30," Passive".PadToMapSize(),featcolor); } List<string> desc = Feat.Description(ft); for(int j=0;j<4;++j){ if(desc.Count > j){ Screen.WriteMapString(2+j+i*5,0," " + desc[j].PadRight(64),featcolor); } else{ Screen.WriteMapString(2+j+i*5,0,"".PadRight(66)); } } } if(feat_chosen != FeatType.NO_FEAT){ Screen.WriteMapString(21,0,"--Type [a-d] to choose a feat---[?] for help---[Enter] to accept--"); Screen.WriteMapChar(21,8,new colorchar(Color.Cyan,'a')); Screen.WriteMapChar(21,10,new colorchar(Color.Cyan,'d')); Screen.WriteMapChar(21,33,new colorchar(Color.Cyan,'?')); Screen.WriteMapString(21,48,new cstr(Color.Magenta,"Enter")); MouseUI.CreateButton(ConsoleKey.Enter,false,Global.MAP_OFFSET_ROWS + ROWS-1,Global.MAP_OFFSET_COLS + 47,1,17); } else{ Screen.WriteMapString(21,0,"--Type [a-d] to choose a feat---[?] for help----------------------"); Screen.WriteMapChar(21,8,new colorchar(Color.Cyan,'a')); Screen.WriteMapChar(21,10,new colorchar(Color.Cyan,'d')); Screen.WriteMapChar(21,33,new colorchar(Color.Cyan,'?')); MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS + ROWS-1,Global.MAP_OFFSET_COLS + 47); } B.DisplayNow("Your " + Skill.Name(skill) + " skill increases to " + skills[skill] + ". Choose a feat: "); if(!Help.displayed[TutorialTopic.Feats]){ Help.TutorialTip(TutorialTopic.Feats,true); B.DisplayNow("Your " + Skill.Name(skill) + " skill increases to " + skills[skill] + ". Choose a feat: "); } Screen.CursorVisible = true; command = Input.ReadKey(); Screen.CursorVisible = false; char ch = command.GetCommandChar(); switch(ch){ case 'a': case 'b': case 'c': case 'd': { FeatType ft = Feat.OfSkill(skill,(int)(ch-97)); int i = (int)(ch - 'a'); if(feat_chosen == ft){ feat_chosen = FeatType.NO_FEAT; MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS + 1 + i*5,60); MouseUI.CreateMapButton((ConsoleKey)(ConsoleKey.A + i),false,1 + i*5,5); } else{ if(!HasFeat(ft)){ if(feat_chosen != FeatType.NO_FEAT){ int num = (int)feat_chosen % 4; MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS + 1 + num*5,60); MouseUI.CreateMapButton((ConsoleKey)(ConsoleKey.A + num),false,1 + num*5,5); } feat_chosen = ft; MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS + 1 + i*5,60); MouseUI.CreateMapButton(ConsoleKey.Enter,false,1 + i*5,5); } } break; } case '?': Help.DisplayHelp(HelpTopic.Feats); UI.DisplayStats(); break; case (char)13: if(feat_chosen != FeatType.NO_FEAT){ done = true; } break; default: break; } } feats[feat_chosen] = true; feats_in_order.Add(feat_chosen); learned.Add("You master the " + Feat.Name(feat_chosen) + " feat. "); if(Feat.IsActivated(feat_chosen)){ active_feat_learned = true; } MouseUI.PopButtonMap(); } else{ learned.Add("Your " + Skill.Name(skill) + " skill increases to " + skills[skill] + ". "); } if(skill == SkillType.MAGIC){ maxmp += 5; curmp += 5; List<SpellType> unknown = new List<SpellType>(); List<colorstring> unknownstr = new List<colorstring>(); List<SpellType> random_spell_list = new List<SpellType>(); foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){ random_spell_list.Add(spell); } while(unknown.Count < 5 && random_spell_list.Count > 0){ SpellType spell = random_spell_list.RemoveRandom(); if(!HasSpell(spell) && spell != SpellType.NO_SPELL && spell != SpellType.NUM_SPELLS){ unknown.Add(spell); } } unknown.Sort((sp1,sp2)=>Spell.Tier(sp1).CompareTo(Spell.Tier(sp2))); foreach(SpellType spell in unknown){ colorstring cs = new colorstring(); cs.strings.Add(new cstr(Spell.Name(spell).PadRight(17) + Spell.Tier(spell).ToString().PadLeft(3),Color.Gray)); cs.strings.Add(new cstr("".PadRight(5),Color.Gray)); unknownstr.Add(cs + Spell.Description(spell)); } M.Draw(); /*for(int i=unknown.Count+2;i<ROWS;++i){ Screen.WriteMapString(i,0,"".PadRight(COLS)); }*/ Help.TutorialTip(TutorialTopic.SpellTiers); Screen.WriteMapString(unknown.Count+2,0,"".PadRight(COLS)); colorstring topborder = new colorstring("---------------------Tier-----------------Description-------------",Color.Gray); int selection = Select("Learn which spell? ",topborder,new colorstring("".PadRight(25,'-') + "[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(COLS,'-'),Color.Gray),unknownstr,false,true,false,true,HelpTopic.Spells); spells[unknown[selection]] = true; learned.Add("You learn " + Spell.Name(unknown[selection]) + ". "); spells_in_order.Add(unknown[selection]); } if(learned.Count > 0){ foreach(string s in learned){ B.Add(s); } } if(active_feat_learned){ M.Draw(); Help.TutorialTip(TutorialTopic.ActiveFeats); } }
public static int[] DisplayEquipment() { MouseUI.PushButtonMap(); UI.draw_bottom_commands = false; UI.darken_status_bar = true; Weapon equippedWeapon = player.EquippedWeapon; Armor equippedArmor = player.EquippedArmor; WeaponType selectedWeapon = equippedWeapon.type; ArmorType selectedArmor = equippedArmor.type; List<MagicTrinketType> trinkets = player.magic_trinkets; int selectedTrinketIdx = -1; if(trinkets.Count > 0){ selectedTrinketIdx = R.Roll(trinkets.Count)-1; int i = 0; foreach(MagicTrinketType trinket in trinkets){ MouseUI.CreateButton((ConsoleKey)(ConsoleKey.I + i),false,i+1+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS + 32,1,34); ++i; } } Screen.Blank(); Screen.WriteMapString(0,0,"".PadRight(COLS,'-')); int line = 1; for(WeaponType w = WeaponType.SWORD;w <= WeaponType.BOW;++w){ Screen.WriteMapString(line,2,"[ ] " + player.WeaponOfType(w).EquipmentScreenName()); ConsoleKey key = (ConsoleKey)(ConsoleKey.A + line-1); if(w == selectedWeapon){ key = ConsoleKey.Enter; } if(trinkets.Count >= line){ MouseUI.CreateButton(key,false,line+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS,1,32); } else{ MouseUI.CreateMapButton(key,false,line,1); } ++line; } line = 8; for(ArmorType a = ArmorType.LEATHER;a <= ArmorType.FULL_PLATE;++a){ Screen.WriteMapString(line,2,"[ ] " + player.ArmorOfType(a).EquipmentScreenName()); ConsoleKey key = (ConsoleKey)(ConsoleKey.A + line-3); if(a == selectedArmor){ key = ConsoleKey.Enter; } if(trinkets.Count >= line){ MouseUI.CreateButton(key,false,line+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS,1,32); } else{ MouseUI.CreateMapButton(key,false,line,1); } ++line; } line = 1; foreach(MagicTrinketType m in trinkets){ Screen.WriteMapString(line,34,"[ ] " + MagicTrinket.Name(m).Capitalize()); ++line; } Screen.WriteMapString(11,0,"".PadRight(COLS,'-')); ConsoleKeyInfo command; bool done = false; while(!done){ line = 1; for(WeaponType w = WeaponType.SWORD;w <= WeaponType.BOW;++w){ char c = ' '; Color letter_color = Color.Cyan; if(equippedWeapon.status[EquipmentStatus.STUCK]){ letter_color = Color.Red; } if(selectedWeapon == w){ c = '>'; letter_color = Color.Red; } Screen.WriteMapChar(line,0,c); Screen.WriteMapChar(line,3,(char)(w+(int)'a'),letter_color); ++line; } line = 8; for(ArmorType a = ArmorType.LEATHER;a <= ArmorType.FULL_PLATE;++a){ char c = ' '; Color letter_color = Color.Cyan; if(equippedArmor.status[EquipmentStatus.STUCK]){ letter_color = Color.Red; } if(selectedArmor == a){ c = '>'; letter_color = Color.Red; } Screen.WriteMapChar(line,0,c); Screen.WriteMapChar(line,3,(char)(a+(int)'f'),letter_color); ++line; } line = 1; int letter = 0; foreach(MagicTrinketType m in trinkets){ if(selectedTrinketIdx == trinkets.IndexOf(m)){ Screen.WriteMapChar(line,32,'>'); } else{ Screen.WriteMapChar(line,32,' '); } Screen.WriteMapChar(line,35,(char)(letter+(int)'i'),Color.Red); ++line; ++letter; } Weapon newWeapon = player.WeaponOfType(selectedWeapon); Armor newArmor = player.ArmorOfType(selectedArmor); MagicTrinketType selectedTrinket = selectedTrinketIdx >= 0? trinkets[selectedTrinketIdx] : MagicTrinketType.NO_MAGIC_TRINKET; List<colorstring> wStr = newWeapon.Description().GetColorStrings(); wStr[0] = new colorstring("Weapon",Color.DarkRed,": ",Color.Gray) + wStr[0]; List<colorstring> aStr = newArmor.Description().GetColorStrings(); aStr[0] = new colorstring("Armor",Color.DarkCyan,": ",Color.Gray) + aStr[0]; { string wEnch = newWeapon.DescriptionOfEnchantment(); string aEnch = newArmor.DescriptionOfEnchantment(); if(wEnch != ""){ wStr.Add(new colorstring(wEnch,newWeapon.EnchantmentColor())); } if(aEnch != ""){ aStr.Add(new colorstring(aEnch,newArmor.EnchantmentColor())); } } List<colorstring> mStr = MagicTrinket.Description(selectedTrinket).GetColorStrings(); mStr[0] = new colorstring("Magic trinket",Color.DarkGreen,": ",Color.Gray) + mStr[0]; if(mStr.Count > 1){ mStr[1] = "".PadRight(15) + mStr[1]; } List<colorstring> wStatusShort = newWeapon.ShortStatusList(); List<colorstring> aStatusShort = newArmor.ShortStatusList(); int wMin = wStr.Count + wStatusShort.Count; int aMin = aStr.Count + aStatusShort.Count; int lines_free = 12 - wMin - aMin - mStr.Count; List<colorstring> wStatusLong = newWeapon.LongStatusList(); List<colorstring> aStatusLong = newArmor.LongStatusList(); int wDiff = wStatusLong.Count - wStatusShort.Count; int aDiff = aStatusLong.Count - aStatusShort.Count; bool expandW = false; bool expandA = false; if(wDiff + aDiff <= lines_free){ //if there's room to use the full versions of both, do that. expandW = true; expandA = true; } else{ if(wDiff > aDiff){ //otherwise, try to fit the biggest. if(wDiff <= lines_free){ expandW = true; } else{ if(aDiff <= lines_free){ expandA = true; } //if that doesn't work, we settle for the condensed version. } } else{ if(aDiff <= lines_free){ expandA = true; } else{ if(wDiff <= lines_free){ expandW = true; } } } } if(expandW){ wStr.AddRange(wStatusLong); lines_free -= wDiff; } else{ wStr.AddRange(wStatusShort); } if(expandA){ aStr.AddRange(aStatusLong); lines_free -= aDiff; } else{ aStr.AddRange(aStatusShort); } List<colorstring> top = new List<colorstring>(); //now let's distribute those extra lines. (0-7 possible) for(int i=0;i<2;++i){ //space between sections, then at the bottom. This takes care of 6 lines. if(lines_free >= 2){ lines_free -= 2; wStr.Add(new colorstring("")); aStr.Add(new colorstring("")); } if(lines_free >= 1){ lines_free -= 1; mStr.Add(new colorstring("")); } } if(lines_free >= 1){ //if there's one left, it means that we had the full 7 lines, so we need an extra space at the top. lines_free -= 1; top.Add(new colorstring("")); } int row = 12; foreach(List<colorstring> list in new List<List<colorstring>>{top,wStr,aStr,mStr}){ foreach(colorstring cs in list){ Screen.WriteMapString(row++,0,cs.PadRight(COLS)); } } if(newWeapon == equippedWeapon && newArmor == equippedArmor){ Screen.WriteMapString(row,0,"".PadRight(COLS,'-')); MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS+row,Global.MAP_OFFSET_COLS); } else{ if((newWeapon != equippedWeapon && equippedWeapon.status[EquipmentStatus.STUCK]) || (newArmor != equippedArmor && equippedArmor.status[EquipmentStatus.STUCK])){ Screen.WriteMapString(row,0,"".PadRight(COLS,'-')); MouseUI.RemoveButton(Global.MAP_OFFSET_ROWS+row,Global.MAP_OFFSET_COLS); } else{ Screen.WriteMapString(row,0,new colorstring("[",Color.Gray,"Enter",Color.Magenta,"] to confirm",Color.Gray).PadOuter(COLS,'-')); MouseUI.CreateMapButton(ConsoleKey.Enter,false,row,1); } } Screen.ResetColors(); B.DisplayNow("Your equipment: "); Screen.CursorVisible = true; command = Input.ReadKey(); char ch = command.GetCommandChar(); switch(ch){ case 'a': case 'b': case 'c': case 'd': case 'e': case '!': case '@': case '#': case '$': case '%': { switch(ch){ case '!': ch = 'a'; break; case '@': ch = 'b'; break; case '#': ch = 'c'; break; case '$': ch = 'd'; break; case '%': ch = 'e'; break; } int num = (int)(ch - 'a'); if(num != (int)(selectedWeapon)){ MouseUI.GetButton((int)(selectedWeapon)+1+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS).key = (ConsoleKey)(ConsoleKey.A + (int)selectedWeapon); MouseUI.GetButton(num+1+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS).key = ConsoleKey.Enter; selectedWeapon = (WeaponType)num; } break; } case 'f': case 'g': case 'h': case '*': case '(': case ')': { switch(ch){ case '*': ch = 'f'; break; case '(': ch = 'g'; break; case ')': ch = 'h'; break; } int num = (int)(ch - 'f'); if(num != (int)(selectedArmor)){ MouseUI.GetButton((int)(selectedArmor)+8+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS).key = (ConsoleKey)(ConsoleKey.F + (int)selectedArmor); MouseUI.GetButton(num+8+Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS).key = ConsoleKey.Enter; selectedArmor = (ArmorType)num; } break; } case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': { int num = (int)ch - (int)'i'; if(num < trinkets.Count && num != selectedTrinketIdx){ selectedTrinketIdx = num; } break; } case (char)27: case ' ': selectedWeapon = equippedWeapon.type; //reset selectedArmor = equippedArmor.type; done = true; break; case (char)13: done = true; break; default: break; } } MouseUI.PopButtonMap(); UI.draw_bottom_commands = true; UI.darken_status_bar = false; return new int[]{(int)selectedWeapon,(int)selectedArmor}; }
public static int DisplayCharacterInfo(bool readkey) { //todo remove old version in Actor MouseUI.PushButtonMap(); UI.DisplayStats(); UI.draw_bottom_commands = false; UI.darken_status_bar = true; const Color c = Color.Green; const Color text = Color.Gray; List<colorstring> top = new List<colorstring>{new colorstring("".PadRight(COLS,'-'),text)}; List<colorstring> name = new List<colorstring>{(new cstr("Name",c) + new cstr(": " + Actor.player_name,text)).PadRight(COLS/2) + (new cstr("Turns played",c) + new cstr(": " + Q.turn/100,text))}; List<colorstring> skills = null; List<colorstring> feats = null; List<colorstring> spells = null; List<colorstring> trinkets = null; List<colorstring> divider = new List<colorstring>{new colorstring("Active abilities",c,":",text)}; List<colorstring> actives = new List<colorstring>(); List<List<colorstring>> potential_skills = new List<List<colorstring>>(); for(int indent=7;indent>=1;--indent){ List<colorstring> list = new List<colorstring>{new colorstring("Skills",c,":",text)}; potential_skills.Add(list); for(SkillType sk = SkillType.COMBAT;sk < SkillType.NUM_SKILLS;++sk){ int skill_base = player.skills[sk]; int skill_mod = player.BonusSkill(sk); colorstring skill_string = new colorstring(" " + Skill.Name(sk) + "(",text,skill_base.ToString(),Color.White); if(skill_mod > 0){ skill_string.Add($"+{skill_mod}",Color.Yellow); } else{ if(skill_mod < 0){ skill_string.strings.Add(new cstr(skill_mod.ToString(),Color.Blue)); } } skill_string.strings.Add(new cstr(")",text)); list.AddWithWrap(skill_string,Global.COLS,indent); } } skills = potential_skills.WhereLeast(x=>x.Count)[0]; //Take the first result (i.e. highest indent) from the lowest count. List<List<colorstring>> potential_feats = new List<List<colorstring>>(); for(int indent=6;indent>=1;--indent){ List<colorstring> list = new List<colorstring>{new colorstring("Feats",c,":",text)}; potential_feats.Add(list); for(int i=0;i<Actor.feats_in_order.Count;++i){ string comma = (i == Actor.feats_in_order.Count - 1)? "" : ","; colorstring feat_string = new colorstring(" " + Feat.Name(Actor.feats_in_order[i]) + comma); list.AddWithWrap(feat_string,Global.COLS,indent); } } feats = potential_feats.WhereLeast(x=>x.Count)[0]; //Take the first result (i.e. highest indent) from the lowest count. List<List<colorstring>> potential_spells = new List<List<colorstring>>(); for(int indent=7;indent>=1;--indent){ List<colorstring> list = new List<colorstring>{new colorstring("Spells",c,":",text)}; potential_spells.Add(list); for(int i=0;i<Actor.spells_in_order.Count;++i){ string comma = (i == Actor.spells_in_order.Count - 1)? "" : ","; colorstring spell_string = new colorstring(" " + Spell.Name(Actor.spells_in_order[i]) + comma); list.AddWithWrap(spell_string,Global.COLS,indent); } } spells = potential_spells.WhereLeast(x=>x.Count)[0]; //Take the first result (i.e. highest indent) from the lowest count. List<string> magic_equipment_names = new List<string>(); foreach(Weapon w in player.weapons){ if(w.IsEnchanted()){ magic_equipment_names.Add(w.NameWithEnchantment()); } } foreach(Armor a in player.armors){ if(a.IsEnchanted()){ magic_equipment_names.Add(a.NameWithEnchantment()); } } foreach(MagicTrinketType trinket in player.magic_trinkets){ magic_equipment_names.Add(MagicTrinket.Name(trinket)); } List<List<colorstring>> potential_trinkets = new List<List<colorstring>>(); for(int indent=18;indent>=1;--indent){ //todo keep this value? List<colorstring> list = new List<colorstring>{new colorstring("Magical equipment",c,":",text)}; potential_trinkets.Add(list); for(int i=0;i<magic_equipment_names.Count;++i){ string comma = (i == magic_equipment_names.Count - 1)? "" : ","; colorstring equip_string = new colorstring(" " + magic_equipment_names[i].Capitalize() + comma); list.AddWithWrap(equip_string,Global.COLS,indent); } } trinkets = potential_trinkets.WhereLeast(x=>x.Count)[0]; //Take the first result (i.e. highest indent) from the lowest count. List<FeatType> active_feats = new List<FeatType>(); foreach(FeatType f in Actor.feats_in_order){ if(Feat.IsActivated(f)){ active_feats.Add(f); } } for(int i=0;i<active_feats.Count;++i){ actives.Add(new colorstring(" [",text,((char)(i+'a')).ToString(),Color.Cyan,"] " + Feat.Name(active_feats[i]),text)); } //eventually activated trinkets or temporary effects will go here. const int total_height = Global.SCREEN_H - Global.MAP_OFFSET_ROWS; List<List<colorstring>> all = new List<List<colorstring>>{top,name,skills,feats,spells,trinkets,divider,actives}; List<List<colorstring>> some = new List<List<colorstring>>{name,skills,feats,spells}; List<List<colorstring>> top_titles = new List<List<colorstring>>{name,skills,feats,spells,trinkets}; int rows_left = total_height - 1; // -1 for the bottom border foreach(var list in all){ rows_left -= list.Count; } //Here's how the extra rows are distributed: if(rows_left >= 1){ trinkets.Add(new colorstring("")); --rows_left; } if(rows_left >= 1){ actives.Add(new colorstring("")); --rows_left; } List<List<colorstring>> cramped = new List<List<colorstring>>(); foreach(var list in some){ if(list.Count == 1){ cramped.Add(list); //a list is considered cramped if its title (in green) is right next to another title. } } if(rows_left >= cramped.Count){ foreach(var list in cramped){ list.Add(new colorstring("")); --rows_left; } } List<List<colorstring>> no_blank_line = new List<List<colorstring>>(); foreach(var list in some){ if(list.Last().Length() > 0){ no_blank_line.Add(list); //this time, we try to put a space between each list and the next title. } } if(rows_left >= no_blank_line.Count){ foreach(var list in no_blank_line){ list.Add(new colorstring("")); --rows_left; } } /*if(rows_left >= 1){ divider.Add(new colorstring("")); --rows_left; }*/ int top_text_height = 0; foreach(var list in top_titles){ top_text_height += list.Count; } if(rows_left >= 1 && top_text_height < 14){ top.Add(new colorstring("")); --rows_left; } for(int i=0;i<rows_left;++i){ actives.Add(new colorstring("")); } int row = 0; foreach(var list in all){ foreach(colorstring cs in list){ Screen.WriteMapString(row,0,cs.PadRight(COLS)); ++row; } } Screen.WriteMapString(row,0,"".PadRight(COLS,'-'),text); Screen.ResetColors(); B.DisplayNow("Character information: "); Screen.CursorVisible = true; int result = -1; if(readkey){ result = player.GetSelection("Character information: ",active_feats.Count,false,true,false); //todo, currently only feats. } MouseUI.PopButtonMap(); UI.draw_bottom_commands = true; UI.darken_status_bar = false; return result; }
public override List<colorstring> GetStatusBarInfo() { List<colorstring> result = new List<colorstring>(); Color text = UI.darken_status_bar? Colors.status_darken : Color.Gray; if(p.Equals(UI.MapCursor)){ text = UI.darken_status_bar? Colors.status_highlight_darken : Colors.status_highlight; } foreach(string s in Name(true).GetWordWrappedList(17,true)){ colorstring cs = new colorstring(); result.Add(cs); if(result.Count == 1){ Color c = color; if(!revealed_by_light && !IsLit()){ c = Colors.darkcolor; } cs.strings.Add(new cstr(symbol.ToString(),c)); cs.strings.Add(new cstr(": " + s,text)); } else{ cs.strings.Add(new cstr(" " + s,text)); } } return result; }
public static void WriteString(int r,int c,colorstring cs){ if(cs.Length() > 0){ int pos = c; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(s.s.Length + pos > Global.SCREEN_W){ s.s = s.s.Substring(0,Global.SCREEN_W - pos); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,pos+i].Equals(cch)){ memory[r,pos+i] = cch; changed = true; } ++i; } if(changed){ Game.Console.SetCursorPosition(pos,r); Game.Console.Write(s.s); } pos += s.s.Length; } } }
public List<colorstring> ShortStatusList() { List<colorstring> result = new List<colorstring>(); List<EquipmentStatus> list = new List<EquipmentStatus>(); for(int i=0;i<(int)EquipmentStatus.NUM_STATUS;++i){ EquipmentStatus st = (EquipmentStatus)i; if(status[st]){ list.Add(st); } } for(int i=0;i<list.Count;++i){ EquipmentStatus st = list[i]; string comma = (i == list.Count - 1)? "" : ","; colorstring statusString = new colorstring(" " + StatusName(st) + comma,StatusColor(st)); result.AddWithWrap(statusString,Global.COLS - 2,1); } if(result.Count > 2){ //hard cap at 2 lines result.RemoveRange(2,result.Count - 2); } for(int i=0;i<result.Count;++i){ result[i] = result[i].PadOuter(Global.COLS); } return result; }
public colorstring EquipmentScreenName() { colorstring result = new colorstring(NameWithEnchantment().Capitalize() + " ",EnchantmentColor()); for(int i=0;i<(int)EquipmentStatus.NUM_STATUS;++i){ if(status[(EquipmentStatus)i]){ result.strings.Add(new cstr("*",StatusColor((EquipmentStatus)i))); if(result.Length() >= 25){ break; } } } return result; }
public colorstring(colorstring other) { foreach(cstr cs in other.strings){ strings.Add(cs); } }
public static void WriteMapString(int r,int c,colorstring cs) { if(cs.Length() > 0){ r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; int start_col = -1; int end_col = -1; int cpos = c; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(cpos-Global.MAP_OFFSET_COLS + s.s.Length > Global.COLS){ s.s = s.s.Substring(0,Global.COLS-(cpos-Global.MAP_OFFSET_COLS)); } s.color = Colors.ResolveColor(s.color); s.bgcolor = Colors.ResolveColor(s.bgcolor); colorchar cch; cch.color = s.color; cch.bgcolor = s.bgcolor; if(!GLMode){ ConsoleColor co = Colors.GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = Colors.GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } } int i = 0; bool changed = false; foreach(char ch in s.s){ cch.c = ch; if(!memory[r,cpos+i].Equals(cch)){ memory[r,cpos+i] = cch; if(start_col == -1){ start_col = cpos+i; } end_col = cpos+i; changed = true; } ++i; } if(changed && !GLMode){ Console.SetCursorPosition(cpos,r); Console.Write(s.s); } cpos += s.s.Length; } if(GLMode && !NoGLUpdate && start_col != -1){ UpdateGLBuffer(r,start_col,r,end_col); } if(MouseUI.AutomaticButtonsFromStrings && GLMode){ int idx = -1; int len = cs.Length(); for(int i=0;i<len;++i){ if(cs[i].c == '['){ idx = i; break; } } if(idx != -1 && idx+1 < cs.Length()){ ConsoleKey key = ConsoleKey.A; bool shifted = false; switch(cs[idx+1].c){ case 'E': key = ConsoleKey.Enter; break; case 'T': key = ConsoleKey.Tab; break; case 'P': //"Press any key" break; case '?': key = ConsoleKey.Oem2; shifted = true; break; case '=': key = ConsoleKey.OemPlus; break; default: //all others should be lowercase letters key = (ConsoleKey)(ConsoleKey.A + ((int)cs[idx+1].c - (int)'a')); break; } MouseUI.CreateMapButton(key,shifted,r-Global.MAP_OFFSET_ROWS,1); } } /*if(cpos-Global.MAP_OFFSET_COLS < Global.COLS){ WriteString(r,cpos,"".PadRight(Global.COLS-(cpos-Global.MAP_OFFSET_COLS))); }*/ } }
public static async Task TutorialTip(TutorialTopic topic) { if (Global.Option(OptionType.NEVER_DISPLAY_TIPS) || displayed[topic]) { return; } Color box_edge_color = Color.Blue; Color box_corner_color = Color.Yellow; Color first_line_color = Color.Yellow; Color text_color = Color.Gray; string[] text = TutorialText(topic); int stringwidth = 27; // length of "[Press any key to continue]" foreach (string s in text) { if (s.Length > stringwidth) { stringwidth = s.Length; } } stringwidth += 4; //2 blanks on each side int boxwidth = stringwidth + 2; int boxheight = text.Length + 5; //for(bool done=false;!done;){ colorstring[] box = new colorstring[boxheight]; //maybe i should make this a list to match the others box[0] = new colorstring("+", box_corner_color, "".PadRight(stringwidth, '-'), box_edge_color, "+", box_corner_color); box[text.Length + 1] = new colorstring("|", box_edge_color, "".PadRight(stringwidth), Color.Gray, "|", box_edge_color); box[text.Length + 2] = new colorstring("|", box_edge_color) + ("[Press any key to continue]".PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here box[text.Length + 3] = new colorstring("|", box_edge_color) + ("[=] Stop showing tips".PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here box[text.Length + 4] = new colorstring("+", box_corner_color, "".PadRight(stringwidth, '-'), box_edge_color, "+", box_corner_color); int pos = 1; foreach (string s in text) { box[pos] = new colorstring("|", box_edge_color) + (s.PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here if (pos == 1) { box[pos] = new colorstring(); box[pos].strings.Add(new cstr("|", box_edge_color)); box[pos].strings.Add(new cstr(s.PadOuter(stringwidth), first_line_color)); //PadOuter originally here box[pos].strings.Add(new cstr("|", box_edge_color)); } ++pos; } int y = (Global.SCREEN_H - boxheight) / 2; int x = (Global.SCREEN_W - boxwidth) / 2; colorchar[,] memory = Screen.GetCurrentRect(y, x, boxheight, boxwidth); List <List <colorstring> > frames = new List <List <colorstring> >(); frames.Add(BoxAnimationFrame(boxheight - 2, FrameWidth(boxheight, boxwidth))); for (int i = boxheight - 4; i > 0; i -= 2) { frames.Add(BoxAnimationFrame(i, FrameWidth(frames.Last().Count, frames.Last()[0].Length()))); } for (int i = frames.Count - 1; i >= 0; --i) //since the frames are in reverse order { int y_offset = i + 1; int x_offset = (boxwidth - frames[i][0].Length()) / 2; Screen.WriteList(y + y_offset, x + x_offset, frames[i]); await Task.Delay(20); } foreach (colorstring s in box) { Screen.WriteString(y, x, s); ++y; } Actor.player.DisplayStats(false); if (topic != TutorialTopic.Feats) //hacky exception - don't get rid of the line that's already there. { Actor.B.DisplayNow(); } Game.Console.CursorVisible = false; await Task.Delay(500); Global.FlushInput(); /* switch(Game.Console.ReadKey(true).KeyChar){ * case 'q': * box_edge_color = NextColor(box_edge_color); * break; * case 'w': * box_corner_color = NextColor(box_corner_color); * break; * case 'e': * first_line_color = NextColor(first_line_color); * break; * case 'r': * text_color = NextColor(text_color); * break; * default: * done=true; * break; * } * }*/ if ((await Game.Console.ReadKey(true)).KeyChar == '=') { Global.Options[OptionType.NEVER_DISPLAY_TIPS] = true; } Screen.WriteArray((Global.SCREEN_H - boxheight) / 2, x, memory); if (topic != TutorialTopic.Feats) //another exception { Actor.player.DisplayStats(true); } displayed[topic] = true; Game.Console.CursorVisible = true; }
public async Task<bool> InputHuman() { DisplayStats(true); if (HasFeat(FeatType.DANGER_SENSE)) { M.UpdateDangerValues(); } M.Draw(); if (HasAttr(AttrType.AUTOEXPLORE)) { if (path.Count == 0) { if (!FindAutoexplorePath()) { B.Add("You don't see a path for further exploration. "); } } } if (!HasAttr(AttrType.AFRAID) && !HasAttr(AttrType.PARALYZED) && !HasAttr(AttrType.FROZEN) && !HasAttr(AttrType.ASLEEP)) { await B.Print(false); } else { B.DisplayNow(); } Cursor(); Game.Console.CursorVisible = true; if (HasAttr(AttrType.PARALYZED) || HasAttr(AttrType.AFRAID) || HasAttr(AttrType.ASLEEP)) { if (HasAttr(AttrType.AFRAID)) { await Task.Delay(250); } if (HasAttr(AttrType.ASLEEP)) { await Task.Delay(100); } Q1(); return true; } if (HasAttr(AttrType.FROZEN)) { int damage = Global.Roll(Weapon.Damage(weapons[0]).dice, 6) + TotalSkill(SkillType.COMBAT); attrs[Forays.AttrType.FROZEN] -= damage; if (attrs[Forays.AttrType.FROZEN] < 0) { attrs[Forays.AttrType.FROZEN] = 0; } if (HasAttr(AttrType.FROZEN)) { B.Add("You attempt to break free. "); } else { B.Add("You break free! "); } Q1(); return true; } if (Global.Option(OptionType.AUTOPICKUP) && tile().inv != null && !tile().inv.ignored && !tile().Is(FeatureType.QUICKFIRE)) { bool grenade = false; foreach (Tile t in TilesWithinDistance(1)) { if (t.Is(FeatureType.GRENADE)) { grenade = true; } } if (!grenade && !HasAttr(AttrType.ON_FIRE) && !HasAttr(AttrType.CATCHING_FIRE)) { bool monster = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a)) { monster = true; break; } } if (!monster) { if (await StunnedThisTurn()) { return true; } Item i = tile().inv; i.row = -1; i.col = -1; tile().inv = null; B.Add("You pick up " + i.TheName() + ". "); bool added = false; foreach (Item item in inv) { if (item.itype == i.itype && !item.do_not_stack && !i.do_not_stack) { item.quantity += i.quantity; added = true; break; } } if (!added) { inv.Add(i); } Q1(); return true; } } } if (path.Count > 0) { bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { //check LOS, prevents detected mobs from stopping you monsters_visible = true; } } if (!monsters_visible) { if (Game.Console.KeyAvailable) { await Game.Console.ReadKey(true); Interrupt(); } else { //AI_Step(M.tile[path[0]]); await PlayerWalk(DirectionOf(path[0])); if (path.Count > 0) { if (DistanceFrom(path[0]) == 0) { path.RemoveAt(0); } } //QS(); return true; } } else { Interrupt(); } } if (HasAttr(AttrType.RUNNING)) { bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { //check LOS, prevents detected mobs from stopping you monsters_visible = true; } } Tile t = TileInDirection(attrs[AttrType.RUNNING]); bool stopped_by_terrain = false; if (t.IsKnownTrap() || t.Is(FeatureType.FUNGUS_ACTIVE) || t.Is(FeatureType.FUNGUS_PRIMED) || t.Is(FeatureType.GRENADE) || t.Is(FeatureType.POISON_GAS) || t.Is(FeatureType.QUICKFIRE)) { stopped_by_terrain = true; } if (!monsters_visible && !stopped_by_terrain && !Game.Console.KeyAvailable) { if (attrs[AttrType.RUNNING] == 5) { int hplimit = HasFeat(FeatType.ENDURING_SOUL) ? 20 : 10; if (curhp % hplimit == 0) { if (HasAttr(AttrType.WAITING)) { attrs[Forays.AttrType.WAITING]--; Q1(); return true; } else { attrs[AttrType.RUNNING] = 0; } } else { Q1(); return true; } } else { if (t.passable) { await PlayerWalk(attrs[AttrType.RUNNING]); return true; } else { Tile opposite = TileInDirection(RotateDirection(attrs[AttrType.RUNNING], true, 4)); int num_floors = 0; int floor_dir = 0; foreach (Tile t2 in TilesAtDistance(1)) { //if(t2 != opposite && t2.name == "floor"){ if (t2 != opposite && (t2.passable || t2.ttype == TileType.DOOR_C)) { num_floors++; floor_dir = DirectionOf(t2); } } if (num_floors == 1) { attrs[Forays.AttrType.RUNNING] = floor_dir; await PlayerWalk(floor_dir); return true; } else { attrs[Forays.AttrType.RUNNING] = 0; attrs[Forays.AttrType.WAITING] = 0; } } } } else { if (Game.Console.KeyAvailable) { await Game.Console.ReadKey(true); } attrs[AttrType.RUNNING] = 0; attrs[Forays.AttrType.WAITING] = 0; } } if (HasAttr(AttrType.RESTING)) { if (attrs[AttrType.RESTING] == 10) { attrs[AttrType.RESTING] = -1; curhp += ((maxhp - curhp) / 2); //recover half of your missing health ResetSpells(); B.Add("You rest...you feel great! "); await B.Print(false); DisplayStats(true); Cursor(); } else { bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { //check LOS, prevents detected mobs from stopping you monsters_visible = true; } } if (monsters_visible || Game.Console.KeyAvailable) { if (Game.Console.KeyAvailable) { await Game.Console.ReadKey(true); } if (monsters_visible) { attrs[AttrType.RESTING] = 0; B.Add("You rest...you are interrupted! "); await B.Print(false); Cursor(); } else { attrs[AttrType.RESTING] = 0; B.Add("You rest...you stop resting. "); await B.Print(false); Cursor(); } } else { attrs[AttrType.RESTING]++; B.Add("You rest... "); Q1(); return true; } } } if (Q.turn == 0) { await Help.TutorialTip(TutorialTopic.Movement); Cursor(); } if (!Help.displayed[TutorialTopic.Attacking] && M.AllActors().Any(a => (a != this && CanSee(a)))) { await Help.TutorialTip(TutorialTopic.Attacking); Cursor(); } ConsoleKeyInfo command = await Game.Console.ReadKey(true); string ch = ConvertInput(command); ch = ConvertVIKeys(ch); bool alt = false; bool ctrl = false; bool shift = false; if ((command.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt) { alt = true; } if ((command.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control) { ctrl = true; } if ((command.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift) { shift = true; } switch (ch) { case "7": case "8": case "9": case "4": case "6": case "1": case "2": case "3": { //jQuery.Select("#debug").ReplaceWith("<div id=\"debug\"><p>DEBUG Key Down, Key is " + command.Key + ", Char is " + command.KeyChar.ToString() + ", ch is " + ch + "</p></div>"); int dir = ch[0] - 48; //ascii 0-9 are 48-57 if (shift || alt || ctrl) { bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { monsters_visible = true; } } await PlayerWalk(dir); if (!monsters_visible) { attrs[AttrType.RUNNING] = dir; } } else { await PlayerWalk(dir); } break; } case "5": case ".": if (HasFeat(FeatType.FULL_DEFENSE) && EnemiesAdjacent() > 0) { if (!HasAttr(AttrType.CATCHING_FIRE) && !HasAttr(AttrType.ON_FIRE)) { attrs[AttrType.DEFENSIVE_STANCE]++; B.Add("You ready yourself. "); } } if (HasAttr(AttrType.CATCHING_FIRE)) { attrs[AttrType.CATCHING_FIRE] = 0; B.Add("You stop the flames from spreading. "); } else { if (HasAttr(AttrType.ON_FIRE)) { bool update = false; int oldradius = LightRadius(); if (attrs[AttrType.ON_FIRE] > light_radius) { update = true; } int i = 2; if (Global.Roll(1, 3) == 3) { // 1 in 3 times, you don't make progress against the fire i = 1; } attrs[AttrType.ON_FIRE] -= i; if (attrs[AttrType.ON_FIRE] < 0) { attrs[AttrType.ON_FIRE] = 0; } if (update) { UpdateRadius(oldradius, LightRadius()); } if (HasAttr(AttrType.ON_FIRE)) { B.Add("You put out some of the fire. "); //better message? } else { B.Add("You put out the fire. "); } } } if (M.tile[row, col].inv != null) { B.Add("You see " + M.tile[row, col].inv.AName() + ". "); } QS(); break; case "w": { int dir = await GetDirection("Start walking in which direction? ", false, true); if (dir != 0) { bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { monsters_visible = true; } } if (dir != 5) { await PlayerWalk(dir); } else { Q1(); } if (!monsters_visible) { attrs[AttrType.RUNNING] = dir; int hplimit = HasFeat(FeatType.ENDURING_SOUL) ? 20 : 10; if (curhp % hplimit == 0 && dir == 5) { attrs[Forays.AttrType.WAITING] = 20; } } } else { Q0(); } break; } case "o": { int dir = 0; int total = 0; foreach (Tile t in TilesAtDistance(1)) { if (t.ttype == TileType.DOOR_C || t.ttype == TileType.DOOR_O || t.ttype == TileType.RUBBLE || (HasFeat(FeatType.DISARM_TRAP) && t.IsKnownTrap())) { if (t.actor() == null && (t.inv == null || t.IsTrap())) { dir = DirectionOf(t); ++total; } } } if (total == 1) { Tile t = TileInDirection(dir); if (t.ttype == TileType.DOOR_C || t.ttype == TileType.DOOR_O || t.ttype == TileType.RUBBLE) { if (await StunnedThisTurn()) { return true; } t.Toggle(this); Q1(); } else { if (t.IsTrap()) { if (GrabPreventsMovement(t)) { B.Add("You can't currently reach that trap. "); Q0(); return true; } else { if (await StunnedThisTurn()) { return true; } if (Global.Roll(5) <= 4) { B.Add("You disarm " + Tile.Prototype(t.ttype).the_name + ". "); t.Toggle(this); Q1(); } else { if (Global.Roll(20) <= skills[Forays.SkillType.DEFENSE]) { B.Add("You almost set off " + Tile.Prototype(t.ttype).the_name + "! "); Q1(); } else { B.Add("You set off " + Tile.Prototype(t.ttype).the_name + "! "); await Move(t.row, t.col); Q1(); } } } } else { Q0(); //shouldn't happen } } } else { dir = await GetDirection("Operate something in which direction? "); if (dir != -1) { Tile t = TileInDirection(dir); if (t.IsKnownTrap()) { if (HasFeat(FeatType.DISARM_TRAP)) { if (GrabPreventsMovement(t)) { B.Add("You can't currently reach that trap. "); Q0(); return true; } if (await StunnedThisTurn()) { return true; } if (Global.Roll(5) <= 4) { B.Add("You disarm " + Tile.Prototype(t.ttype).the_name + ". "); t.Toggle(this); Q1(); } else { if (Global.Roll(20) <= skills[Forays.SkillType.DEFENSE]) { B.Add("You almost set off " + Tile.Prototype(t.ttype).the_name + "! "); Q1(); } else { B.Add("You set off " + Tile.Prototype(t.ttype).the_name + "! "); await Move(t.row, t.col); Q1(); } } } else { B.Add("You don't know how to disable that trap. "); Q0(); return true; } } else { switch (t.ttype) { case TileType.DOOR_C: case TileType.DOOR_O: case TileType.RUBBLE: if (await StunnedThisTurn()) { break; } t.Toggle(this); Q1(); break; case TileType.CHEST: B.Add("Stand on the chest and press 'g' to retrieve its contents. "); Q0(); break; case TileType.STAIRS: B.Add("Stand on the stairs and press '>' to descend. "); Q0(); break; default: Q0(); break; } } } else { Q0(); } } break; } /*case 'c': { int door = DirectionOfOnlyUnblocked(TileType.DOOR_O); if(door == -1){ int dir = GetDirection("Close in which direction? "); if(dir != -1){ if(TileInDirection(dir).type == TileType.DOOR_O){ if(StunnedThisTurn()){ break; } TileInDirection(dir).Toggle(this); Q1(); } else{ Q0(); } } else{ Q0(); } } else{ if(door == 0){ B.Add("There's nothing to close here. "); Q0(); } else{ if(StunnedThisTurn()){ break; } TileInDirection(door).Toggle(this); Q1(); } } break; }*/ case "s": { if (Weapon.BaseWeapon(weapons[0]) == WeaponType.BOW || HasFeat(FeatType.QUICK_DRAW)) { if (ActorsAtDistance(1).Count > 0) { if (ActorsAtDistance(1).Count == 1) { B.Add("You can't fire with an enemy so close. "); } else { B.Add("You can't fire with enemies so close. "); } Q0(); } /*if(Global.Option(OptionType.LAST_TARGET) && target!=null && DistanceFrom(target)==1){ //since you can't fire target = null; //at adjacent targets anyway. }*/ else { List<Tile> line = await GetTarget(12); if (line != null) { //if(DistanceFrom(t) > 1 || t.actor() == null){ await FireArrow(line); /*} else{ B.Add("You can't fire at adjacent targets. "); Q0(); }*/ } else { Q0(); } } } else { B.Add("You can't fire arrows without your bow equipped. "); Q0(); } break; } case "f": { List<FeatType> active_feats = new List<FeatType>(); List<FeatType> passive_feats = new List<FeatType>(); foreach (FeatType ft in feats_in_order) { if (Feat.IsActivated(ft)) { active_feats.Add(ft); } else { passive_feats.Add(ft); } } Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); int line = 1; if (active_feats.Count > 0) { Screen.WriteMapString(line, 0, "Active feats:".PadToMapSize()); ++line; char letter = 'a'; foreach (FeatType ft in active_feats) { string s = "[" + string.FromCharCode(letter) + "] " + Feat.Name(ft); Screen.WriteMapString(line, 0, s.PadToMapSize()); Screen.WriteMapChar(line, 1, string.FromCharCode(letter), Color.Cyan); ++line; ++letter; } Screen.WriteMapString(line, 0, "".PadToMapSize()); ++line; } if (passive_feats.Count > 0) { Screen.WriteMapString(line, 0, "Passive feats:".PadToMapSize()); ++line; foreach (FeatType ft in passive_feats) { string s = " " + Feat.Name(ft); Screen.WriteMapString(line, 0, s.PadToMapSize()); ++line; } Screen.WriteMapString(line, 0, "".PadToMapSize()); ++line; } Screen.WriteMapString(line, 0, "Feats currently being learned:".PadToMapSize()); ++line; if (partial_feats_in_order.Count == 0) { Screen.WriteMapString(line, 0, " None".PadToMapSize()); ++line; } else { if (partial_feats_in_order.Count + line > 21) { int extras = partial_feats_in_order.Count + line - 21; foreach (FeatType ft in partial_feats_in_order) { if (line == 21) { //don't print the bottommost feats again break; } Screen.WriteMapString(line, 0, " " + Feat.Name(ft).PadRight(21)); if (extras > 0) { Screen.WriteMapString(line, 25, "(" + (-feats[ft]) + "/" + Feat.MaxRank(ft) + ")".PadRight(7)); FeatType ft2 = partial_feats_in_order[partial_feats_in_order.Count - extras]; Screen.WriteMapString(line, 36, Feat.Name(ft2).PadRight(21)); Screen.WriteMapString(line, 57, "(" + (-feats[ft2]) + "/" + Feat.MaxRank(ft2) + ")".PadRight(6)); ++line; --extras; } else { Screen.WriteMapString(line, 25, "(" + (-feats[ft]) + "/" + Feat.MaxRank(ft) + ")".PadRight(37)); ++line; } } } else { foreach (FeatType ft in partial_feats_in_order) { Screen.WriteMapString(line, 0, " " + Feat.Name(ft).PadRight(21)); Screen.WriteMapString(line, 25, "(" + (-feats[ft]) + "/" + Feat.MaxRank(ft) + ")".PadRight(37)); ++line; } } } Screen.WriteMapString(line, 0, ("".PadRight(25, '-') + "[?] for help").PadRight(COLS, '-')); Screen.WriteMapChar(line, 26, new colorchar(Color.Cyan, "?")); ++line; if (line <= 21) { Screen.WriteMapString(line, 0, "".PadToMapSize()); } Screen.ResetColors(); if (active_feats.Count > 0) { B.DisplayNow("Use which feat? "); } else { B.DisplayNow("Feats: "); } Game.Console.CursorVisible = true; FeatType selected_feat = FeatType.NO_FEAT; bool done = false; while (!done) { command = await Game.Console.ReadKey(true); ch = ConvertInput(command); int ii = ch[0] - 'a'; if (active_feats.Count > ii && ii >= 0) { selected_feat = active_feats[ii]; done = true; } else { if (ch == "?") { await Help.DisplayHelp(HelpTopic.Feats); done = true; } else { done = true; } } } M.RedrawWithStrings(); if (selected_feat != FeatType.NO_FEAT) { if (await StunnedThisTurn()) { break; } if (true != await UseFeat(selected_feat)) { Q0(); } } else { Q0(); } break; } case "z": { foreach (Actor a in ActorsWithinDistance(2)) { if (a.HasAttr(AttrType.SPELL_DISRUPTION) && a.HasLOE(this)) { if (this == player) { if (CanSee(a)) { B.Add(a.Your() + " presence prevents you from casting! "); } else { B.Add("Something prevents you from casting! "); } } Q0(); return true; } } List<colorstring> ls = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); //foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){ bool bonus_marked = false; foreach (SpellType spell in spells_in_order) { if (HasSpell(spell)) { //string s = Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3); //s = s + FailRate(spell).ToString().PadLeft(9) + "%"; //s = s + Spell.Description(spell).PadLeft(34); colorstring cs = new colorstring(Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3), Color.Gray); cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%", FailColor(spell))); if (HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked) { bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else { cs = cs + Spell.Description(spell); } ls.Add(cs); sp.Add(spell); } } if (sp.Count > 0) { colorstring topborder = new colorstring("------------------Level---Fail rate--------Description------------", Color.Gray); int basefail = magic_penalty * 5; if (!HasFeat(FeatType.ARMORED_MAGE)) { basefail += Armor.AddedFailRate(armors[0]); } colorstring bottomborder = new colorstring("------------Base fail rate: ", Color.Gray, (basefail.ToString().PadLeft(3) + "%"), FailColor(basefail), "----------[", Color.Gray, "?", Color.Cyan, "] for help".PadRight(22, '-'), Color.Gray); //int i = Select("Cast which spell? ",topborder,bottomborder,ls); int i = await Select("Cast which spell? ", topborder, bottomborder, ls, false, false, true, true, HelpTopic.Spells); if (i != -1) { if (true != await CastSpell(sp[i])) { Q0(); } } else { Q0(); } } else { B.Add("You don't know any spells. "); Q0(); } break; } case "r": if (attrs[AttrType.RESTING] != -1) { //gets set to -1 if you've rested on this level bool monsters_visible = false; foreach (Actor a in M.AllActors()) { if (a != this && CanSee(a) && HasLOS(a.row, a.col)) { //check LOS, prevents detected mobs from stopping you monsters_visible = true; } } if (!monsters_visible) { bool can_recover_spells = false; if (magic_penalty > 0) { can_recover_spells = true; } if (curhp < maxhp || can_recover_spells) { if (await StunnedThisTurn()) { break; } attrs[AttrType.RESTING] = 1; B.Add("You rest... "); Q1(); } else { B.Add("You don't need to rest right now. "); Q0(); } } else { B.Add("You can't rest while there are enemies around! "); Q0(); } } else { B.Add("You find it impossible to rest again on this dungeon level. "); Q0(); } break; case ">": if (M.tile[row, col].ttype == TileType.STAIRS) { if (await StunnedThisTurn()) { break; } bool can_recover_spells = false; if (magic_penalty > 0) { can_recover_spells = true; } if (attrs[AttrType.RESTING] != -1 && (curhp < maxhp || can_recover_spells)) { B.DisplayNow("Really take the stairs without resting first?(y/n): "); Game.Console.CursorVisible = true; bool done = false; while (!done) { command = await Game.Console.ReadKey(true); switch (command.KeyChar) { case 'y': case 'Y': done = true; break; default: Q0(); return true; } } } B.Add("You walk down the stairs. "); await B.PrintAll(); if (M.current_level < 20) { await M.GenerateLevel(); } else { await M.GenerateBossLevel(false); B.Add("You enter a sweltering cavern. "); B.Add("Bones lie scattered across the sulfurous ground. "); } Q0(); } else { Tile stairs = null; foreach (Tile t in M.AllTiles()) { if (t.ttype == TileType.STAIRS && t.seen) { stairs = t; break; } } if (stairs != null) { B.DisplayNow("Travel to the stairs?(y/n): "); Game.Console.CursorVisible = true; bool done = false; while (!done) { command = await Game.Console.ReadKey(true); switch (command.KeyChar) { case 'y': case 'Y': case '>': case (char)13: done = true; break; default: Q0(); return true; } } FindPath(stairs, -1, true); Q0(); } else { B.Add("You don't see any stairs here. "); Q0(); } } break; case "x": { attrs[AttrType.AUTOEXPLORE]++; Q0(); } break; case "g": case ";": if (tile().inv == null) { if (tile().ttype == TileType.CHEST) { if (await StunnedThisTurn()) { break; } tile().OpenChest(); Q1(); } else { if (tile().IsShrine()) { if (await StunnedThisTurn()) { break; } switch (tile().ttype) { case TileType.COMBAT_SHRINE: IncreaseSkill(SkillType.COMBAT); break; case TileType.DEFENSE_SHRINE: IncreaseSkill(SkillType.DEFENSE); break; case TileType.MAGIC_SHRINE: IncreaseSkill(SkillType.MAGIC); break; case TileType.SPIRIT_SHRINE: IncreaseSkill(SkillType.SPIRIT); break; case TileType.STEALTH_SHRINE: IncreaseSkill(SkillType.STEALTH); break; case TileType.SPELL_EXCHANGE_SHRINE: { List<colorstring> ls = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); bool bonus_marked = false; foreach (SpellType spell in spells_in_order) { if (HasSpell(spell)) { colorstring cs = new colorstring(Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3), Color.Gray); cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%", FailColor(spell))); if (HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked) { bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else { cs = cs + Spell.Description(spell); } ls.Add(cs); sp.Add(spell); } } if (sp.Count > 0) { colorstring topborder = new colorstring("------------------Level---Fail rate--------Description------------", Color.Gray); int basefail = magic_penalty * 5; if (!HasFeat(FeatType.ARMORED_MAGE)) { basefail += Armor.AddedFailRate(armors[0]); } colorstring bottomborder = new colorstring("------------Base fail rate: ", Color.Gray, (basefail.ToString().PadLeft(3) + "%"), FailColor(basefail), "----------[", Color.Gray, "?", Color.Cyan, "] for help".PadRight(22, '-'), Color.Gray); int i = await Select("Trade one of your spells for another? ", topborder, bottomborder, ls, false, false, true, true, HelpTopic.Spells); if (i != -1) { List<SpellType> unknown = new List<SpellType>(); foreach (SpellType spell in GetSpellTypes()) { if (!HasSpell(spell) && spell != SpellType.BLESS && spell != SpellType.MINOR_HEAL && spell != SpellType.HOLY_SHIELD && spell != SpellType.NO_SPELL && spell != SpellType.NUM_SPELLS) { unknown.Add(spell); } } SpellType forgotten = sp[i]; spells_in_order.Remove(forgotten); spells[forgotten] = 0; SpellType learned = unknown.Random(); spells[learned] = 1; spells_in_order.Add(learned); B.Add("You forget " + Spell.Name(forgotten) + ". You learn " + Spell.Name(learned) + ". "); tile().TransformTo(TileType.RUINED_SHRINE); } else { Q0(); } } break; } default: break; } if (tile().ttype != TileType.SPELL_EXCHANGE_SHRINE) { Q1(); } if (tile().ttype == TileType.MAGIC_SHRINE && spells_in_order.Count > 1) { tile().TransformTo(TileType.SPELL_EXCHANGE_SHRINE); } else { if (tile().ttype != TileType.SPELL_EXCHANGE_SHRINE) { tile().TransformTo(TileType.RUINED_SHRINE); } } foreach (Tile t in TilesAtDistance(2)) { if (t.IsShrine()) { t.TransformTo(TileType.RUINED_SHRINE); } } } else { B.Add("There's nothing here to pick up. "); Q0(); } } } else { if (await StunnedThisTurn()) { break; } if (InventoryCount() < Global.MAX_INVENTORY_SIZE) { if (InventoryCount() + tile().inv.quantity <= Global.MAX_INVENTORY_SIZE) { Item i = tile().inv; tile().inv = null; if (i.light_radius > 0) { i.UpdateRadius(i.light_radius, 0); } i.row = -1; i.col = -1; B.Add("You pick up " + i.TheName() + ". "); bool added = false; foreach (Item item in inv) { if (item.itype == i.itype && !item.do_not_stack && !i.do_not_stack) { item.quantity += i.quantity; added = true; break; } } if (!added) { inv.Add(i); } Q1(); } else { int space_left = Global.MAX_INVENTORY_SIZE - InventoryCount(); Item i = tile().inv; Item newitem = new Item(i, row, col); newitem.quantity = space_left; i.quantity -= space_left; B.Add("You pick up " + newitem.TheName() + ", but have no room for the other " + i.quantity.ToString() + ". "); bool added = false; foreach (Item item in inv) { if (item.itype == newitem.itype && !item.do_not_stack && !newitem.do_not_stack) { item.quantity += newitem.quantity; added = true; break; } } if (!added) { inv.Add(newitem); } Q1(); } } else { B.Add("Your pack is too full to pick up " + tile().inv.TheName() + ". "); Q0(); } } break; case "d": if (inv.Count == 0) { B.Add("You have nothing to drop. "); Q0(); } else { int num = -1; Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); char letter = 'a'; int line = 1; foreach (string s in InventoryList()) { string s2 = "[" + (string)letter + "] " + s; Screen.WriteMapString(line, 0, s2.PadRight(COLS)); Screen.WriteMapChar(line, 1, new colorchar(Color.Cyan, letter)); letter++; line++; } //Screen.WriteMapString(line,0,("".PadRight(25,"-") + "[?] for help").PadRight(COLS,"-")); Screen.WriteMapString(line, 0, ("------Space left: " + (Global.MAX_INVENTORY_SIZE - InventoryCount()).ToString().PadRight(7, '-') + "[?] for help").PadRight(COLS, '-')); Screen.WriteMapChar(line, 26, new colorchar(Color.Cyan, "?")); if (line < ROWS) { Screen.WriteMapString(line + 1, 0, "".PadRight(COLS)); } B.DisplayNow("Drop which item? "); Game.Console.CursorVisible = true; while (true) { command = await Game.Console.ReadKey(true); ch = ConvertInput(command); int ii = ch[0] - 'a'; if (ii >= 0 && ii < InventoryList().Count) { num = ii; break; } else { if (ch == "?") { await Help.DisplayHelp(HelpTopic.Items); num = -1; break; } } break; } M.RedrawWithStrings(); if (num != -1) { if (await StunnedThisTurn()) { break; } Item i = inv[num]; if (i.quantity <= 1) { if (tile().ttype == TileType.HEALING_POOL) { B.Add("You drop " + i.TheName() + " into the healing pool. "); inv.Remove(i); if (curhp < maxhp) { B.Add("The pool glows briefly. "); B.Add("You suddenly feel great again! "); B.Add("The healing pool dries up. "); curhp = maxhp; } else { B.Add("The pool glows briefly, then dries up. "); } tile().TurnToFloor(); Q1(); } else { if (tile().GetItem(i)) { B.Add("You drop " + i.TheName() + ". "); inv.Remove(i); i.ignored = true; Q1(); } else { B.Add("There is no room. "); Q0(); } } } else { if (tile().ttype == TileType.HEALING_POOL) { Item newitem = new Item(i, row, col); newitem.quantity = 1; i.quantity--; B.Add("You drop " + newitem.TheName() + " into the healing pool. "); if (curhp < maxhp) { B.Add("The pool glows briefly. "); B.Add("You suddenly feel great again! "); B.Add("The healing pool dries up. "); curhp = maxhp; } else { B.Add("The pool glows briefly, then dries up. "); } tile().TurnToFloor(); Q1(); } else { B.DisplayNow("Drop how many? (1-" + i.quantity + "): "); int count = await Global.EnterInt(); if (count == 0) { Q0(); } else { if (count >= i.quantity || count == -1) { if (tile().GetItem(i)) { B.Add("You drop " + i.TheName() + ". "); inv.Remove(i); i.ignored = true; Q1(); } else { B.Add("There is no room. "); Q0(); } } else { Item newitem = new Item(i, row, col); newitem.quantity = count; if (tile().GetItem(newitem)) { i.quantity -= count; B.Add("You drop " + newitem.TheName() + ". "); newitem.ignored = true; Q1(); } else { B.Add("There is no room. "); Q0(); } } } } } } else { Q0(); } } break; case "i": /* if(inv.Count == 0){ B.Add("You have nothing in your pack. "); } else{ Select("In your pack: ",InventoryList(),true,false,true); Game.Console.CursorVisible = true; Game.Console.ReadKey(true); } Q0(); break;*/ if (inv.Count == 0) { B.Add("You have nothing in your pack. "); Q0(); } else { // int i = Select("Use which item? ",InventoryList()); Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); char letter = 'a'; int line = 1; foreach (string s in InventoryList()) { string s2 = "[" + string.FromCharCode(letter) + "] " + s; Screen.WriteMapString(line, 0, s2.PadRight(COLS)); Screen.WriteMapChar(line, 1, new colorchar(Color.Cyan, letter)); letter++; line++; } Screen.WriteMapString(line, 0, ("------Space left: " + (Global.MAX_INVENTORY_SIZE - InventoryCount()).ToString().PadRight(7, '-') + "[?] for help").PadRight(COLS, '-')); Screen.WriteMapChar(line, 26, new colorchar(Color.Cyan, "?")); if (line < ROWS) { Screen.WriteMapString(line + 1, 0, "".PadRight(COLS)); } B.DisplayNow("In your pack: "); Game.Console.CursorVisible = true; command = await Game.Console.ReadKey(true); ch = ConvertInput(command); if (ch == "?") { await Help.DisplayHelp(HelpTopic.Items); } M.RedrawWithStrings(); Q0(); } break; case "a": if (inv.Count == 0) { B.Add("You have nothing in your pack. "); Q0(); } else { // int i = Select("Use which item? ",InventoryList()); int num = -1; Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); char letter = 'a'; int line = 1; foreach (string s in InventoryList()) { string s2 = "[" + (string)letter + "] " + s; Screen.WriteMapString(line, 0, s2.PadRight(COLS)); Screen.WriteMapChar(line, 1, new colorchar(Color.Cyan, letter)); letter++; line++; } Screen.WriteMapString(line, 0, ("------Space left: " + (Global.MAX_INVENTORY_SIZE - InventoryCount()).ToString().PadRight(7, '-') + "[?] for help").PadRight(COLS, '-')); //Screen.WriteMapString(line,0,("".PadRight(25,"-") + "[?] for help").PadRight(COLS,"-")); Screen.WriteMapChar(line, 26, new colorchar(Color.Cyan, "?")); if (line < ROWS) { Screen.WriteMapString(line + 1, 0, "".PadRight(COLS)); } B.DisplayNow("Apply which item? "); Game.Console.CursorVisible = true; while (true) { command = await Game.Console.ReadKey(true); ch = ConvertInput(command); int ii = ch[0] - 'a'; if (ii >= 0 && ii < InventoryList().Count) { num = ii; break; } else { if (ch == "?") { await Help.DisplayHelp(HelpTopic.Items); num = -1; break; } } break; } M.RedrawWithStrings(); //if(i != -1){ if (num != -1) { if (await StunnedThisTurn()) { break; } //if(inv[i].Use(this)){ if (await inv[num].Use(this)) { Q1(); } else { Q0(); } } else { Q0(); } } break; case "e": { int[] changes = await DisplayEquipment(); WeaponType new_weapon = Weapon.BaseWeapon((WeaponType)changes[0]); ArmorType new_armor = Armor.BaseArmor((ArmorType)changes[1]); WeaponType old_weapon = weapons[0]; ArmorType old_armor = armors[0]; bool weapon_changed = (new_weapon != Weapon.BaseWeapon(old_weapon)); bool armor_changed = (new_armor != Armor.BaseArmor(old_armor)); bool cursed_weapon = false; if (weapon_changed && HasAttr(AttrType.CURSED_WEAPON)) { cursed_weapon = true; weapon_changed = false; } if (!weapon_changed && !armor_changed) { if (cursed_weapon) { B.Add("Your " + Weapon.Name(weapons[0]) + " is stuck to your hand and can't be dropped. "); } Q0(); } else { if (await StunnedThisTurn()) { break; } if (weapon_changed) { bool done = false; while (!done) { WeaponType w = weapons[0]; weapons.Remove(w); weapons.Insert(weapons.Count, w); if (new_weapon == Weapon.BaseWeapon(weapons[0])) { done = true; } } if (HasFeat(FeatType.QUICK_DRAW) && !armor_changed) { B.Add("You quickly ready your " + Weapon.Name(weapons[0]) + ". "); } else { B.Add("You ready your " + Weapon.Name(weapons[0]) + ". "); } UpdateOnEquip(old_weapon, weapons[0]); } if (armor_changed) { bool done = false; while (!done) { ArmorType a = armors[0]; armors.Remove(a); armors.Insert(armors.Count, a); if (new_armor == Armor.BaseArmor(armors[0])) { done = true; } } B.Add("You wear your " + Armor.Name(armors[0]) + ". "); UpdateOnEquip(old_armor, armors[0]); } if (cursed_weapon) { B.Add("Your " + Weapon.Name(weapons[0]) + " is stuck to your hand and can't be dropped. "); } if (HasFeat(FeatType.QUICK_DRAW) && !armor_changed) { Q0(); } else { Q1(); } } break; } case "!": //note that these are the top-row numbers, NOT the actual shifted versions case "@": //<---this is the "2" above the "w" (not the "@", and not the numpad 2) case "#": case "$": case "%": { if (HasAttr(AttrType.CURSED_WEAPON)) { B.Add("Your " + Weapon.Name(weapons[0]) + " is stuck to your hand and can't be dropped. "); Q0(); } else { WeaponType new_weapon = WeaponType.NO_WEAPON; switch (ch) { case "!": new_weapon = WeaponType.SWORD; break; case "@": new_weapon = WeaponType.MACE; break; case "#": new_weapon = WeaponType.DAGGER; break; case "$": new_weapon = WeaponType.STAFF; break; case "%": new_weapon = WeaponType.BOW; break; } WeaponType old_weapon = weapons[0]; if (new_weapon == Weapon.BaseWeapon(old_weapon)) { Q0(); } else { if (await StunnedThisTurn()) { break; } bool done = false; while (!done) { WeaponType w = weapons[0]; weapons.Remove(w); weapons.Insert(weapons.Count, w); if (new_weapon == Weapon.BaseWeapon(weapons[0])) { done = true; } } if (HasFeat(FeatType.QUICK_DRAW)) { B.Add("You quickly ready your " + Weapon.Name(weapons[0]) + ". "); Q0(); } else { B.Add("You ready your " + Weapon.Name(weapons[0]) + ". "); Q1(); } UpdateOnEquip(old_weapon, weapons[0]); } } break; } case "*": //these are toprow numbers, not shifted versions. see above. case "(": case ")": { ArmorType new_armor = ArmorType.NO_ARMOR; switch (ch) { case "*": new_armor = ArmorType.LEATHER; break; case "(": new_armor = ArmorType.CHAINMAIL; break; case ")": new_armor = ArmorType.FULL_PLATE; break; } ArmorType old_armor = armors[0]; if (new_armor == Armor.BaseArmor(old_armor)) { Q0(); } else { if (await StunnedThisTurn()) { break; } bool done = false; while (!done) { ArmorType a = armors[0]; armors.Remove(a); armors.Insert(armors.Count, a); if (new_armor == Armor.BaseArmor(armors[0])) { done = true; } } B.Add("You wear your " + Armor.Name(armors[0]) + ". "); Q1(); UpdateOnEquip(old_armor, armors[0]); } break; } case "t": if (await StunnedThisTurn()) { break; } if (light_radius == 0) { if (HasAttr(AttrType.ENHANCED_TORCH)) { UpdateRadius(LightRadius(), Global.MAX_LIGHT_RADIUS - attrs[AttrType.DIM_LIGHT] * 2, true); } else { UpdateRadius(LightRadius(), 6 - attrs[AttrType.DIM_LIGHT], true); //normal light radius is 6 } if (!M.wiz_dark) { B.Add("You bring out your torch. "); } else { B.Add("You bring out your torch, but it gives off no light! "); } } else { UpdateRadius(LightRadius(), 0, true); UpdateRadius(0, attrs[AttrType.ON_FIRE]); if (!M.wiz_lite) { B.Add("You put away your torch. "); } else { B.Add("You put away your torch. The air still shines brightly. "); } } Q1(); break; case "\u000D": await GetTarget(true, -1, true); Q0(); break; case "p": { Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); int i = 1; foreach (string s in B.GetMessages()) { Screen.WriteMapString(i, 0, s.PadRight(COLS)); ++i; } Screen.WriteMapString(21, 0, "".PadRight(COLS, '-')); B.DisplayNow("Previous messages: "); Game.Console.CursorVisible = true; await Game.Console.ReadKey(true); Q0(); break; } case "c": DisplayCharacterInfo(); Q0(); break; case "O": case "=": { for (bool done = false; !done; ) { List<string> ls = new List<string>(); ls.Add("Use last target when possible".PadRight(58) + (Global.Option(OptionType.LAST_TARGET) ? "yes " : "no ").PadLeft(4)); ls.Add("Automatically pick up items (if safe)".PadRight(58) + (Global.Option(OptionType.AUTOPICKUP) ? "yes " : "no ").PadLeft(4)); ls.Add("Hide old messages instead of darkening them".PadRight(58) + (Global.Option(OptionType.HIDE_OLD_MESSAGES) ? "yes " : "no ").PadLeft(4)); ls.Add("Hide the command hints on the side".PadRight(58) + (Global.Option(OptionType.HIDE_COMMANDS) ? "yes " : "no ").PadLeft(4)); ls.Add("Cast a spell instead of attacking".PadRight(46) + (F[0] == SpellType.NO_SPELL ? "no " : Spell.Name(F[0])).PadLeft(16)); ls.Add("Don't use roman numerals for automatic naming".PadRight(58) + (Global.Option(OptionType.NO_ROMAN_NUMERALS) ? "yes " : "no ").PadLeft(4)); ls.Add("Never show tutorial tips".PadRight(58) + (Global.Option(OptionType.NEVER_DISPLAY_TIPS) ? "yes " : "no ").PadLeft(4)); ls.Add("Reset tutorial tips before each game".PadRight(58) + (Global.Option(OptionType.ALWAYS_RESET_TIPS) ? "yes " : "no ").PadLeft(4)); await Select("Options: ", ls, true, false, false); Game.Console.CursorVisible = true; ch = ConvertInput(await Game.Console.ReadKey(true)); switch (ch) { case "a": Global.Options[OptionType.LAST_TARGET] = !Global.Option(OptionType.LAST_TARGET); break; case "b": Global.Options[OptionType.AUTOPICKUP] = !Global.Option(OptionType.AUTOPICKUP); break; case "c": Global.Options[OptionType.HIDE_OLD_MESSAGES] = !Global.Option(OptionType.HIDE_OLD_MESSAGES); break; case "d": Global.Options[OptionType.HIDE_COMMANDS] = !Global.Option(OptionType.HIDE_COMMANDS); break; case "e": { if (skills[Forays.SkillType.MAGIC] > 0) { M.RedrawWithStrings(); List<colorstring> list = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); bool bonus_marked = false; foreach (SpellType spell in spells_in_order) { if (HasSpell(spell)) { colorstring cs = new colorstring(Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3), Color.Gray); cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%", FailColor(spell))); if (HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked) { bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else { cs = cs + Spell.Description(spell); } list.Add(cs); sp.Add(spell); } } if (sp.Count > 0) { colorstring topborder = new colorstring("------------------Level---Fail rate--------Description------------", Color.Gray); int basefail = magic_penalty * 5; if (!HasFeat(FeatType.ARMORED_MAGE)) { basefail += Armor.AddedFailRate(armors[0]); } colorstring bottomborder = new colorstring("------------Base fail rate: ", Color.Gray, (basefail.ToString().PadLeft(3) + "%"), FailColor(basefail), "".PadRight(37, '-'), Color.Gray); int i = await Select("Automatically cast which spell? ", topborder, bottomborder, list, false, false, false, false, HelpTopic.Overview); if (i != -1) { F[0] = sp[i]; } else { F[0] = SpellType.NO_SPELL; } } } break; } case "f": Global.Options[OptionType.NO_ROMAN_NUMERALS] = !Global.Option(OptionType.NO_ROMAN_NUMERALS); break; case "g": Global.Options[OptionType.NEVER_DISPLAY_TIPS] = !Global.Option(OptionType.NEVER_DISPLAY_TIPS); break; case "h": Global.Options[OptionType.ALWAYS_RESET_TIPS] = !Global.Option(OptionType.ALWAYS_RESET_TIPS); break; case "\u001B": case " ": case "\u000D": done = true; break; default: break; } } Q0(); break; } case "?": case "/": { await Help.DisplayHelp(); Q0(); break; } case "-": { Game.Console.CursorVisible = false; List<string> commandhelp = Help.HelpText(HelpTopic.Commands); commandhelp.RemoveRange(0, 2); Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); for (int i = 0; i < 20; ++i) { Screen.WriteMapString(i + 1, 0, commandhelp[i].PadRight(COLS)); } Screen.WriteMapString(ROWS - 1, 0, "".PadRight(COLS, '-')); B.DisplayNow("Commands: "); Game.Console.CursorVisible = true; await Game.Console.ReadKey(true); Q0(); break; } case "q": { List<string> ls = new List<string>(); ls.Add("Save your progress and exit to main menu"); ls.Add("Save your progress and quit game"); ls.Add("Abandon character and exit to main menu"); ls.Add("Abandon character and quit game"); ls.Add("Quit game immediately - don't save anything"); ls.Add("Continue playing"); Game.Console.CursorVisible = true; switch (await Select("Quit? ", ls)) { case 0: Global.SaveGame(B, M, Q); Global.GAME_OVER = true; Global.SAVING = true; break; case 1: Global.SaveGame(B, M, Q); Global.GAME_OVER = true; Global.QUITTING = true; Global.SAVING = true; break; case 2: Global.GAME_OVER = true; Global.KILLED_BY = "giving up"; break; case 3: Global.GAME_OVER = true; Global.QUITTING = true; Global.KILLED_BY = "giving up"; break; case 4: Global.Quit(); break; case 5: default: break; } Q0(); break; } case "~": //debug mode if (false) { List<string> l = new List<string>(); l.Add("Throw a prismatic orb"); l.Add("create chests"); l.Add("Create a poison gas vent"); l.Add("create fog"); l.Add("Forget the map"); l.Add("Heal to full"); l.Add("Become invulnerable"); l.Add("get items!"); l.Add("Spawn a monster"); l.Add("Use a rune of passage"); l.Add("See the entire level"); l.Add("Generate new level"); l.Add("Gain all skills and feats"); l.Add("Spawn shrines"); l.Add("create trap"); l.Add("create door"); l.Add("spawn lots of goblins and lose neck snap"); l.Add("remove all enemies, spawn boss"); l.Add("detect monsters forever"); l.Add("trigger floor collapse"); switch (await Select("Activate which cheat? ", l)) { case 0: { await new Item(ConsumableType.PRISMATIC, "prismatic orb", "*", Color.White).Use(this); Q1(); break; } case 1: { foreach (Tile t in TilesWithinDistance(3)) { t.TransformTo(TileType.CHEST); } Q0(); //Screen.AnimateExplosion(this,5,new colorchar(Color.RandomIce,"*"),25); //Q1(); break; } case 2: { List<Tile> line = await GetTarget(-1, -1); if (line != null) { Tile t = line.Last(); /*if(t != null && t.inv == null){ Item.Create(Item.RandomItem(),t.row,t.col); t.inv.do_not_stack = true; Q.Add(new Event(t.inv,new List<Tile>{t},100,Forays.EventType.MIMIC,AttrType.NO_ATTR,0,"")); }*/ if (t != null) { /*t.TransformTo(TileType.FIRE_GEYSER); int frequency = Global.Roll(21) + 4; //5-25 int variance = Global.Roll(10) - 1; //0-9 int variance_amount = (frequency * variance) / 10; int number_of_values = variance_amount*2 + 1; int minimum_value = frequency - variance_amount; if(minimum_value < 5){ int diff = 5 - minimum_value; number_of_values -= diff; minimum_value = 5; } int delay = ((minimum_value - 1) + Global.Roll(number_of_values)) * 100; Q.Add(new Event(t,delay + 200,EventType.FIRE_GEYSER,(frequency*10)+variance)); //notice the hacky way the value is stored Q.Add(new Event(t,delay,EventType.FIRE_GEYSER_ERUPTION,2));*/ t.TransformTo(TileType.POISON_GAS_VENT); Q.Add(new Event(t, 100, EventType.POISON_GAS_VENT)); } } Q0(); break; } case 3: { //ConsoleKeyInfo command2 = Game.Console.ReadKey(true); //Game.Console.Write(command2.Key); List<Tile> line = await GetTarget(-1, -1); if (line != null) { Tile t = line.Last(); if (t != null) { t.AddOpaqueFeature(FeatureType.FOG); } } Q0(); break; } case 4: { Game.Console.CursorVisible = false; colorchar cch; cch.c = " "; cch.color = Color.Black; cch.bgcolor = Color.Black; foreach (Tile t in M.AllTiles()) { t.seen = false; Screen.WriteMapChar(t.row, t.col, cch); } Game.Console.CursorVisible = true; Q0(); break; } case 5: curhp = maxhp; Q0(); break; case 6: if (!HasAttr(AttrType.INVULNERABLE)) { attrs[AttrType.INVULNERABLE]++; B.Add("On. "); } else { attrs[AttrType.INVULNERABLE] = 0; B.Add("Off. "); } Q0(); break; case 7: { for (int i = 0; i < 50; ++i) { Item.Create(Item.RandomItem(), this); } Q0(); break; } case 8: //Create(ActorType.CULTIST,18,50); M.SpawnMob(ActorType.DIRE_RAT); Q1(); break; case 9: await new Item(ConsumableType.PASSAGE, "rune of passage", "&", Color.White).Use(this); Q1(); break; case 10: foreach (Tile t in M.AllTiles()) { t.seen = true; } M.Draw(); foreach (Actor a in M.AllActors()) { Screen.WriteMapChar(a.row, a.col, new colorchar(a.color, Color.Black, a.symbol)); } await Game.Console.ReadKey(true); Q0(); break; case 11: await M.GenerateLevel(); Q0(); break; case 12: { /*Tile t = await GetTarget(); if(t != null){ TileType oldtype = t.type; t.TransformTo(TileType.GRENADE); t.toggles_into = oldtype; t.passable = Tile.Prototype(oldtype).passable; t.opaque = Tile.Prototype(oldtype).opaque; switch(oldtype){ case TileType.FLOOR: t.the_name = "the grenade on the floor"; t.a_name = "a grenade on a floor"; break; case TileType.STAIRS: t.the_name = "the grenade on the stairway"; t.a_name = "a grenade on a stairway"; break; case TileType.DOOR_O: t.the_name = "the grenade in the open door"; t.a_name = "a grenade in an open door"; break; default: t.the_name = "the grenade and " + Tile.Prototype(oldtype).the_name; t.a_name = "a grenade and " + Tile.Prototype(oldtype).a_name; break; } Q.Add(new Event(t,100,EventType.GRENADE)); }*/ level = 10; skills[SkillType.COMBAT] = 10; skills[SkillType.DEFENSE] = 10; skills[SkillType.MAGIC] = 10; skills[SkillType.SPIRIT] = 10; skills[SkillType.STEALTH] = 10; foreach (FeatType f in GetFeatTypes()) { if (f != FeatType.NO_FEAT && f != FeatType.NUM_FEATS) { feats[f] = 1; } } Q0(); B.Add("\"I HAVE THE POWERRRR!\" "); break; } case 13: { //LevelUp(); foreach (Tile t in TilesWithinDistance(2)) { t.TransformTo((TileType)(Global.Roll(5) + 20)); } Q0(); break; } case 14: { foreach (Tile t in TilesAtDistance(1)) { t.TransformTo(Tile.RandomTrap()); } Q0(); break; } case 15: { List<Tile> line = await GetTarget(-1, -1); if (line != null) { Tile t = line.Last(); if (t != null) { t.TransformTo(TileType.DOOR_O); } } Q0(); break; } case 16: { for (int i = 0; i < 100; ++i) { M.SpawnMob(ActorType.GOBLIN); } if (HasFeat(FeatType.NECK_SNAP)) { feats[FeatType.NECK_SNAP] = 0; } Q0(); break; } case 17: { foreach (Actor a in M.AllActors()) { if (a != this) { Q.KillEvents(a, Forays.EventType.ANY_EVENT); M.RemoveTargets(a); M.actor[a.p] = null; } } foreach (Tile t in M.AllTiles()) { if (t.passable && t.actor() == null) { Create(ActorType.FIRE_DRAKE, t.row, t.col, true, false); break; } } Q0(); break; } case 18: { if (attrs[Forays.AttrType.DETECTING_MONSTERS] == 0) { attrs[Forays.AttrType.DETECTING_MONSTERS] = 1; } else { attrs[Forays.AttrType.DETECTING_MONSTERS] = 0; } Q0(); break; } case 19: { List<Tile> line = await GetTarget(-1, -1); if (line != null) { Tile t = line.Last(); if (t != null) { t.Toggle(null, TileType.CHASM); Q.Add(new Event(t, 100, EventType.FLOOR_COLLAPSE)); B.Add("The floor begins to collapse! "); } } Q0(); break; } default: Q0(); break; } } else { Q0(); } break; case " ": Q0(); break; default: B.Add("Press '?' for help. "); Q0(); break; } if (ch != "x") { attrs[Forays.AttrType.AUTOEXPLORE] = 0; } return false; }
public async Task<int> Select(string message, colorstring top_border, colorstring bottom_border, List<colorstring> strings, bool no_ask, bool no_cancel, bool easy_cancel, bool help_key, HelpTopic help_topic) { int result = -2; while (result == -2) { Screen.WriteMapString(0, 0, top_border); char letter = 'a'; int i = 1; foreach (colorstring s in strings) { Screen.WriteMapString(i, 0, new colorstring("[", Color.Gray, (string)letter, Color.Cyan, "] ", Color.Gray)); Screen.WriteMapString(i, 4, s); letter++; i++; } Screen.WriteMapString(i, 0, bottom_border); if (i < ROWS - 1) { Screen.WriteMapString(i + 1, 0, "".PadRight(COLS)); } if (no_ask) { B.DisplayNow(message); return -1; } else { result = await GetSelection(message, strings.Count, no_cancel, easy_cancel, help_key); if (result == -2) { await Help.DisplayHelp(help_topic); } else { M.RedrawWithStrings(); return result; } } } return -1; }
public async void IncreaseSkill(SkillType skill) { List<string> learned = new List<string>(); skills[skill]++; B.Add("You feel a rush of power. "); //DisplayStats(); await B.PrintAll(); ConsoleKeyInfo command; FeatType feat_increased = FeatType.NO_FEAT; bool done = false; while (!done) { Screen.ResetColors(); Screen.WriteMapString(0, 0, "".PadRight(COLS, '-')); for (int i = 0; i < 4; ++i) { FeatType ft = Feat.OfSkill(skill, i); Color featcolor = (feat_increased == ft) ? Color.Green : Color.Gray; Color lettercolor = Color.Cyan; int featlevel = (feat_increased == ft) ? (-feats[ft]) + 1 : (-feats[ft]); if (HasFeat(ft)) { featcolor = Color.Magenta; lettercolor = Color.DarkRed; featlevel = Feat.MaxRank(ft); } Screen.WriteMapString(1 + i * 5, 0, ("[" + string.FromCharCode((char)(i + 97)) + "] ")); Screen.WriteMapChar(1 + i * 5, 1, string.FromCharCode((char)(i + 97)), lettercolor); Screen.WriteMapString(1 + i * 5, 4, Feat.Name(ft).PadRight(21) + "(" + featlevel + "/" + Feat.MaxRank(ft) + ")", featcolor); if (Feat.IsActivated(ft)) { Screen.WriteMapString(1 + i * 5, 30, " Active".PadToMapSize()); } else { Screen.WriteMapString(1 + i * 5, 30, " Passive".PadToMapSize()); } List<string> desc = Feat.Description(ft); for (int j = 0; j < 4; ++j) { if (desc.Count > j) { Screen.WriteMapString(2 + j + i * 5, 0, " " + desc[j].PadRight(64)); } else { Screen.WriteMapString(2 + j + i * 5, 0, "".PadRight(66)); } } } if (feat_increased != FeatType.NO_FEAT) { Screen.WriteMapString(21, 0, "--Type [a-d] to choose a feat---[?] for help---[Enter] to accept--"); Screen.WriteMapChar(21, 8, new colorchar(Color.Cyan, 'a')); Screen.WriteMapChar(21, 10, new colorchar(Color.Cyan, 'd')); Screen.WriteMapChar(21, 33, new colorchar(Color.Cyan, '?')); Screen.WriteMapString(21, 48, new cstr(Color.Magenta, "Enter")); } else { Screen.WriteMapString(21, 0, "--Type [a-d] to choose a feat---[?] for help----------------------"); Screen.WriteMapChar(21, 8, new colorchar(Color.Cyan, 'a')); Screen.WriteMapChar(21, 10, new colorchar(Color.Cyan, 'd')); Screen.WriteMapChar(21, 33, new colorchar(Color.Cyan, '?')); } B.DisplayNow("Your " + Skill.Name(skill) + " skill increases to " + skills[skill] + ". Choose a feat: "); if (!Help.displayed[TutorialTopic.Feats]) { await Help.TutorialTip(TutorialTopic.Feats); B.DisplayNow("Your " + Skill.Name(skill) + " skill increases to " + skills[skill] + ". Choose a feat: "); } Game.Console.CursorVisible = true; command = await Game.Console.ReadKey(true); Game.Console.CursorVisible = false; string ch = ConvertInput(command); switch (ch) { case "a": case "b": case "c": case "d": { FeatType ft = Feat.OfSkill(skill, (int)(ch[0] - 97)); if (feat_increased == ft) { feat_increased = FeatType.NO_FEAT; } else { if (feat_increased == FeatType.NO_FEAT && !HasFeat(ft)) { feat_increased = ft; } } break; } case "?": await Help.DisplayHelp(HelpTopic.Feats); DisplayStats(); break; case "\u000D": if (feat_increased != FeatType.NO_FEAT) { done = true; } break; default: break; } } feats[feat_increased]--; //negative values are used until you've completely learned a feat partial_feats_in_order.AddUnique(feat_increased); if (feats[feat_increased] == -(Feat.MaxRank(feat_increased))) { feats[feat_increased] = 1; partial_feats_in_order.Remove(feat_increased); feats_in_order.Add(feat_increased); learned.Add("You master the " + Feat.Name(feat_increased) + " feat. "); } else { string points = "points"; if (Feat.MaxRank(feat_increased) + feats[feat_increased] == 1) { points = "point"; } if (feats[feat_increased] == -1) { learned.Add("You start learning the " + Feat.Name(feat_increased) + " feat (" + (Feat.MaxRank(feat_increased) + feats[feat_increased]) + " " + points + " left). "); } else { learned.Add("You continue learning the " + Feat.Name(feat_increased) + " feat (" + (Feat.MaxRank(feat_increased) + feats[feat_increased]) + " " + points + " left). "); } } if (skill == SkillType.MAGIC) { List<SpellType> unknown = new List<SpellType>(); List<colorstring> unknownstr = new List<colorstring>(); foreach (SpellType spell in GetSpellTypes()) { if (!HasSpell(spell) && spell != SpellType.BLESS && spell != SpellType.MINOR_HEAL && spell != SpellType.HOLY_SHIELD && spell != SpellType.NO_SPELL && spell != SpellType.NUM_SPELLS) { unknown.Add(spell); colorstring cs = new colorstring(); cs.strings.Add(new cstr(Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3), Color.Gray)); int failrate = (Spell.Level(spell) - TotalSkill(SkillType.MAGIC)) * 5; if (failrate < 0) { failrate = 0; } cs.strings.Add(new cstr(failrate.ToString().PadLeft(9) + "%", FailColor(failrate))); unknownstr.Add(cs + Spell.Description(spell)); } } for (int i = unknown.Count + 2; i < ROWS; ++i) { Screen.WriteMapString(i, 0, "".PadRight(COLS)); } colorstring topborder = new colorstring("------------------Level---Fail rate--------Description------------", Color.Gray); int selection = await Select("Learn which spell? ", topborder, new colorstring("".PadRight(25, '-') + "[", Color.Gray, "?", Color.Cyan, "] for help".PadRight(COLS, '-'), Color.Gray), unknownstr, false, true, false, true, HelpTopic.Spells); spells[unknown[selection]] = 1; learned.Add("You learn " + Spell.Name(unknown[selection]) + ". "); spells_in_order.Add(unknown[selection]); } if (learned.Count > 0) { foreach (string s in learned) { B.Add(s); } } }
public async Task<bool> UseFeat(FeatType feat) { switch (feat) { case FeatType.LUNGE: { List<Tile> line = await GetTarget(2); Tile t = null; if (line != null) { t = line.Last(); } if (t != null && t.actor() != null) { bool moved = false; /*foreach(Tile neighbor in t.NeighborsBetween(row,col)){ if(neighbor.passable && neighbor.actor() == null){ moved = true; B.Add("You lunge! "); Move(neighbor.row,neighbor.col); attrs[AttrType.BONUS_COMBAT] += 4; Attack(0,t.actor()); attrs[AttrType.BONUS_COMBAT] -= 4; break; } }*/ if (DistanceFrom(t) == 2 && line[1].passable && line[1].actor() == null && !GrabPreventsMovement(line[1])) { moved = true; B.Add("You lunge! "); await Move(line[1].row, line[1].col); attrs[AttrType.BONUS_COMBAT] += 4; await Attack(0, t.actor()); attrs[AttrType.BONUS_COMBAT] -= 4; } if (!moved) { if (GrabPreventsMovement(line[1])) { B.Add("You can't currently reach that spot. "); return false; } else { B.Add("The way is blocked! "); return false; } } else { MakeNoise(); return true; } } else { return false; } //break; } case FeatType.TUMBLE: /*Tumble - (A, 200 energy) - You pick a tile within distance 2. If there is at least one passable tile between you and it(you CAN tumble past actors), you move to that tile. Additional effects: If you move past an actor, they lose sight of you and their turns_target_location is set to X - rand_function_of(stealth skill). (there's a good chance they'll find you, then attack, but you will have still moved past them) ; You will automatically dodge the first arrow that would hit you before your next turn.(it's still possible they'll roll 2 successes and hit you) ; Has the same effect as standing still, if you're on fire or catching fire. */ { target = null; //don't try to automatically pick previous targets while tumbling. this solution isn't ideal. List<Tile> line = await GetTarget(false, 2, false); target = null; //then, don't remember an actor picked as the target of tumble Tile t = null; if (line != null) { t = line.Last(); } if (t != null && t.passable && t.actor() == null && !GrabPreventsMovement(t)) { List<Actor> actors_moved_past = new List<Actor>(); bool moved = false; foreach (Tile neighbor in t.NeighborsBetween(row, col)) { if (neighbor.actor() != null) { actors_moved_past.Add(neighbor.actor()); } if (neighbor.passable && !moved) { B.Add("You tumble. "); await Move(t.row, t.col); moved = true; attrs[AttrType.TUMBLING]++; if (HasAttr(AttrType.CATCHING_FIRE)) { //copy&paste happened here: todo, make a single fire-handling method attrs[AttrType.CATCHING_FIRE] = 0; B.Add("You stop the flames from spreading. "); if (HasAttr(AttrType.STARTED_CATCHING_FIRE_THIS_TURN)) { attrs[AttrType.STARTED_CATCHING_FIRE_THIS_TURN] = 0; B.Add("You stop the flames from spreading. "); } } else { if (HasAttr(AttrType.STARTED_CATCHING_FIRE_THIS_TURN)) { attrs[AttrType.STARTED_CATCHING_FIRE_THIS_TURN] = 0; B.Add("You stop the flames from spreading. "); } else { if (HasAttr(AttrType.ON_FIRE)) { bool update = false; int oldradius = LightRadius(); if (attrs[AttrType.ON_FIRE] > light_radius) { update = true; } int i = 2; if (Global.Roll(1, 3) == 3) { // 1 in 3 times, you don't make progress against the fire i = 1; } attrs[AttrType.ON_FIRE] -= i; if (attrs[AttrType.ON_FIRE] < 0) { attrs[AttrType.ON_FIRE] = 0; } if (update) { UpdateRadius(oldradius, LightRadius()); } if (HasAttr(AttrType.ON_FIRE)) { B.Add("You put out some of the fire. "); } else { B.Add("You put out the fire. "); } } } } } } if (moved) { foreach (Actor a in actors_moved_past) { int i = 10 - Global.Roll(Stealth()); if (i < 0) { i = 0; } a.player_visibility_duration = i; } Q.Add(new Event(this, 200, EventType.MOVE)); return true; } else { B.Add("The way is blocked! "); return false; } } else { if (GrabPreventsMovement(t)) { B.Add("You can't currently reach that spot. "); } return false; } //break; } case FeatType.ARCANE_SHIELD: //25% fail rate for the 'failrate' feats if (magic_penalty < 20) { /*if(curhp < maxhp){ here's the old arcane healing feat magic_penalty += 5; if(magic_penalty > 20){ magic_penalty = 20; } B.Add("You drain your magic reserves. "); int amount = Global.Roll(TotalSkill(SkillType.MAGIC)/2,6) + 25; TakeDamage(DamageType.HEAL,DamageClass.NO_TYPE,amount,null); if(curhp == maxhp){ B.Add("Your wounds close. "); } else{ B.Add("Some of your wounds close. "); } } else{ B.Add("You're not injured. "); return false; }*/ magic_penalty += 5; if (magic_penalty > 20) { magic_penalty = 20; } B.Add("You drain your magic reserves. "); int amount = Global.Roll(TotalSkill(SkillType.MAGIC) / 2, 6) + 25; if (HasAttr(AttrType.ARCANE_SHIELDED)) { B.Add("You strengthen your arcane barrier. "); } else { B.Add("An arcane barrier surrounds you. "); } attrs[Forays.AttrType.ARCANE_SHIELDED] += amount; Q.KillEvents(this, AttrType.ARCANE_SHIELDED); Q.Add(new Event(this, 2000, Forays.AttrType.ARCANE_SHIELDED, "Your arcane shield dissolves. ")); } else { B.Add("Your magic reserves are empty! "); return false; } break; case FeatType.FORCE_OF_WILL: foreach (Actor a in ActorsWithinDistance(2)) { if (a.HasAttr(AttrType.SPELL_DISRUPTION) && a.HasLOE(this)) { if (this == player) { if (CanSee(a)) { B.Add(a.Your() + " presence prevents you from casting! "); } else { B.Add("Something prevents you from casting! "); } } return false; } } if (magic_penalty < 20) { int basefail = magic_penalty * 5; basefail -= skills[SkillType.SPIRIT] * 2; if (basefail > 100) { basefail = 100; } if (basefail < 0) { basefail = 0; } List<colorstring> ls = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); bool bonus_marked = false; foreach (SpellType spell in spells_in_order) { if (HasSpell(spell)) { colorstring cs = new colorstring(Spell.Name(spell).PadRight(15) + Spell.Level(spell).ToString().PadLeft(3), Color.Gray); cs.strings.Add(new cstr(basefail.ToString().PadLeft(9) + "%", FailColor(basefail))); if (HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked) { bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else { cs = cs + Spell.Description(spell); } ls.Add(cs); sp.Add(spell); } } if (sp.Count > 0) { colorstring topborder = new colorstring("------------------Level---Fail rate--------Description------------", Color.Gray); colorstring bottomborder = new colorstring("---Force of will fail rate: ", Color.Gray, (basefail.ToString().PadLeft(3) + "%"), FailColor(basefail), "".PadRight(37, '-'), Color.Gray); int i = await Select("Use force of will to cast which spell? ", topborder, bottomborder, ls, false, false, true, true, HelpTopic.Spells); if (i != -1) { if (true != await CastSpell(sp[i], true)) { Q0(); return true; } else { //drained magic is now handled in CastSpell return true; } } else { Q0(); return true; } } else { Q0(); return true; } } else { B.Add("Your magic reserves are empty! "); return false; } //break; case FeatType.DISARM_TRAP: { int dir = await GetDirection("Disarm which trap? "); if (dir != -1 && TileInDirection(dir).IsKnownTrap()) { if (ActorInDirection(dir) != null) { B.Add("There is " + ActorInDirection(dir).AVisible() + " in the way. "); } else { if (GrabPreventsMovement(TileInDirection(dir))) { B.Add("You can't currently reach that trap. "); Q0(); return true; } if (Global.Roll(5) <= 4) { B.Add("You disarm " + Tile.Prototype(TileInDirection(dir).ttype).the_name + ". "); TileInDirection(dir).Toggle(this); Q1(); } else { if (Global.Roll(20) <= skills[SkillType.DEFENSE]) { B.Add("You almost set off " + Tile.Prototype(TileInDirection(dir).ttype).the_name + "! "); Q1(); } else { B.Add("You set off " + Tile.Prototype(TileInDirection(dir).ttype).the_name + "! "); await Move(TileInDirection(dir).row, TileInDirection(dir).col); Q1(); } } } } else { Q0(); } return true; } case FeatType.DISTRACT: { List<Tile> line = await GetTarget(12, 3); Tile t = null; if (line != null) { t = line.Last(); } if (t != null) { if (!t.passable) { t = line.LastBeforeSolidTile(); } B.Add("You throw a small stone. "); foreach (Actor a in t.ActorsWithinDistance(3)) { if (a != this && a.player_visibility_duration >= 0) { if (a.HasAttr(AttrType.DISTRACTED)) { B.Add(a.the_name + " isn't fooled. ", a); a.player_visibility_duration = 999; //automatic detection next turn } else { List<pos> p = a.GetPath(t); if (p.Count <= 6) { a.path = p; if (Global.CoinFlip()) { a.attrs[Forays.AttrType.DISTRACTED]++; } } } } } } else { return false; } break; } default: return false; } Q1(); return true; }
public void InputHuman() { if(HasAttr(AttrType.DETECTING_MOVEMENT) && footsteps.Count > 0 && time_of_last_action < Q.turn){ Screen.CursorVisible = false; Screen.AnimateMapCells(footsteps,new colorchar('!',Color.Red)); previous_footsteps = footsteps; footsteps = new List<pos>(); } if(HasAttr(AttrType.SWITCHING_ARMOR)){ attrs[AttrType.SWITCHING_ARMOR]--; } if(HasFeat(FeatType.DANGER_SENSE)){ M.UpdateDangerValues(); } Screen.UpdateScreenCenterColumn(col); M.Draw(); UI.MapCursor = new pos(-1,-1); UI.DisplayStats(); if(HasAttr(AttrType.AUTOEXPLORE) && !grab_item_at_end_of_path){ if(path.Count == 0){ //todo: autoexplore could also track whether the current path is leading to an unexplored tile instead of to an item/shrine/etc. if(!FindAutoexplorePath()){ // - in this case I could check that tile's neighbors each turn, and calculate a new path early if they've all been mapped now. B.Add("You don't see a path for further exploration. "); } } } if(!HasAttr(AttrType.PARALYZED) && !HasAttr(AttrType.ASLEEP)){ B.Print(false); } else{ B.DisplayNow(); } Cursor(); Screen.CursorVisible = true; if(HasAttr(AttrType.PARALYZED,AttrType.ASLEEP)){ if(HasAttr(AttrType.ASLEEP)){ Thread.Sleep(25); } Q1(); return; } if(HasAttr(AttrType.ENRAGED) && !HasAttr(AttrType.FROZEN)){ Thread.Sleep(100); EnragedMove(); return; } bool pick_up = false; if(tile().inv != null || tile().type == TileType.CHEST){ if(grab_item_at_end_of_path && path.Count == 0){ pick_up = true; } if((Global.Option(OptionType.AUTOPICKUP) && InventoryCount() < Global.MAX_INVENTORY_SIZE && (tile().type == TileType.CHEST || !tile().inv.ignored))){ pick_up = true; } } if(pick_up){ if(!NextStepIsDangerous(tile())){ if(StunnedThisTurn()){ return; } if(tile().type == TileType.CHEST){ tile().OpenChest(); if(tile().type != TileType.CHEST){ grab_item_at_end_of_path = false; } Q1(); } else{ if(InventoryCount() + tile().inv.quantity <= Global.MAX_INVENTORY_SIZE){ Item i = tile().inv; tile().inv = null; if(i.light_radius > 0){ i.UpdateRadius(i.light_radius,0); } i.row = -1; i.col = -1; B.Add("You pick up " + i.TheName() + ". "); GetItem(i); Q1(); } else{ Item i = tile().inv; int space_left = Global.MAX_INVENTORY_SIZE - InventoryCount(); if(space_left <= 0){ B.Add("You have no room for " + i.TheName() + ". "); i.ignored = true; Q0(); } else{ Item newitem = new Item(i,row,col); newitem.quantity = space_left; i.quantity -= space_left; B.Add("You pick up " + newitem.TheName() + ", but have no room for the other " + i.quantity.ToString() + ". "); i.ignored = true; GetItem(newitem); Q1(); } } grab_item_at_end_of_path = false; } return; } } if(path.Count > 0){ if(!NextStepIsDangerous(M.tile[path[0]])){ if(Input.KeyIsAvailable()){ ConsoleKeyInfo key = Input.ReadKey(); if(key.GetCommandChar() == 'x' && HasAttr(AttrType.AUTOEXPLORE)){ PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } return; } else{ Interrupt(); } } else{ PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } return; } } else{ Interrupt(); } } if(HasAttr(AttrType.RUNNING)){ Tile next = TileInDirection(attrs[AttrType.RUNNING]); if(!NextStepIsDangerous(next) && !Input.KeyIsAvailable()){ if(attrs[AttrType.RUNNING] == 5){ bool recover = false; if(!HasAttr(AttrType.NONLIVING)){ if(HasFeat(FeatType.ENDURING_SOUL) && curhp % 10 != 0){ recover = true; } if(HasAttr(AttrType.BANDAGED)){ recover = true; } } if(!recover){ if(HasAttr(AttrType.WAITING)){ attrs[AttrType.WAITING]--; Q1(); return; } else{ attrs[AttrType.RUNNING] = 0; } } else{ Q1(); return; } } else{ bool corridor = true; foreach(int dir in U.FourDirections){ if(TileInDirection(dir).passable && TileInDirection(dir.RotateDir(true,1)).passable && TileInDirection(dir.RotateDir(true,2)).passable){ corridor = false; break; } } List<Tile> tiles = new List<Tile>(); if(corridor){ List<int> blocked = new List<int>(); for(int i=-1;i<=1;++i){ blocked.Add(attrs[AttrType.RUNNING].RotateDir(true,4+i)); } tiles = TilesAtDistance(1).Where(x=>(x.passable || x.Is(TileType.DOOR_C,TileType.RUBBLE)) && ApproximateEuclideanDistanceFromX10(x) == 10 && !blocked.Contains(DirectionOf(x))); } if(!corridor && next.passable){ PlayerWalk(attrs[AttrType.RUNNING]); return; } else{ if(corridor && tiles.Count == 1){ attrs[AttrType.RUNNING] = DirectionOf(tiles[0]); PlayerWalk(attrs[AttrType.RUNNING]); foreach(int dir in U.FourDirections){ //now check again to see whether the player has entered a room if(TileInDirection(dir).passable && TileInDirection(dir.RotateDir(true,1)).passable && TileInDirection(dir.RotateDir(true,2)).passable){ corridor = false; break; } } if(!corridor){ attrs[AttrType.RUNNING] = 0; attrs[AttrType.WAITING] = 0; } return; } else{ attrs[AttrType.RUNNING] = 0; attrs[AttrType.WAITING] = 0; } /*Tile opposite = TileInDirection(attrs[AttrType.RUNNING].RotateDir(true,4)); int num_floors = 0; int floor_dir = 0; foreach(Tile t2 in TilesAtDistance(1)){ //if(t2 != opposite && t2.name == "floor"){ if(t2 != opposite && (t2.passable || t2.type == TileType.DOOR_C)){ num_floors++; floor_dir = DirectionOf(t2); } } if(num_floors == 1){ attrs[AttrType.RUNNING] = floor_dir;//the purpose of this code is to detect whether there's a valid turn to make PlayerWalk(floor_dir); //and take it if so. if there's a branch, it should stop. return; } else{ attrs[AttrType.RUNNING] = 0; attrs[AttrType.WAITING] = 0; }*/ } } } else{ if(Input.KeyIsAvailable()){ Input.ReadKey(); } attrs[AttrType.RUNNING] = 0; attrs[AttrType.WAITING] = 0; } } if(HasAttr(AttrType.RESTING)){ if(attrs[AttrType.RESTING] == 10){ attrs[AttrType.RESTING] = -1; curhp = maxhp; curmp = maxmp; B.Add("You rest...you feel great! "); RemoveExhaustion(); bool repaired = false; foreach(EquipmentStatus eqstatus in Enum.GetValues(typeof(EquipmentStatus))){ foreach(Weapon w in weapons){ if(w.status[eqstatus]){ repaired = true; w.status[eqstatus] = false; } } foreach(Armor a in armors){ if(a.status[eqstatus]){ repaired = true; a.status[eqstatus] = false; } } } if(repaired){ B.Add("You finish repairing your equipment. "); } if(magic_trinkets.Contains(MagicTrinketType.CIRCLET_OF_THE_THIRD_EYE)){ Event hiddencheck = null; foreach(Event e in Q.list){ if(!e.dead && e.type == EventType.CHECK_FOR_HIDDEN){ hiddencheck = e; break; } } List<Tile> valid_list = M.AllTiles().Where(x=>x.passable && !x.seen); while(valid_list.Count > 0){ Tile chosen = valid_list.RemoveRandom(); if(chosen == null){ break; } var dijkstra = M.tile.GetDijkstraMap(new List<pos>{chosen.p},x=>!M.tile[x].passable && !M.tile[x].IsDoorType(true)); //todo: blocksconnectivityofmap? if(chosen.TilesWithinDistance(18).Where(x=>x.passable && !x.seen && dijkstra[x.p] <= 18).Count < 20){ continue; } foreach(Tile t in chosen.TilesWithinDistance(12)){ if(t.type != TileType.FLOOR && !t.solid_rock){ t.seen = true; if(t.type != TileType.WALL){ t.revealed_by_light = true; } if(t.IsTrap() || t.Is(TileType.HIDDEN_DOOR)){ if(hiddencheck != null){ hiddencheck.area.Remove(t); } } if(t.IsTrap()){ t.name = Tile.Prototype(t.type).name; t.a_name = Tile.Prototype(t.type).a_name; t.the_name = Tile.Prototype(t.type).the_name; t.symbol = Tile.Prototype(t.type).symbol; t.color = Tile.Prototype(t.type).color; } if(t.Is(TileType.HIDDEN_DOOR)){ t.Toggle(null); } colorchar ch2 = Screen.BlankChar(); if(t.inv != null){ t.inv.revealed_by_light = true; ch2.c = t.inv.symbol; ch2.color = t.inv.color; M.last_seen[t.row,t.col] = ch2; } else{ if(t.features.Count > 0){ ch2 = t.FeatureVisual(); M.last_seen[t.row,t.col] = ch2; } else{ ch2.c = t.symbol; ch2.color = t.color; if(ch2.c == '#' && ch2.color == Color.RandomGlowingFungus){ ch2.color = Color.Gray; } M.last_seen[t.row,t.col] = ch2; } } } } M.Draw(); B.Add("Your " + MagicTrinket.Name(MagicTrinketType.CIRCLET_OF_THE_THIRD_EYE) + " grants you a vision. "); break; } } B.Print(false); UI.DisplayStats(); Cursor(); } else{ bool monsters_visible = false; foreach(Actor a in M.AllActors()){ if(a != this && CanSee(a) && HasLOS(a.row,a.col)){ //check LOS, prevents detected mobs from stopping you if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 1){ monsters_visible = true; } } } if(monsters_visible || Input.KeyIsAvailable()){ if(Input.KeyIsAvailable()){ Input.ReadKey(); } if(monsters_visible){ attrs[AttrType.RESTING] = 0; B.Add("You rest...you are interrupted! "); B.Print(false); Cursor(); } else{ attrs[AttrType.RESTING] = 0; B.Add("You rest...you stop resting. "); B.Print(false); Cursor(); } } else{ attrs[AttrType.RESTING]++; B.Add("You rest... ",true); Q1(); return; } } } MouseUI.IgnoreMouseMovement = false; if(Q.turn == 0){ Help.TutorialTip(TutorialTopic.Movement); //todo: move this elsewhere? Cursor(); } if(!Help.displayed[TutorialTopic.Attacking] && M.AllActors().Any(a=>(a != this && CanSee(a)))){ Help.TutorialTip(TutorialTopic.Attacking); Cursor(); } ConsoleKeyInfo command = Input.ReadKey(); char ch = command.GetAction().GetCommandChar(); bool alt = false; bool ctrl = false; bool shift = false; if((command.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt){ alt = true; } if((command.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control){ ctrl = true; } if((command.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift){ shift = true; } switch(ch){ case '7': case '8': case '9': case '4': case '6': case '1': case '2': case '3': { if(FrozenThisTurn()){ break; } if(HasAttr(AttrType.CONFUSED)){ PlayerWalk(Global.RandomDirection()); break; } int dir = ch - 48; //ascii 0-9 are 48-57 if(shift || alt || ctrl){ bool monsters_visible = false; foreach(Actor a in M.AllActors()){ if(a!=this && CanSee(a) && HasLOS(a.row,a.col)){ if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 2){ monsters_visible = true; } } } PlayerWalk(dir); if(!monsters_visible){ attrs[AttrType.RUNNING] = dir; } } else{ PlayerWalk(dir); } break; } case '5': { if(tile().inv != null){ tile().inv.revealed_by_light = true; if(tile().inv.quantity > 1){ B.Add("There are " + tile().inv.AName() + " here. "); } else{ B.Add("There is " + tile().inv.AName() + " here. "); } //B.Add("You see " + M.tile[row,col].inv.AName() + ". "); } if(HasAttr(AttrType.BURNING)){ if(tile().IsWater() && !tile().Is(FeatureType.OIL)){ B.Add("You extinguish the flames. "); attrs[AttrType.BURNING] = 0; if(light_radius == 0){ UpdateRadius(1,0); } Q.KillEvents(this,AttrType.BURNING); Fire.burning_objects.Remove(this); } else{ if(tile().Is(FeatureType.SLIME)){ B.Add("You cover yourself in slime to remove the flames. "); attrs[AttrType.BURNING] = 0; if(light_radius == 0){ UpdateRadius(1,0); } Q.KillEvents(this,AttrType.BURNING); attrs[AttrType.SLIMED] = 1; Fire.burning_objects.Remove(this); Help.TutorialTip(TutorialTopic.Slimed); } } } if(HasAttr(AttrType.SLIMED) && tile().IsWater() && !tile().Is(FeatureType.FIRE)){ attrs[AttrType.SLIMED] = 0; B.Add("You wash off the slime. "); } if(HasAttr(AttrType.OIL_COVERED) && tile().Is(FeatureType.SLIME)){ attrs[AttrType.OIL_COVERED] = 0; attrs[AttrType.SLIMED] = 1; B.Add("You cover yourself in slime to remove the oil. "); Help.TutorialTip(TutorialTopic.Slimed); } if(HasAttr(AttrType.OIL_COVERED) && tile().IsWater() && !tile().Is(FeatureType.FIRE,FeatureType.OIL)){ attrs[AttrType.OIL_COVERED] = 0; B.Add("You wash off the oil. "); tile().AddFeature(FeatureType.OIL); } attrs[AttrType.NO_PLATE_ARMOR_NOISE] = 1; if(Speed() < 100){ QS(); } else{ Q1(); } break; } case 'w': { int dir = GetDirection("Start walking in which direction? ",false,true); if(dir != 0){ bool monsters_visible = false; foreach(Actor a in M.AllActors()){ if(a != this && CanSee(a) && HasLOS(a.row,a.col)){ if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 2){ monsters_visible = true; } } } if(dir != 5){ if(FrozenThisTurn()){ break; } PlayerWalk(dir); } else{ QS(); } if(!monsters_visible){ attrs[AttrType.RUNNING] = dir; bool recover = false; if(!HasAttr(AttrType.NONLIVING)){ if(HasFeat(FeatType.ENDURING_SOUL) && curhp % 10 != 0){ recover = true; } if(HasAttr(AttrType.BANDAGED)){ recover = true; } } if(!recover && dir == 5){ attrs[AttrType.WAITING] = 20; } } } else{ Q0(); } break; } case 'o': { if(FrozenThisTurn()){ break; } int dir = GetDirection("Operate something in which direction? "); if(dir != -1){ Tile t = TileInDirection(dir); if(t.IsKnownTrap()){ if(HasFeat(FeatType.DISARM_TRAP)){ if(ActorInDirection(dir) != null){ B.Add("There is " + ActorInDirection(dir).AName(true) + " in the way. "); Q0(); return; } if(StunnedThisTurn()){ return; } if(t.name.Contains("(safe)")){ B.Add("You disarm " + Tile.Prototype(t.type).the_name + ". "); t.Toggle(this); } else{ B.Add("You make " + Tile.Prototype(t.type).the_name + " safe to cross. "); t.SetName(Tile.Prototype(t.type).name + " (safe)"); } Q1(); } else{ B.Add("You don't know how to disable that trap. "); Q0(); return; } } else{ switch(t.type){ case TileType.DOOR_C: case TileType.DOOR_O: case TileType.RUBBLE: if(StunnedThisTurn()){ break; } if(t.type == TileType.RUBBLE && !HasAttr(AttrType.BRUTISH_STRENGTH)){ IncreaseExhaustion(1); } t.Toggle(this); Q1(); break; case TileType.CHEST: B.Add("Stand on the chest and press 'g' to retrieve its contents. "); Q0(); break; case TileType.STAIRS: B.Add("Stand on the stairs and press '>' to descend. "); Q0(); break; case TileType.POOL_OF_RESTORATION: B.Add("Stand over the pool and drop an item in to activate it. "); Q0(); break; case TileType.STONE_SLAB: B.Add("The slab will open if light shines upon it. "); Q0(); break; default: if(t.IsShrine()){ B.Add("Stand on the shrine and press 'g' to activate it. "); } Q0(); break; } } } else{ Q0(); } break; } case 's': { if(FrozenThisTurn()){ break; } if(Bow.status[EquipmentStatus.OUT_OF_ARROWS]){ B.Add("You're out of arrows! "); Q0(); } else{ if(EquippedWeapon.type == WeaponType.BOW || HasFeat(FeatType.QUICK_DRAW)){ if(ActorsAtDistance(1).Count > 0){ int seen = ActorsAtDistance(1).Where(x=>CanSee(x)).Count; if(seen > 0){ if(seen == 1){ B.Add("You can't fire with an enemy so close. "); } else{ B.Add("You can't fire with enemies so close. "); } Q0(); } else{ B.Add("As you raise your bow, something knocks it down! "); B.Print(true); Q1(); } } else{ MouseUI.fire_arrow_hack = true; List<Tile> line = GetTargetLine(12); if(line != null && line.LastOrDefault() != tile()){ if(EquippedWeapon != Bow && HasFeat(FeatType.QUICK_DRAW)){ EquippedWeapon = Bow; } FireArrow(line); if(Bow.status[EquipmentStatus.ONE_ARROW_LEFT]){ Bow.status[EquipmentStatus.ONE_ARROW_LEFT] = false; Bow.status[EquipmentStatus.OUT_OF_ARROWS] = true; } else{ if(Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS]){ if(R.OneIn(15)){ Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS] = false; Bow.status[EquipmentStatus.ONE_ARROW_LEFT] = true; B.Add("You're down to your last arrow! "); B.PrintAll(); } } else{ if(Bow.status[EquipmentStatus.LOW_ON_ARROWS]){ if(R.OneIn(20)){ Bow.status[EquipmentStatus.LOW_ON_ARROWS] = false; Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS] = true; B.Add("You have only a few arrows left! "); B.PrintAll(); } } else{ if(R.OneIn(25)){ Bow.status[EquipmentStatus.LOW_ON_ARROWS] = true; B.Add("You're running a bit low on arrows. "); B.PrintAll(); } } } } } else{ Q0(); } } } else{ B.Add("You need your bow to fire arrows - press e to switch equipment. "); //B.Add("You can't fire arrows without your bow equipped - press e to switch equipment. "); Q0(); } } break; } case 'z': { if(FrozenThisTurn()){ break; } foreach(Actor a in ActorsWithinDistance(2)){ if(a.HasAttr(AttrType.SILENCE_AURA) && a.HasLOE(this)){ if(this == player){ if(CanSee(a)){ B.Add(a.Your() + " aura of silence prevents you from casting! "); } else{ B.Add("An aura of silence prevents you from casting! "); } } Q0(); return; } } if(HasAttr(AttrType.SILENCED)){ B.Add("You can't cast while silenced. "); Q0(); return; } List<colorstring> ls = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); //foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){ bool bonus_marked = false; foreach(SpellType spell in spells_in_order){ if(HasSpell(spell)){ //string s = Spell.Name(spell).PadRight(15) + Spell.Tier(spell).ToString().PadLeft(3); //s = s + FailRate(spell).ToString().PadLeft(9) + "%"; //s = s + Spell.Description(spell).PadLeft(34); //this is the recent one! colorstring cs = new colorstring(Spell.Name(spell).PadRight(17) + Spell.Tier(spell).ToString().PadLeft(3),Color.Gray); colorstring cs = new colorstring(Spell.Name(spell).PadRight(17) + Spell.Tier(spell).ToString().PadLeft(2),Color.Gray); //cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%",FailColor(spell))); int failrate = Spell.FailRate(spell,exhaustion); cs.strings.Add(new cstr("/",Color.DarkGray)); cs.strings.Add(new cstr((failrate.ToString() + "% ").PadRight(5),FailColor(failrate))); // this too cs.strings.Add(new cstr("".PadLeft(5),Color.Gray)); if(HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked){ bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else{ cs = cs + Spell.Description(spell); } ls.Add(cs); sp.Add(spell); } } if(sp.Count > 0){ colorstring topborder = new colorstring("-------------------Tier/Fail%-----------Description---------------",Color.Gray); //colorstring topborder = new colorstring("-------------------Tier (fail%)---------Description---------------",Color.Gray); //colorstring topborder = new colorstring("---------------------Tier-----------------Description-------------",Color.Gray); colorstring bottomborder = new colorstring("".PadRight(25,'-') + "[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(COLS,'-'),Color.Gray); //colorstring bottomborder = new colorstring("----------------" + "Exhaustion: ".PadLeft(12+(3-basefail.ToString().Length),'-'),Color.Gray,(basefail.ToString() + "%"),FailColor(basefail),"----------[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(22,'-'),Color.Gray); //int i = Select("Cast which spell? ",topborder,bottomborder,ls); int i = Select("Cast which spell? ",topborder,bottomborder,ls,false,false,true,true,HelpTopic.Spells); if(i != -1){ if(!CastSpell(sp[i])){ Q0(); } } else{ Q0(); } } else{ B.Add("You don't know any spells. "); Q0(); } break; } case 'r': if(FrozenThisTurn()){ break; } if(attrs[AttrType.RESTING] != -1){ //gets set to -1 if you've rested on this level bool monsters_visible = false; foreach(Actor a in M.AllActors()){ if(a != this && CanSee(a) && HasLOS(a.row,a.col)){ //check LOS, prevents detected mobs from stopping you if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 1){ monsters_visible = true; } } } bool equipment_can_be_repaired = false; foreach(EquipmentStatus eqs in Enum.GetValues(typeof(EquipmentStatus))){ foreach(Weapon w in weapons){ if(w.status[eqs]){ equipment_can_be_repaired = true; break; } } foreach(Armor a in armors){ if(a.status[eqs]){ equipment_can_be_repaired = true; break; } } if(equipment_can_be_repaired){ break; } } if(!monsters_visible){ if(curhp < maxhp || curmp < maxmp || exhaustion > 0 || equipment_can_be_repaired){ if(Global.Option(OptionType.CONFIRM_BEFORE_RESTING) && !B.YesOrNoPrompt("Rest and repair your equipment?")){ Q0(); break; } if(StunnedThisTurn()){ break; } attrs[AttrType.RESTING] = 1; B.Add("You rest... ",true); Q1(); } else{ B.Add("You don't need to rest right now. "); Q0(); } } else{ B.Add("You can't rest while there are enemies around! "); Q0(); } } else{ B.Add("You find it impossible to rest again on this dungeon level. "); Q0(); } break; case '>': if(FrozenThisTurn()){ break; } if(M.tile[row,col].type == TileType.STAIRS){ if(StunnedThisTurn()){ break; } bool equipment_can_be_repaired = false; foreach(EquipmentStatus eqs in Enum.GetValues(typeof(EquipmentStatus))){ foreach(Weapon w in weapons){ if(w.status[eqs]){ equipment_can_be_repaired = true; break; } } foreach(Armor a in armors){ if(a.status[eqs]){ equipment_can_be_repaired = true; break; } } if(equipment_can_be_repaired){ break; } } if(attrs[AttrType.RESTING] != -1 && (curhp < maxhp || curmp < maxmp || exhaustion > 0 || equipment_can_be_repaired)){ MouseUI.descend_hack = true; if(!B.YesOrNoPrompt("Really take the stairs without resting first?")){ Q0(); return; } } bool shrine_remaining = false; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(M.tile[i,j].IsShrine() && M.tile[i,j].type != TileType.SPELL_EXCHANGE_SHRINE){ shrine_remaining = true; break; } } if(shrine_remaining){ MouseUI.descend_hack = true; break; } } if(shrine_remaining){ Help.TutorialTip(TutorialTopic.DistributionOfShrines); if(!B.YesOrNoPrompt("You feel an ancient power calling you back. Leave anyway?")){ Q0(); return; } } B.Add("You walk down the stairs. "); B.PrintAll(); if(M.current_level < 20){ M.GenerateLevel(); } else{ M.GenerateFinalLevel(); B.Add("Strange chants and sulfurous smoke fill the air here. "); } if(magic_trinkets.Contains(MagicTrinketType.LENS_OF_SCRYING)){ Item i = inv.Where(x=>!Item.identified[x.type]).RandomOrDefault(); if(i != null){ string itemname = i.NameWithoutQuantity(); Item.identified[i.type] = true; string IDedname = i.NameWithoutQuantity(); string isare = " is a "; if(i.quantity > 1){ isare = " are "; } B.Add("Your " + MagicTrinket.Name(MagicTrinketType.LENS_OF_SCRYING) + " reveals that your " + itemname + isare + IDedname + ". "); } } if(M.current_level == 3){ Help.TutorialTip(TutorialTopic.SwitchingEquipment); } Q0(); } else{ Tile stairs = null; foreach(Tile t in M.AllTiles()){ if(t.type == TileType.STAIRS && t.seen){ stairs = t; break; } } if(stairs != null){ List<pos> stairpath = GetPath(stairs,-1,true); foreach(pos p in stairpath){ if(p.row != row || p.col != col){ colorchar cch = Screen.MapChar(p.row,p.col); if(p.row == stairs.row && p.col == stairs.col){ cch.bgcolor = Color.Green; if(Global.LINUX && !Screen.GLMode){ //no bright bg in terminals cch.bgcolor = Color.DarkGreen; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(p.row,p.col,cch); } else{ cch.bgcolor = Color.DarkGreen; if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(p.row,p.col,cch); } } } MouseUI.PushButtonMap(MouseMode.YesNoPrompt); MouseUI.CreateButton(ConsoleKey.Y,false,2,Global.MAP_OFFSET_COLS + 22,1,2); MouseUI.CreateButton(ConsoleKey.N,false,2,Global.MAP_OFFSET_COLS + 25,1,2); B.DisplayNow("Travel to the stairs? (y/n): "); Screen.CursorVisible = true; bool done = false; while(!done){ command = Input.ReadKey(); switch(command.KeyChar){ case 'y': case 'Y': case '>': case (char)13: done = true; MouseUI.PopButtonMap(); break; default: Q0(); MouseUI.PopButtonMap(); return; } } FindPath(stairs,-1,true); if(path.Count > 0){ PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } } else{ B.Add("There's no path to the stairs. "); Q0(); } } else{ B.Add("You don't see any stairs here. "); Q0(); } } break; case 'x': { if(FrozenThisTurn()){ break; } if((tile().inv != null && !tile().inv.ignored) || (tile().Is(TileType.CHEST) && (tile().inv == null || !tile().inv.ignored))){ goto case 'g'; } if(!FindAutoexplorePath()){ B.Add("You don't see a path for further exploration. "); Q0(); } else{ attrs[AttrType.AUTOEXPLORE]++; PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } } break; } case 'X': if(FrozenThisTurn()){ break; } Screen.CursorVisible = false; Dictionary<Actor,colorchar> old_ch = new Dictionary<Actor,colorchar>(); List<Actor> drawn = new List<Actor>(); foreach(Actor a in M.AllActors()){ if(CanSee(a)){ old_ch.Add(a,M.last_seen[a.row,a.col]); M.last_seen[a.row,a.col] = new colorchar(a.symbol,a.color); drawn.Add(a); } } Screen.MapDrawWithStrings(M.last_seen,0,0,ROWS,COLS); ChoosePathingDestination(); foreach(Actor a in drawn){ M.last_seen[a.row,a.col] = old_ch[a]; } M.Redraw(); if(path.Count > 0){ PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } } else{ Q0(); } break; case 'g': { if(FrozenThisTurn()){ break; } if(tile().inv == null){ if(tile().type == TileType.CHEST){ if(StunnedThisTurn()){ break; } tile().OpenChest(); Q1(); } else{ if(tile().IsShrine()){ if(StunnedThisTurn()){ break; } switch(tile().type){ case TileType.COMBAT_SHRINE: Help.TutorialTip(TutorialTopic.Combat); IncreaseSkill(SkillType.COMBAT); break; case TileType.DEFENSE_SHRINE: Help.TutorialTip(TutorialTopic.Defense); IncreaseSkill(SkillType.DEFENSE); break; case TileType.MAGIC_SHRINE: Help.TutorialTip(TutorialTopic.Magic); IncreaseSkill(SkillType.MAGIC); break; case TileType.SPIRIT_SHRINE: Help.TutorialTip(TutorialTopic.Spirit); IncreaseSkill(SkillType.SPIRIT); break; case TileType.STEALTH_SHRINE: Help.TutorialTip(TutorialTopic.Stealth); IncreaseSkill(SkillType.STEALTH); break; case TileType.SPELL_EXCHANGE_SHRINE: //currently disabled { List<colorstring> ls = new List<colorstring>(); List<SpellType> sp = new List<SpellType>(); bool bonus_marked = false; foreach(SpellType spell in spells_in_order){ if(HasSpell(spell)){ colorstring cs = new colorstring(Spell.Name(spell).PadRight(18) + Spell.Tier(spell).ToString().PadLeft(3),Color.Gray); //cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%",FailColor(spell))); cs.strings.Add(new cstr("".PadRight(5),Color.Gray)); if(HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked){ bonus_marked = true; cs = cs + Spell.DescriptionWithIncreasedDamage(spell); } else{ cs = cs + Spell.Description(spell); } ls.Add(cs); sp.Add(spell); } } if(sp.Count > 0){ colorstring topborder = new colorstring("----------------------Tier-----------------Description------------",Color.Gray); int basefail = exhaustion; colorstring bottomborder = new colorstring("----------------" + "Exhaustion: ".PadLeft(12+(3-basefail.ToString().Length),'-'),Color.Gray,(basefail.ToString() + "%"),FailColor(basefail),"----------[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(22,'-'),Color.Gray); int i = Select("Trade one of your spells for another? ",topborder,bottomborder,ls,false,false,true,true,HelpTopic.Spells); if(i != -1){ List<SpellType> unknown = new List<SpellType>(); foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){ if(!HasSpell(spell) && spell != SpellType.NO_SPELL && spell != SpellType.NUM_SPELLS){ unknown.Add(spell); } } SpellType forgotten = sp[i]; spells_in_order.Remove(forgotten); spells[forgotten] = false; SpellType learned = unknown.Random(); spells[learned] = true; spells_in_order.Add(learned); B.Add("You forget " + Spell.Name(forgotten) + ". You learn " + Spell.Name(learned) + ". "); tile().TransformTo(TileType.RUINED_SHRINE); tile().SetName("ruined shrine of magic"); } else{ Q0(); } } break; } default: break; } if(tile().type != TileType.SPELL_EXCHANGE_SHRINE){ Q1(); } //if(tile().type == TileType.MAGIC_SHRINE && spells_in_order.Count > 1){ // tile().TransformTo(TileType.SPELL_EXCHANGE_SHRINE); //} //else{ if(tile().type != TileType.SPELL_EXCHANGE_SHRINE && !tile().name.Contains("ruined")){ string oldname = tile().name; tile().TransformTo(TileType.RUINED_SHRINE); tile().SetName("ruined " + oldname); } //} foreach(Tile t in TilesWithinDistance(2)){ if(t.IsShrine()){ string oldname = t.name; t.TransformTo(TileType.RUINED_SHRINE); t.SetName("ruined " + oldname); } } } else{ if(tile().type == TileType.BLAST_FUNGUS){ if(InventoryCount() < Global.MAX_INVENTORY_SIZE){ if(StunnedThisTurn()){ break; } B.Add("You pull the blast fungus from the floor. "); B.Add("Its fuse ignites! "); tile().Toggle(null); Item i = Item.Create(ConsumableType.BLAST_FUNGUS,this); if(i != null){ i.other_data = 3; i.revealed_by_light = true; Q.Add(new Event(i,100,EventType.BLAST_FUNGUS)); Screen.AnimateMapCell(row,col,new colorchar('3',Color.Red),100); } Q1(); } else{ B.Add("Your pack is too full to pick up the blast fungus. "); Q0(); } } else{ if(tile().type == TileType.RUINED_SHRINE){ B.Add("This " + tile().name + " has no power left. "); Q0(); } else{ B.Add("There's nothing here to pick up. "); Q0(); } } } } } else{ if(InventoryCount() < Global.MAX_INVENTORY_SIZE){ if(StunnedThisTurn()){ break; } if(InventoryCount() + tile().inv.quantity <= Global.MAX_INVENTORY_SIZE){ Item i = tile().inv; tile().inv = null; if(i.light_radius > 0){ i.UpdateRadius(i.light_radius,0); } i.row = -1; i.col = -1; i.revealed_by_light = true; B.Add("You pick up " + i.TheName() + ". "); GetItem(i); Q1(); } else{ int space_left = Global.MAX_INVENTORY_SIZE - InventoryCount(); Item i = tile().inv; Item newitem = new Item(i,row,col); newitem.quantity = space_left; i.quantity -= space_left; newitem.revealed_by_light = true; B.Add("You pick up " + newitem.TheName() + ", but have no room for the other " + i.quantity.ToString() + ". "); i.ignored = true; GetItem(newitem); Q1(); } } else{ tile().inv.revealed_by_light = true; B.Add("Your pack is too full to pick up " + tile().inv.TheName() + ". "); tile().inv.ignored = true; Q0(); } } break; } case 'i': case 'a': //these are handled in the same case label so I can drop down from the selection to the action case 'f': case 'd': { if(inv.Count == 0){ B.Add("You have nothing in your pack. "); Q0(); break; } if(ch == 'a' || ch == 'f' || ch == 'd'){ if(FrozenThisTurn()){ break; } } string msg = "In your pack: "; bool no_redraw = (ch == 'i'); switch(ch){ case 'a': msg = "Apply which item? "; break; case 'f': msg = "Fling which item? "; break; case 'd': msg = "Drop which item? "; break; } ItemSelection sel = new ItemSelection(); sel.value = -2; while(sel.value != -1){ sel = SelectItem(msg,no_redraw); if(ch == 'i'){ sel.description_requested = true; } if(sel.value != -1 && sel.description_requested){ MouseUI.PushButtonMap(MouseMode.Inventory); MouseUI.AutomaticButtonsFromStrings = true; Screen.CursorVisible = false; colorchar[,] screen = Screen.GetCurrentScreen(); for(int letter=0;letter<inv.Count;++letter){ Screen.WriteMapChar(letter+1,1,(char)(letter+'a'),Color.DarkCyan); } List<colorstring> box = UI.ItemDescriptionBox(inv[sel.value],false,false,31); int i = (Global.SCREEN_H - box.Count) / 2; int j = (Global.SCREEN_W - box[0].Length()) / 2; foreach(colorstring cs in box){ Screen.WriteString(i,j,cs); ++i; } switch(Input.ReadKey().GetCommandChar()){ case 'a': ch = 'a'; sel.description_requested = false; break; case 'f': ch = 'f'; sel.description_requested = false; break; case 'd': ch = 'd'; sel.description_requested = false; break; } MouseUI.PopButtonMap(); MouseUI.AutomaticButtonsFromStrings = false; if(sel.description_requested){ Screen.WriteArray(0,0,screen); } else{ M.Redraw(); //this will break if the box goes off the map, todo break; } Screen.CursorVisible = true; } else{ break; } } if(sel.value == -1){ Q0(); break; } int num = sel.value; if(ch == 'f' && (inv[num].NameOfItemType() == "orb" || inv[num].type == ConsumableType.BLAST_FUNGUS)){ ch = 'a'; } switch(ch){ case 'a': { if(FrozenThisTurn()){ break; } if(HasAttr(AttrType.NONLIVING) && inv[num].NameOfItemType() == "potion"){ B.Add("Potions have no effect on you in stone form. "); Q0(); } else{ if(HasAttr(AttrType.NONLIVING) && inv[num].type == ConsumableType.BANDAGES){ B.Add("Bandages have no effect on you in stone form. "); Q0(); } else{ if(HasAttr(AttrType.BLIND) && inv[num].NameOfItemType() == "scroll"){ B.Add("You can't read scrolls while blind. "); Q0(); } else{ if(inv[num].NameOfItemType() == "wand" && inv[num].charges == 0 && inv[num].other_data == -1){ B.Add("That wand has no charges left. "); Q0(); } else{ bool silenced = HasAttr(AttrType.SILENCED,AttrType.SILENCE_AURA); string silence_message = "You can't read scrolls while silenced. "; if(HasAttr(AttrType.SILENCE_AURA)){ silence_message = "Your silence aura makes reading scrolls impossible. "; } else{ List<Actor> auras = ActorsWithinDistance(2).Where(x=>x.HasAttr(AttrType.SILENCE_AURA) && x.HasLOE(this)); if(auras.Count > 0){ silenced = true; Actor a = auras.Where(x=>CanSee(x)).RandomOrDefault(); if(a != null){ silence_message = a.the_name + "'s silence aura makes reading scrolls impossible. "; } else{ silence_message = "An aura of silence makes reading scrolls impossible. "; } } } if(silenced && inv[num].NameOfItemType() == "scroll"){ B.Add(silence_message); Q0(); } else{ Actor thief = ActorsAtDistance(1).Where(x=>x.type == ActorType.SNEAK_THIEF).RandomOrDefault(); if(thief != null){ B.Add(thief.YouVisible("snatch",true) + " your " + inv[num].SingularName(false) + "! "); B.PrintAll(); Item stolen = inv[num]; if(inv[num].quantity > 1){ stolen = new Item(inv[num],inv[num].row,inv[num].col); stolen.revealed_by_light = inv[num].revealed_by_light; inv[num].quantity--; } else{ inv.Remove(stolen); } thief.GetItem(stolen); Q1(); } else{ if(StunnedThisTurn()){ break; } if(HasAttr(AttrType.SLIMED,AttrType.OIL_COVERED) && R.OneIn(5)){ Item i = inv[num]; B.Add("The " + i.SingularName() + " slips out of your hands! "); i.revealed_by_light = true; if(i.quantity <= 1){ if(tile().type == TileType.POOL_OF_RESTORATION){ B.Add("You drop " + i.TheName() + " into the pool. "); inv.Remove(i); if(curhp < maxhp || curmp < maxmp || exhaustion > 0){ B.Add("The pool's glow restores you. "); curhp = maxhp; curmp = maxmp; RemoveExhaustion(); } else{ B.Add("The pool of restoration glows briefly, then dries up. "); } tile().TurnToFloor(); } else{ if(tile().GetItem(i)){ B.Add("You drop " + i.TheName() + ". "); inv.Remove(i); } else{ //this only happens if every tile is full - i.e. never } } } else{ if(tile().type == TileType.POOL_OF_RESTORATION){ Item newitem = new Item(i,row,col); newitem.quantity = 1; i.quantity--; B.Add("You drop " + newitem.TheName() + " into the pool. "); if(curhp < maxhp || curmp < maxmp){ B.Add("The pool's glow restores you. "); curhp = maxhp; curmp = maxmp; } else{ B.Add("The pool of restoration glows briefly, then dries up. "); } tile().TurnToFloor(); } else{ Item newitem = new Item(i,row,col); newitem.quantity = 1; newitem.revealed_by_light = true; if(tile().GetItem(newitem)){ i.quantity -= 1; B.Add("You drop " + newitem.TheName() + ". "); } else{ //should never happen } } } Q1(); break; } if(inv[num].Use(this)){ Q1(); } else{ Q0(); } } } } } } } break; } case 'f': { if(FrozenThisTurn()){ break; } if(StunnedThisTurn()){ break; } List<Tile> line = GetTargetTile(12,0,false,false); if(line != null){ Item i = null; if(inv[num].quantity == 1){ i = inv[num]; } else{ i = new Item(inv[num],-1,-1); inv[num].quantity--; } i.revealed_by_light = true; i.ignored = true; Tile t = line.LastBeforeSolidTile(); Actor first = FirstActorInLine(line); B.Add(You("fling") + " " + i.TheName() + ". "); if(first != null && first != this){ t = first.tile(); B.Add("It hits " + first.the_name + ". ",first); } line = line.ToFirstSolidTileOrActor(); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } { Tile first_unseen = null; foreach(Tile tile2 in line){ if(!tile2.seen){ first_unseen = tile2; break; } } if(first_unseen != null){ line = line.To(first_unseen); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } } } if(line.Count > 0){ AnimateProjectile(line,i.symbol,i.color); } if(i.IsBreakable()){ B.Add("It breaks! ",t); i.CheckForMimic(); } else{ bool broken = false; if(i.type == ConsumableType.FLINT_AND_STEEL){ if(R.OneIn(3)){ i.other_data--; if(i.other_data == 2){ B.Add("Your flint & steel shows signs of wear. ",t); } if(i.other_data == 1){ B.Add("Your flint & steel is almost depleted. ",t); } if(i.other_data == 0){ broken = true; B.Add("Your flint & steel is used up. ",t); } } } if(!broken){ t.GetItem(i); } } inv.Remove(i); t.MakeNoise(2); if(first != null && first != this){ first.player_visibility_duration = -1; first.attrs[AttrType.PLAYER_NOTICED]++; } else{ if(t.IsTrap()){ t.TriggerTrap(); } } Q1(); } else{ Q0(); } break; } case 'd': { if(FrozenThisTurn()){ break; } if(StunnedThisTurn()){ break; } Item i = inv[num]; i.revealed_by_light = true; if(i.quantity <= 1){ if(tile().type == TileType.POOL_OF_RESTORATION){ B.Add("You drop " + i.TheName() + " into the pool. "); inv.Remove(i); if(curhp < maxhp || curmp < maxmp){ B.Add("The pool's glow restores you. "); curhp = maxhp; curmp = maxmp; } else{ B.Add("The pool of restoration glows briefly, then dries up. "); } tile().TurnToFloor(); Q1(); } else{ if(tile().GetItem(i)){ B.Add("You drop " + i.TheName() + ". "); inv.Remove(i); i.ignored = true; Q1(); } else{ B.Add("There is no room. "); Q0(); } } } else{ if(tile().type == TileType.POOL_OF_RESTORATION){ Item newitem = new Item(i,row,col); newitem.quantity = 1; i.quantity--; B.Add("You drop " + newitem.TheName() + " into the pool. "); if(curhp < maxhp || curmp < maxmp){ B.Add("The pool's glow restores you. "); curhp = maxhp; curmp = maxmp; } else{ B.Add("The pool of restoration glows briefly, then dries up. "); } tile().TurnToFloor(); Q1(); } else{ //B.DisplayNow("Drop how many? (1-" + i.quantity + "): "); //int count = Global.EnterInt(); int count = 1; if(count == 0){ Q0(); } else{ if(count >= i.quantity || count == -1){ if(tile().GetItem(i)){ B.Add("You drop " + i.TheName() + ". "); inv.Remove(i); i.ignored = true; Q1(); } else{ B.Add("There is no room. "); Q0(); } } else{ Item newitem = new Item(i,row,col); newitem.quantity = count; newitem.revealed_by_light = true; if(tile().GetItem(newitem)){ i.quantity -= count; B.Add("You drop " + newitem.TheName() + ". "); newitem.ignored = true; Q1(); } else{ B.Add("There is no room. "); Q0(); } } } } } break; } } break; } case 'e': { int[] changes = UI.DisplayEquipment(); M.Redraw(); Weapon new_weapon = WeaponOfType((WeaponType)changes[0]); Armor new_armor = ArmorOfType((ArmorType)changes[1]); Weapon old_weapon = EquippedWeapon; Armor old_armor = EquippedArmor; bool weapon_changed = (new_weapon != old_weapon); bool armor_changed = (new_armor != old_armor); if(weapon_changed || armor_changed){ if(FrozenThisTurn()){ break; } } bool cursed_weapon = false; bool cursed_armor = false; if(weapon_changed && EquippedWeapon.status[EquipmentStatus.STUCK]){ cursed_weapon = true; weapon_changed = false; armor_changed = false; } if(armor_changed && EquippedArmor.status[EquipmentStatus.STUCK]){ cursed_armor = true; armor_changed = false; weapon_changed = false; } if(!weapon_changed && !armor_changed){ if(cursed_weapon){ B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. "); } if(cursed_armor){ B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. "); } Q0(); } else{ if(StunnedThisTurn()){ break; } Help.displayed[TutorialTopic.SwitchingEquipment] = true; if(weapon_changed){ EquippedWeapon = new_weapon; if(HasFeat(FeatType.QUICK_DRAW) && !armor_changed && old_weapon != Bow){ B.Add("You quickly ready your " + EquippedWeapon + ". "); } else{ if(old_weapon == Bow){ B.Add("You put away your bow and ready your " + EquippedWeapon + ". "); } else{ B.Add("You ready your " + EquippedWeapon + ". "); } } //UpdateOnEquip(old_weapon,EquippedWeapon); } if(armor_changed){ EquippedArmor = new_armor; //UpdateOnEquip(old_armor,EquippedArmor); if(TotalProtectionFromArmor() == 0){ if(EquippedArmor.status[EquipmentStatus.DAMAGED]){ B.Add("You wear your damaged " + EquippedArmor + ". "); B.Add("(It provides no protection until repaired.) "); } else{ B.Add("You wear your " + EquippedArmor + ". "); B.Add("You can't wear it effectively in your exhausted state. "); } } else{ B.Add("You wear your " + EquippedArmor + ". "); } attrs[AttrType.SWITCHING_ARMOR] = 1; } if(cursed_weapon){ B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. "); } if(cursed_armor){ B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. "); } if(HasFeat(FeatType.QUICK_DRAW) && !armor_changed && old_weapon != Bow){ Q0(); } else{ Q1(); } } break; } case '!': //note that these are the top-row numbers, NOT the actual shifted versions case '@': //<---this is the '2' above the 'w' (not the '@', and not the numpad 2) case '#': case '$': case '%': { if(FrozenThisTurn()){ break; } if(EquippedWeapon.status[EquipmentStatus.STUCK]){ B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. "); Q0(); } else{ Weapon new_weapon = null; switch(ch){ case '!': new_weapon = Sword; break; case '@': new_weapon = Mace; break; case '#': new_weapon = Dagger; break; case '$': new_weapon = Staff; break; case '%': new_weapon = Bow; break; } Weapon old_weapon = EquippedWeapon; if(new_weapon == old_weapon){ Q0(); } else{ if(StunnedThisTurn()){ break; } Help.displayed[TutorialTopic.SwitchingEquipment] = true; EquippedWeapon = new_weapon; if(HasFeat(FeatType.QUICK_DRAW) && old_weapon != Bow){ B.Add("You quickly ready your " + EquippedWeapon + ". "); Q0(); } else{ if(old_weapon == Bow){ B.Add("You put away your bow and ready your " + EquippedWeapon + ". "); } else{ B.Add("You ready your " + EquippedWeapon + ". "); } Q1(); } //UpdateOnEquip(old_weapon,EquippedWeapon); } } break; } case '*': //these are toprow numbers, not shifted versions. see above. case '(': case ')': { if(FrozenThisTurn()){ break; } if(EquippedArmor.status[EquipmentStatus.STUCK]){ B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. "); Q0(); } else{ Armor new_armor = null; switch(ch){ case '*': new_armor = Leather; break; case '(': new_armor = Chainmail; break; case ')': new_armor = Plate; break; } Armor old_armor = EquippedArmor; if(new_armor == old_armor){ Q0(); } else{ if(StunnedThisTurn()){ break; } Help.displayed[TutorialTopic.SwitchingEquipment] = true; EquippedArmor = new_armor; if(TotalProtectionFromArmor() == 0){ if(EquippedArmor.status[EquipmentStatus.DAMAGED]){ B.Add("You wear your damaged " + EquippedArmor + ". "); B.Add("(It provides no protection until repaired.) "); } else{ B.Add("You wear your " + EquippedArmor + ". "); B.Add("You can't wear it effectively in your exhausted state. "); } } else{ B.Add("You wear your " + EquippedArmor + ". "); } attrs[AttrType.SWITCHING_ARMOR] = 1; Q1(); //UpdateOnEquip(old_weapon,EquippedWeapon); } } break; } case 't': if(FrozenThisTurn()){ break; } if(StunnedThisTurn()){ break; } if(light_radius==0){ if(!M.wiz_dark){ B.Add("You bring out your torch. "); } else{ B.Add("You bring out your torch, but it gives off no light! "); } int old = LightRadius(); light_radius = 6; if(old != LightRadius()){ UpdateRadius(old,LightRadius()); } if(HasAttr(AttrType.DIM_LIGHT)){ CalculateDimming(); } } else{ if(!M.wiz_lite){ B.Add("You put away your torch. "); } else{ B.Add("You put away your torch. The air still shines brightly. "); } int old = LightRadius(); if(HasAttr(AttrType.SHINING)){ RefreshDuration(AttrType.SHINING,0); } light_radius = 0; if(old != LightRadius()){ UpdateRadius(old,LightRadius()); } if(HasAttr(AttrType.SHADOW_CLOAK) && !tile().IsLit()){ B.Add("You fade away in the darkness. "); } } Q1(); break; case (char)9: { GetTarget(true,-1,0,false,false,true,""); if(path.Count > 0){ if(FrozenThisTurn()){ break; } PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } } else{ Q0(); } break; } case 'm': { MouseUI.PushButtonMap(); Screen.CursorVisible = false; Tile stairs = M.AllTiles().Where(x=>x.type == TileType.STAIRS && x.seen).RandomOrDefault(); colorchar cch = Screen.BlankChar(); if(stairs != null){ cch = M.last_seen[stairs.row,stairs.col]; M.last_seen[stairs.row,stairs.col] = new colorchar('>',stairs.color); } Screen.MapDrawWithStrings(M.last_seen,0,0,ROWS,COLS); Screen.CursorVisible = true; UI.viewing_map_shrine_info = true; ChoosePathingDestination(false,false,"Map of dungeon level " + M.current_level + ": "); UI.viewing_map_shrine_info = false; if(stairs != null){ M.last_seen[stairs.row,stairs.col] = cch; } MouseUI.PopButtonMap(); M.Redraw(); if(path.Count > 0){ if(FrozenThisTurn()){ break; } PlayerWalk(DirectionOf(path[0])); if(path.Count > 0){ if(DistanceFrom(path[0]) == 0){ path.RemoveAt(0); } } } else{ Q0(); } break; } case 'p': { SharedEffect.ShowPreviousMessages(true); Q0(); break; } case 'c': { int feat = UI.DisplayCharacterInfo(); if(feat >= 0){ if(FrozenThisTurn()){ //todo: fix this, once there are things besides feats to use. break; } foreach(FeatType f in feats_in_order){ if(Feat.IsActivated(f)){ if(feat == 0){ M.Redraw(); if(StunnedThisTurn()){ break; } if(!UseFeat(f)){ Q0(); } break; } else{ --feat; } } } } else{ Q0(); } break; } case '\\': { SharedEffect.ShowKnownItems(Item.identified); Q0(); break; /*MouseUI.PushButtonMap(); List<colorstring> potions = new List<colorstring>(); List<colorstring> scrolls = new List<colorstring>(); List<colorstring> orbs = new List<colorstring>(); foreach(ConsumableType ct in Enum.GetValues(typeof(ConsumableType))){ string type_name = " " + ct.ToString()[0] + ct.ToString().Substring(1).ToLower(); type_name = type_name.Replace('_',' '); Color ided_color = Color.Cyan; if(Item.NameOfItemType(ct) == "potion"){ if(Item.identified[ct]){ potions.Add(new colorstring(type_name,ided_color)); } else{ potions.Add(new colorstring(type_name,Color.DarkGray)); } } else{ if(Item.NameOfItemType(ct) == "scroll"){ if(Item.identified[ct]){ scrolls.Add(new colorstring(type_name,ided_color)); } else{ scrolls.Add(new colorstring(type_name,Color.DarkGray)); } } else{ if(Item.NameOfItemType(ct) == "orb"){ if(Item.identified[ct]){ orbs.Add(new colorstring(type_name,ided_color)); } else{ orbs.Add(new colorstring(type_name,Color.DarkGray)); } } } } } Screen.WriteMapString(0,0,"".PadRight(COLS,'-')); for(int i=1;i<ROWS-1;++i){ Screen.WriteMapString(i,0,"".PadToMapSize()); } Screen.WriteMapString(ROWS-1,0,"".PadRight(COLS,'-')); Color label_color = Color.Yellow; Screen.WriteMapString(1,0," - Potions -",label_color); Screen.WriteMapString(1,33," - Scrolls -",label_color); int line = 2; foreach(colorstring s in potions){ Screen.WriteMapString(line,0,s); ++line; } line = 2; foreach(colorstring s in scrolls){ Screen.WriteMapString(line,33,s); ++line; } Screen.WriteMapString(12,0," - Orbs -",label_color); line = 13; foreach(colorstring s in orbs){ Screen.WriteMapString(line,0,s); ++line; } B.DisplayNow("Discovered item types: "); Screen.CursorVisible = true; Input.ReadKey(); MouseUI.PopButtonMap(); Q0(); break;*/ } case 'O': case '=': { MouseUI.PushButtonMap(); for(bool done=false;!done;){ List<string> ls = new List<string>(); ls.Add("Disable wall sliding".PadRight(58) + (Global.Option(OptionType.NO_WALL_SLIDING)? "yes ":"no ").PadLeft(4)); ls.Add("Automatically pick up items (if safe)".PadRight(58) + (Global.Option(OptionType.AUTOPICKUP)? "yes ":"no ").PadLeft(4)); ls.Add("Hide the path shown by mouse movement".PadRight(58) + (!MouseUI.VisiblePath? "yes ":"no ").PadLeft(4)); ls.Add("Use top-row numbers for movement".PadRight(58) + (Global.Option(OptionType.TOP_ROW_MOVEMENT)? "yes ":"no ").PadLeft(4)); ls.Add("Ask for confirmation before resting".PadRight(58) + (Global.Option(OptionType.CONFIRM_BEFORE_RESTING)? "yes ":"no ").PadLeft(4)); ls.Add("Show out-of-sight areas in dark gray instead".PadRight(58) + (Global.Option(OptionType.DARK_GRAY_UNSEEN)? "yes ":"no ").PadLeft(4)); ls.Add("Never show tutorial tips".PadRight(58) + (Global.Option(OptionType.NEVER_DISPLAY_TIPS)? "yes ":"no ").PadLeft(4)); ls.Add("Reset tutorial tips before each game".PadRight(58) + (Global.Option(OptionType.ALWAYS_RESET_TIPS)? "yes ":"no ").PadLeft(4)); if(Global.LINUX && !Screen.GLMode){ ls.Add("Attempt to fix display glitches on certain terminals".PadRight(COLS)); } /*if(Screen.GLMode){ ls.Add("Disable graphics".PadRight(58) + (Global.Option(OptionType.DISABLE_GRAPHICS)? "yes ":"no ").PadLeft(4)); }*/ Select("Options: ",ls,true,false,false); Screen.CursorVisible = true; ch = Input.ReadKey().GetCommandChar(); switch(ch){ case 'a': Global.Options[OptionType.NO_WALL_SLIDING] = !Global.Option(OptionType.NO_WALL_SLIDING); break; case 'b': Global.Options[OptionType.AUTOPICKUP] = !Global.Option(OptionType.AUTOPICKUP); break; case 'c': MouseUI.VisiblePath = !MouseUI.VisiblePath; break; case 'd': Global.Options[OptionType.TOP_ROW_MOVEMENT] = !Global.Option(OptionType.TOP_ROW_MOVEMENT); break; case 'e': Global.Options[OptionType.CONFIRM_BEFORE_RESTING] = !Global.Option(OptionType.CONFIRM_BEFORE_RESTING); break; case 'f': Global.Options[OptionType.DARK_GRAY_UNSEEN] = !Global.Option(OptionType.DARK_GRAY_UNSEEN); M.Draw(); if(Screen.GLMode){ Screen.UpdateGLBuffer(0,0,Global.SCREEN_H-1,Global.SCREEN_W-1); } break; case 'g': Global.Options[OptionType.NEVER_DISPLAY_TIPS] = !Global.Option(OptionType.NEVER_DISPLAY_TIPS); break; case 'h': Global.Options[OptionType.ALWAYS_RESET_TIPS] = !Global.Option(OptionType.ALWAYS_RESET_TIPS); break; case 'i': if(Global.LINUX && !Screen.GLMode){ colorchar[,] screen = Screen.GetCurrentScreen(); colorchar cch = new colorchar('@',Color.White); for(int i=0;i<Global.SCREEN_H;++i){ for(int j=i%2;j<Global.SCREEN_W;j+=2){ if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){ Screen.WriteChar(i,j,cch); } } } cch = new colorchar('@',Color.Green); for(int i=0;i<Global.SCREEN_H;++i){ Screen.WriteChar(i,0,cch); for(int j=1 + i%2;j<Global.SCREEN_W;j+=2){ if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){ Screen.WriteChar(i,j,cch); } } } cch = new colorchar('@',Color.Cyan); for(int j=0;j<Global.SCREEN_W;++j){ for(int i=0;i<Global.SCREEN_H;++i){ if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){ Screen.WriteChar(i,j,cch); } } } for(int i=0;i<Global.SCREEN_H;++i){ for(int j=0;j<Global.SCREEN_W;++j){ if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){ Screen.WriteChar(i,j,screen[i,j]); } } } } /*else{ if(Screen.GLMode){ Global.Options[OptionType.DISABLE_GRAPHICS] = !Global.Option(OptionType.DISABLE_GRAPHICS); GLGame.graphics_surface.Disabled = Global.Option(OptionType.DISABLE_GRAPHICS); Global.GRAPHICAL = !Global.Option(OptionType.DISABLE_GRAPHICS); if(Global.Option(OptionType.DISABLE_GRAPHICS)){ Screen.UpdateCursor(false); } else{ Game.gl.ResizeToDefault(); } } }*/ break; case (char)27: case ' ': case (char)13: done = true; break; default: break; } } MouseUI.PopButtonMap(); Q0(); break; } case '?': case '/': { Help.DisplayHelp(); Q0(); break; } case '-': { MouseUI.PushButtonMap(); UI.draw_bottom_commands = false; UI.darken_status_bar = true; Screen.CursorVisible = false; List<string> commandhelp = Help.HelpText(HelpTopic.Commands); commandhelp.RemoveRange(0,2); Screen.WriteMapString(0,0,"".PadRight(COLS,'-')); for(int i=0;i<23;++i){ Screen.WriteMapString(i+1,0,commandhelp[i].PadRight(COLS)); } Screen.WriteMapString(ROWS+2,0,"".PadRight(COLS,'-')); B.DisplayNow("Commands: "); Screen.CursorVisible = true; Input.ReadKey(); MouseUI.PopButtonMap(); UI.draw_bottom_commands = true; UI.darken_status_bar = false; Q0(); break; } case 'q': { List<string> ls = new List<string>(); ls.Add("Save your progress and exit to main menu"); ls.Add("Save your progress and quit game"); ls.Add("Abandon character and exit to main menu"); ls.Add("Abandon character and quit game"); ls.Add("Quit game immediately - don't save anything"); ls.Add("Continue playing"); bool no_close = Game.NoClose; Game.NoClose = false; Screen.CursorVisible = true; switch(Select("Quit? ",ls)){ case 0: Global.GAME_OVER = true; Global.SAVING = true; break; case 1: Global.GAME_OVER = true; Global.QUITTING = true; Global.SAVING = true; break; case 2: Global.GAME_OVER = true; Global.KILLED_BY = "giving up"; break; case 3: Global.GAME_OVER = true; Global.QUITTING = true; Global.KILLED_BY = "giving up"; break; case 4: Global.Quit(); break; case 5: default: break; } if(!Global.SAVING){ Q0(); } Game.NoClose = no_close; break; } case 'v': { UI.viewing_commands_idx = U.Modulo(UI.viewing_commands_idx + 1,3); MouseUI.PopButtonMap(); MouseUI.PushButtonMap(MouseMode.Map); MouseUI.CreateStatsButtons(); Q0(); break; } case '~': //debug mode { if(false){ List<string> l = new List<string>(); l.Add("blink"); l.Add("create chests"); l.Add("gain power"); l.Add("spawn monster"); l.Add("Forget the map"); l.Add("Heal to full"); l.Add("Become invulnerable"); l.Add("get items!"); l.Add("other"); l.Add("Use a rune of passage"); l.Add("See the entire level"); l.Add("Generate new level"); l.Add("Create ice or slime"); l.Add("Spawn shrines"); l.Add("create trap"); l.Add("create door"); l.Add("spawn lots of goblins and lose neck snap"); l.Add("brushfire test"); l.Add("detect monsters forever"); l.Add("get specific items"); switch(Select("Activate which cheat? ",l)){ case 0: { //new Item(ConsumableType.DETONATION,"orb of detonation",'*',Color.White).Use(this); new Item(ConsumableType.BLINKING,"orb of detonation",'*',Color.White).Use(this); Q1(); break; } case 1: { foreach(Tile t in TilesWithinDistance(3)){ t.TransformTo(TileType.CHEST); } Q0(); for(int i=0;i<20;++i){ Screen.WriteMapString(i,0,Item.GenerateScrollName().ToLower().PadRight(Global.COLS)); } foreach(EquipmentStatus st in Enum.GetValues(typeof(EquipmentStatus))){ EquippedWeapon.status[st] = true; } Input.ReadKey(); /*while(true){ var k = Input.ReadKey(); B.Add(k.Key.ToString() + "! "); B.Print(true); if(k.Key == ConsoleKey.M){ break; } }*/ break; } case 2: { /*int[,] row_displacement = GetDiamondSquarePlasmaFractal(ROWS,COLS); int[,] col_displacement = GetDiamondSquarePlasmaFractal(ROWS,COLS); colorchar[,] scr = Screen.GetCurrentMap(); M.actor[p] = null; scr[p.row,p.col] = M.VisibleColorChar(p.row,p.col); M.actor[p] = this; int total_rd = 0; int total_cd = 0; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ total_rd += row_displacement[i,j]; total_cd += col_displacement[i,j]; } } int avg_rd = total_rd / (ROWS*COLS); int avg_cd = total_cd / (ROWS*COLS); for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ row_displacement[i,j] -= avg_rd; col_displacement[i,j] -= avg_cd; } } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(i == p.row && j == p.col){ Screen.WriteMapChar(i,j,'@',Color.White); } else{ row_displacement[i,j] /= 8; col_displacement[i,j] /= 8; if(M.tile.BoundsCheck(i+row_displacement[i,j],j+col_displacement[i,j])){ Screen.WriteMapChar(i,j,scr[i+row_displacement[i,j],j+col_displacement[i,j]]); } else{ Screen.WriteMapChar(i,j,Screen.BlankChar()); } } } } Input.ReadKey(); var noise = U.GetNoise(17); for(int i=0;i<17;++i){ for(int j=0;j<17;++j){ char ch2 = '~'; if(noise[i,j] > 0.5f){ ch2 = '^'; } else{ if(noise[i,j] > 0.1f){ ch2 = '#'; } else{ if(noise[i,j] > -0.1f){ ch2 = '.'; } else{ if(noise[i,j] > -0.5f){ ch2 = ','; } } } } Screen.WriteChar(i,j,ch2); } //Screen.WriteMapString(i,0,Global.GenerateCharacterName().PadToMapSize()); //Screen.WriteMapString(i,0,Item.RandomItem().ToString().PadToMapSize()); } pos p1 = new pos(10,9); pos p1b = new pos(11,9); pos p2 = new pos(10,56); pos p2b = new pos(11,56); int dist = p1.ApproximateEuclideanDistanceFromX10(1,32) + p2.ApproximateEuclideanDistanceFromX10(1,32); for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(p1.ApproximateEuclideanDistanceFromX10(i,j) + p2.ApproximateEuclideanDistanceFromX10(i,j) <= dist || p1b.ApproximateEuclideanDistanceFromX10(i,j) + p2b.ApproximateEuclideanDistanceFromX10(i,j) <= dist){ Screen.WriteMapChar(i,j,'.'); } else{ Screen.WriteMapChar(i,j,'#'); } } } //Input.ReadKey(); //M.InitLevel(); //Move(1,1); //List<TileType> tilelist = new List<TileType>{TileType.WALL,TileType.WATER,TileType.VINE,TileType.WAX_WALL,TileType.FLOOR,TileType.BREACHED_WALL,TileType.DOOR_C,TileType.DOOR_O,TileType.CHEST,TileType.STATUE,TileType.FIREPIT,TileType.STALAGMITE,TileType.RUBBLE,TileType.COMBAT_SHRINE,TileType.DEFENSE_SHRINE,TileType.MAGIC_SHRINE,TileType.SPIRIT_SHRINE,TileType.STEALTH_SHRINE,TileType.SPELL_EXCHANGE_SHRINE,TileType.RUINED_SHRINE,TileType.FIRE_GEYSER,TileType.FOG_VENT,TileType.POISON_GAS_VENT,TileType.ICE,TileType.STONE_SLAB,TileType.CHASM,TileType.CRACKED_WALL,TileType.BRUSH,TileType.POPPY_FIELD,TileType.BLAST_FUNGUS,TileType.GLOWING_FUNGUS,TileType.TOMBSTONE,TileType.GRAVE_DIRT,TileType.BARREL,TileType.STANDING_TORCH,TileType.POISON_BULB,TileType.DEMONIC_IDOL,TileType.FIRE_TRAP,TileType.TELEPORT_TRAP,TileType.LIGHT_TRAP,TileType.SLIDING_WALL_TRAP,TileType.GRENADE_TRAP,TileType.SHOCK_TRAP,TileType.ALARM_TRAP,TileType.DARKNESS_TRAP,TileType.POISON_GAS_TRAP,TileType.BLINDING_TRAP,TileType.ICE_TRAP,TileType.PHANTOM_TRAP,TileType.SCALDING_OIL_TRAP,TileType.FLING_TRAP,TileType.STONE_RAIN_TRAP}; //List<pos> tileposlist = new List<pos>{new pos(0,0),new pos(4,0),new pos(8,0),new pos(12,0),new pos(0,8),new pos(0,9),new pos(0,10),new pos(2,10),new pos(4,10),new pos(8,10),new pos(12,10),new pos(13,10),new pos(14,10),new pos(0,11),new pos(1,11),new pos(2,11),new pos(3,11),new pos(4,11),new pos(5,11),new pos(6,11),new pos(8,11),new pos(9,11),new pos(10,11),new pos(11,11),new pos(12,11),new pos(14,11),new pos(15,11),new pos(0,12),new pos(4,12),new pos(5,12),new pos(10,12),new pos(12,12),new pos(13,12),new pos(14,12),new pos(15,12),new pos(0,13),new pos(1,13),new pos(0,14),new pos(1,14),new pos(2,14),new pos(3,14),new pos(4,14),new pos(5,14),new pos(6,14),new pos(7,14),new pos(8,14),new pos(9,14),new pos(10,14),new pos(11,14),new pos(12,14),new pos(13,14),new pos(14,14)}; int[] intarray = new int[16]; intarray[1] = 1; intarray[2] = 1; intarray[5] = -1; intarray[8] = 1; intarray[9] = -1; intarray[10] = 3; Bitmap bmp = new Bitmap("todo_remove.png"); Bitmap result; using(var temp = new Bitmap("result_remove.png")){ result = new Bitmap(temp); } //Bitmap result = new Bitmap("result_remove.png"); //int idx=0; foreach(ConsumableType ct in Enum.GetValues(typeof(ConsumableType))){ if(Item.NameOfItemType(ct) == "other"){ M.tile[2,2].inv = null; Item.Create(ct,2,2); colorchar cch = M.VisibleColorChar(2,2); int ch_offset = (int)(cch.c) * 16; int pos_col = 48 + (idx % 16); int pos_row = 5 + idx / 16; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color); } else{ result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent); } } } ++idx; } } attrs[AttrType.DETECTING_MONSTERS] = 1; for(ActorType at = ActorType.GOBLIN;at <= ActorType.DEMON_LORD;at++){ if(at != ActorType.MARBLE_HORROR_STATUE && at != ActorType.FINAL_LEVEL_CULTIST){ M.actor[2,2] = null; Actor.Create(at,2,2); colorchar cch = M.VisibleColorChar(2,2); int ch_offset = (int)(cch.c) * 16; int pos_col = 32 + (idx % 16); int pos_row = 4 + idx / 16; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color); } else{ result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent); } } } idx += 2; } } { colorchar cch = M.VisibleColorChar(1,1); int ch_offset = (int)(cch.c) * 16; int pos_col = 32; int pos_row = 0; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color); } else{ result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent); } } } } for(ActorType at = ActorType.PHANTOM_ZOMBIE;at <= ActorType.PHANTOM_CONSTRICTOR;at++){ M.actor[2,2] = null; Actor.CreatePhantom(2,2); if(!M.actor[2,2].Is(at)){ at--; continue; } colorchar cch = M.VisibleColorChar(2,2); int ch_offset = (int)(cch.c) * 16; int pos_col = 32 + (idx % 16); int pos_row = 4 + idx / 16; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color); } else{ result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent); result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent); } } } idx += 2; } int diff = 0; foreach(FeatureType ft in Enum.GetValues(typeof(FeatureType))){ M.tile[2,2] = null; Tile.Create(TileType.FLOOR,2,2); M.tile[2,2].revealed_by_light = true; M.tile[2,2].AddFeature(ft); colorchar cch = M.VisibleColorChar(2,2); int ch_offset = (int)(cch.c) * 16; int pos_col = 16 + (diff % 16); int pos_row = diff / 16; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color); } else{ result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent); } } } diff += intarray[idx]; diff++; ++idx; } foreach(TileType tt in tilelist){ M.tile[2,2] = null; pos tilepos = tileposlist[idx]; Tile.Create(tt,2,2); M.tile[2,2].revealed_by_light = true; colorchar cch = M.VisibleColorChar(2,2); int ch_offset = (int)(cch.c) * 16; for(int i=0;i<16;++i){ for(int j=0;j<16;++j){ if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){ System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb()); result.SetPixel(tilepos.row * 16 + j,tilepos.col * 16 + i,pixel_color); } else{ result.SetPixel(tilepos.row * 16 + j,tilepos.col * 16 + i,System.Drawing.Color.Black); } } } ++idx; }*/ Q0(); maxmp = 99; curmp = maxmp; skills[SkillType.MAGIC] = 10; foreach(SpellType sp in new List<SpellType>{SpellType.TELEKINESIS,SpellType.COLLAPSE,SpellType.FORCE_PALM,SpellType.GREASE,SpellType.AMNESIA,SpellType.FLYING_LEAP}){ GainSpell(sp); spells_in_order.Add(sp); } IsHiddenFrom(this); /*M.UpdateSafetyMap(player); var dijk = U.GetDijkstraMap(M.tile,x=>M.tile[x].BlocksConnectivityOfMap(),new List<pos>{this.p}); foreach(pos p in M.AllPositions()){ int v = M.safetymap[p]; colorchar cch = new colorchar(' ',Color.White); if(v == U.DijkstraMin){ cch.c = '#'; } if(v == U.DijkstraMax){ cch.c = '!'; } if(v.IsValidDijkstraValue()){ v /= 10; cch.c = (char)('z' - v.Modulo(26)); cch.color = (Color)(3 - (v+1)/26); } Screen.WriteMapChar(p.row,p.col,cch); } Input.ReadKey(); foreach(pos p in M.AllPositions()){ int v = M.safetymap[p]; colorchar cch = new colorchar(' ',Color.White); if(v == U.DijkstraMin){ cch.c = '#'; } if(v == U.DijkstraMax){ cch.c = '!'; } if(v.IsValidDijkstraValue()){ v = v/10 + dijk[p]; if(v > -2){ cch.c = ':'; } else{ cch.c = '.'; } cch.c = (char)('z' - v.Modulo(26)); cch.color = (Color)(3 - (v+1)/26); } Screen.WriteMapChar(p.row,p.col,cch); } Input.ReadKey();*/ break; } case 3: { /*ConsoleKeyInfo command2 = Input.ReadKey(); Screen.WriteMapString(14,14,((int)(command2.KeyChar)).ToString()); Input.ReadKey(); List<Tile> line = GetTarget(-1,-1); if(line != null){ Tile t = line.Last(); if(t != null){ t.AddOpaqueFeature(FeatureType.FOG); } }*/ Actor a = M.SpawnMob(ActorType.STALKING_WEBSTRIDER); /*foreach(Actor a in M.AllActors()){ if(a.type == ActorType.WARG){ a.attrs[AttrType.WANDERING] = 1; } }*/ Q0(); //M.GenerateFinalLevel(); break; } case 4: { Screen.CursorVisible = false; colorchar cch; cch.c = ' '; cch.color = Color.Black; cch.bgcolor = Color.Black; foreach(Tile t in M.AllTiles()){ t.seen = false; Screen.WriteMapChar(t.row,t.col,cch); } Screen.CursorVisible = true; Q0(); break; } case 5: curhp = maxhp; Q0(); break; case 6: if(!HasAttr(AttrType.INVULNERABLE)){ attrs[AttrType.INVULNERABLE]++; B.Add("On. "); } else{ attrs[AttrType.INVULNERABLE] = 0; B.Add("Off. "); } Q0(); break; case 7: { if(InventoryCount() >= Global.MAX_INVENTORY_SIZE){ inv = new List<Item>(); } while(InventoryCount() < Global.MAX_INVENTORY_SIZE){ Item.Create(Item.RandomItem(),this); } foreach(Item i in inv){ i.revealed_by_light = true; } Q0(); break; } case 8: { //int[,] a = GetBinaryNoise(ROWS,COLS); /*int[,] a = GetDividedNoise(ROWS,COLS,40); int[,] chances = new int[ROWS,COLS]; int[,] values = new int[ROWS,COLS]; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ bool passable = (a[i,j] == 1); if(passable){ values[i,j] = -1; } else{ values[i,j] = 0; } } } int minrow = 1; int maxrow = ROWS-2; int mincol = 1; int maxcol = COLS-2; int val = 0; bool done = false; while(!done){ done = true; for(int i=minrow;i<=maxrow;++i){ for(int j=mincol;j<=maxcol;++j){ if(values[i,j] == val){ for(int s=i-1;s<=i+1;++s){ for(int t=j-1;t<=j+1;++t){ if(values[s,t] == -1){ values[s,t] = val + 1; done = false; } } } } } } ++val; } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(a[i,j] == 1){ //distances[i,j] = values[i,j]; int k = 5 + values[i,j]; if(k >= 10){ chances[i,j] = 10; } else{ chances[i,j] = k; } } } } values = new int[ROWS,COLS]; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ bool passable = (a[i,j] == -1); if(passable){ values[i,j] = -1; } else{ values[i,j] = 0; } } } val = 0; done = false; while(!done){ done = true; for(int i=minrow;i<=maxrow;++i){ for(int j=mincol;j<=maxcol;++j){ if(values[i,j] == val){ for(int s=i-1;s<=i+1;++s){ for(int t=j-1;t<=j+1;++t){ if(values[s,t] == -1){ values[s,t] = val + 1; done = false; } } } } } } ++val; } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(a[i,j] == -1){ //distances[i,j] = -(values[i,j]); int k = 5 + values[i,j]; if(k >= 10){ chances[i,j] = 0; } else{ chances[i,j] = 10 - k; } } } } DungeonGen.StandardDungeon dungeon1 = new DungeonGen.StandardDungeon(); char[,] map1 = dungeon1.GenerateStandard(); DungeonGen.StandardDungeon dungeon2 = new DungeonGen.StandardDungeon(); char[,] map2 = dungeon2.GenerateCave(); char[,] map3 = new char[ROWS,COLS]; for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(a[i,j] == -1){ map3[i,j] = map1[i,j]; } else{ if(a[i,j] == 1){ map3[i,j] = map2[i,j]; } else{ if(map1[i,j] == '#'){ map3[i,j] = map2[i,j]; } else{ if(map2[i,j] == '#'){ map3[i,j] = map1[i,j]; } else{ if(R.CoinFlip()){ map3[i,j] = map1[i,j]; } else{ map3[i,j] = map2[i,j]; } } } } } } } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ Screen.WriteMapChar(i,j,map3[i,j]); if(distances[i,j] > -10){ if(distances[i,j] < 10){ if(distances[i,j] < 0){ Screen.WriteMapChar(i,j,(-distances[i,j]).ToString()[0],Color.DarkMagenta); } else{ if(distances[i,j] > 0){ Screen.WriteMapChar(i,j,distances[i,j].ToString()[0],Color.DarkCyan); } else{ Screen.WriteMapChar(i,j,distances[i,j].ToString()[0],Color.DarkGray); } } } else{ Screen.WriteMapChar(i,j,'+',Color.DarkCyan); } } else{ Screen.WriteMapChar(i,j,'-',Color.DarkMagenta); } } } tile().Toggle(null,TileType.BLAST_FUNGUS); List<Tile> area = new List<Tile>(); foreach(Tile t in TilesWithinDistance(3).Where(x=>x.passable && HasLOE(x))){ t.Toggle(null,TileType.POPPY_FIELD); area.Add(t); } Q.Add(new Event(area,100,EventType.POPPIES)); tile().Toggle(null,TileType.TOMBSTONE); Input.ReadKey(); List<string> movement = new List<string>{"is immobile","moves quickly","moves slowly"}; List<string> ability = new List<string>{"can step back after attacking","moves erratically","flies","can use an aggressive stance","uses a ranged attack","uses a burst attack","lunges","has a poisonous attack","drains life","has a powerful but slow attack","grabs its targets","has a knockback attack","has a slowing attack","has a silencing attack","can steal items","explodes when defeated","stays at range", "sidesteps when it attacks","has a paralyzing attack","has a stunning attack","is stealthy","appears with others of its type","carries a light source","is invisible in darkness","disrupts nearby spells","regenerates","comes back after death","wears armor","has heightened senses","has hard skin that can blunt edged weapons","casts spells","can reduce its target's attack power","can burrow"}; List<string> rare_ability = new List<string>{"is attracted to light","is blind in the light","can create illusions of itself","sets itself on fire","throws a bola to slow its targets","dims nearby light sources","screams to terrify its prey","howls to embolden others attacking its prey","breathes poison","is surrounded by a poisonous cloud", "is surrounded by a cloud of fog","can summon a minion","can fill the area with sunlight","is resistant to weapons","can turn into a statue","can throw explosives","can create stalagmites","collapses into rubble when defeated","has a fiery attack","can teleport its foes away","can pull its targets closer from a distance","releases spores when attacked","can absorb light to heal","leaves a trail as it travels","breathes fire","can spit blinding poison","lays volatile eggs","can breach nearby walls","is knocked back by blunt weapons","causes attackers to become exhausted","can create a temporary wall","can throw its foes overhead"}; char randomsymbol = (char)((R.Roll(26)-1) + (int)'a'); if(R.CoinFlip()){ randomsymbol = randomsymbol.ToString().ToUpper()[0]; } string s1 = "This monster is a " + Screen.GetColor(Color.RandomAny).ToString().ToLower().Replace("dark","dark ") + " '" + randomsymbol + "'. "; string s2 = "It "; bool add_move = R.OneIn(5); int num_abilities = R.Roll(2) + 1; if(R.OneIn(10)){ ++num_abilities; } int total = num_abilities; if(add_move){ ++total; } if(add_move){ --total; if(total == 0){ s2 = s2 + "and " + movement.Random() + ". "; } else{ s2 = s2 + movement.Random() + ", "; } } for(int i=num_abilities;i>0;--i){ --total; string a = ""; if(R.PercentChance(50)){ a = ability.Random(); } else{ a = rare_ability.Random(); } if(!s2.Contains(a)){ if(total == 0){ s2 = s2 + "and " + a + ". "; } else{ s2 = s2 + a + ", "; } } else{ ++i; ++total; } } if(add_rare){ --total; if(total == 0){ s2 = s2 + "and " + rare_ability.Random() + ". "; } else{ s2 = s2 + rare_ability.Random() + ", "; } } B.Add(s1); B.Add(s2); if(s2.Contains("casts spells")){ List<SpellType> all_spells = new List<SpellType>(); foreach(SpellType spl in Enum.GetValues(typeof(SpellType))){ all_spells.Add(spl); } all_spells.Remove(SpellType.NO_SPELL); all_spells.Remove(SpellType.NUM_SPELLS); string sp = "It can cast "; for(int num_spells = R.Roll(4);num_spells > 0;--num_spells){ if(num_spells == 1){ sp = sp + "and " + all_spells.RemoveRandom().ToString().ToLower().Replace('_',' ') + ". "; } else{ sp = sp + all_spells.RemoveRandom().ToString().ToLower().Replace('_',' ') + ", "; } } B.Add(sp); }*/ Q0(); foreach(Tile t in M.AllTiles()){ if(t.passable && DistanceFrom(t) > 4 && R.OneIn(10)){ ActorType at = (ActorType)R.Between(3,72); Actor.Create(at,t.row,t.col); } } break; } case 9: new Item(ConsumableType.PASSAGE,"rune of passage",'&',Color.White).Use(this); Q1(); break; case 10: foreach(Tile t in M.AllTiles()){ t.seen = true; colorchar ch2 = Screen.BlankChar(); if(t.IsKnownTrap() || t.IsShrine() || t.Is(TileType.RUINED_SHRINE)){ t.revealed_by_light = true; } if(t.inv != null){ t.inv.revealed_by_light = true; ch2.c = t.inv.symbol; ch2.color = t.inv.color; M.last_seen[t.row,t.col] = ch2; } else{ if(t.features.Count > 0){ ch2 = t.FeatureVisual(); M.last_seen[t.row,t.col] = ch2; } else{ ch2.c = t.symbol; ch2.color = t.color; if(ch2.c == '#' && ch2.color == Color.RandomGlowingFungus){ ch2.color = Color.Gray; } M.last_seen[t.row,t.col] = ch2; } } Screen.WriteMapChar(t.row,t.col,ch2); } //M.Draw(); foreach(Actor a in M.AllActors()){ Screen.WriteMapChar(a.row,a.col,new colorchar(a.color,Color.Black,a.symbol)); } Input.ReadKey(); Q0(); break; case 11: for(int i=0;i<1;++i){ if(M.current_level < 20){ //M.level_types[M.current_level] = LevelType.Standard; } M.GenerateLevel(); /*foreach(Tile t in M.AllTiles()){ if(t.TilesWithinDistance(1).Any(x=>x.type != TileType.WALL)){ t.seen = true; } } B.Print(false); M.Draw();*/ } Q0(); break; case 12: { /*PosArray<int> map = new PosArray<int>(ROWS,COLS); pos center = new pos(ROWS/2,COLS/2); int n = 2; foreach(pos p in center.PositionsWithinDistance(n-1)){ map[p] = 1; } bool changed = true; while(changed){ changed = false; List<pos> list = center.PositionsAtDistance(n); while(list.Count > 0){ pos p = list.RemoveRandom(); int count = p.PositionsAtDistance(1).Where(x=>map[x] == 1).Count; if(R.PercentChance(count*25)){ //this number can be anywhere from ~19 to 25 map[p] = 1; changed = true; } } ++n; } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ //pos p = new pos(i,j); //if(p.PositionsWithinDistance(1).Where(x=>map[x] == 1).Count >= 5){ if(map[i,j] == 1){ Screen.WriteMapChar(i,j,'.',Color.Green); } else{ Screen.WriteMapChar(i,j,'~',Color.Blue); } } } Input.ReadKey(); for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ pos p = new pos(i,j); if(p.PositionsWithinDistance(1).Where(x=>map[x] == 1).Count >= 5){ //if(map[i,j] == 1){ Screen.WriteMapChar(i,j,'.',Color.Green); } else{ Screen.WriteMapChar(i,j,'~',Color.Blue); } } } Input.ReadKey(); level = 10; skills[SkillType.COMBAT] = 10; skills[SkillType.DEFENSE] = 10; skills[SkillType.MAGIC] = 10; skills[SkillType.SPIRIT] = 10; skills[SkillType.STEALTH] = 10; foreach(FeatType f in Enum.GetValues(typeof(FeatType))){ if(f != FeatType.NO_FEAT && f != FeatType.NUM_FEATS){ feats[f] = true; } } foreach(Tile t in M.AllTiles()){ if(t.type == TileType.FLOOR){ if(R.CoinFlip()){ t.Toggle(null,TileType.STONE_RAIN_TRAP); } else{ t.Toggle(null,TileType.FLING_TRAP); } } } for(int i=0;i<10;++i){ M.SpawnMob(ActorType.FROSTLING); }*/ Q0(); RefreshDuration(AttrType.ENRAGED,1500); break; } case 13: { //LevelUp(); foreach(Tile t in TilesWithinDistance(2)){ t.TransformTo((TileType)(R.Between(0,4)+(int)TileType.COMBAT_SHRINE)); } Q0(); break; } case 14: { foreach(Tile t in TilesAtDistance(1)){ t.TransformTo(Tile.RandomTrap()); } Q0(); break; } case 15: { List<Tile> line = GetTargetTile(-1,0,false,false); if(line != null){ Tile t = line.LastOrDefault(); if(t != null){ //t.TransformTo(TileType.DOOR_O); if(t.Is(FeatureType.FIRE)){ t.RemoveFeature(FeatureType.FIRE); t.Toggle(null,TileType.DEMONIC_IDOL); } else{ t.AddFeature(FeatureType.FIRE); } } } Q0(); break; } case 16: { for(int i=0;i<100;++i){ M.SpawnMob(ActorType.GOBLIN); } if(HasFeat(FeatType.NECK_SNAP)){ feats[FeatType.NECK_SNAP] = false; } Q0(); break; } case 17: { /*List<Tile> list = new List<Tile>(); while(list.Count < 15){ int rr = R.Roll(ROWS-2); int rc = R.Roll(COLS-2); if(M.tile[rr,rc].passable){ list.AddUnique(M.tile[rr,rc]); } } for(int i=0;i<ROWS;++i){ for(int j=0;j<COLS;++j){ if(M.tile[i,j].passable){ List<Tile> closest_tiles = list.WhereLeast(x => x.ApproximateEuclideanDistanceFromX10(i,j)); //List<Tile> closest_tiles = list.WhereLeast(x => new Actor(this,i,j).GetPath(x.row,x.col).Count); if(closest_tiles.Count == 2){ Screen.WriteMapChar(i,j,'=',Color.White); } else{ int idx = list.IndexOf(closest_tiles[0]); Screen.WriteMapChar(i,j,M.tile[i,j].symbol,(Color)(idx+3)); } } else{ if(!M.tile[i,j].solid_rock){ Screen.WriteMapChar(i,j,M.tile[i,j].symbol,M.tile[i,j].color); } else{ Screen.WriteMapChar(i,j,Screen.BlankChar()); } } } } Screen.Blank(); Tile[] prev = new Tile[20]; int idx = 0; foreach(Tile t in M.ReachableTilesByDistance(row,col,false,TileType.DOOR_C)){ Screen.WriteMapChar(t.row,t.col,t.symbol,t.color); prev[idx] = t; idx = (idx + 1) % 20; if(prev[idx] != null){ Screen.WriteMapChar(prev[idx].row,prev[idx].col,Screen.BlankChar()); } Thread.Sleep(10); }*/ foreach(Actor a in M.AllActors()){ if(a != this){ a.Kill(); } } UpdateRadius(LightRadius(),0); for(int i=1;i<ROWS-1;++i){ for(int j=1;j<COLS-1;++j){ M.tile[i,j] = null; Tile.Create(TileType.BRUSH,i,j); } } UpdateRadius(0,LightRadius()); foreach(Tile t in M.AllTiles()){ if(t.TilesWithinDistance(1).Any(x=>x.type != TileType.WALL)){ t.seen = true; } } Q.KillEvents(null,EventType.CHECK_FOR_HIDDEN); M.wiz_lite = true; M.wiz_dark = false; B.Print(false); M.Draw(); Q0(); break; } case 18: { if(attrs[AttrType.DETECTING_MONSTERS] == 0){ attrs[AttrType.DETECTING_MONSTERS] = 1; } else{ attrs[AttrType.DETECTING_MONSTERS] = 0; } Q0(); break; } case 19: { /*List<Tile> line = GetTargetTile(-1,0,false); if(line != null){ Tile t = line.Last(); if(t != null){ t.Toggle(null,TileType.CHASM); Q.Add(new Event(t,100,EventType.FLOOR_COLLAPSE)); B.Add("The floor begins to collapse! "); } }*/ if(tile().inv == null){ tile().inv = Item.Create(ConsumableType.ENCHANTMENT,row,col); //TileInDirection(8).inv = Item.Create(ConsumableType.FLAMES,-1,-1); B.Add("You feel something roll beneath your feet. "); //magic_trinkets.Add(MagicTrinketType.PENDANT_OF_LIFE); } Q0(); break; } default: Q0(); break; } } else{ Q0(); } break; } case ' ': Q0(); break; default: B.Add("Press '?' for help. "); Q0(); break; } if(ch != 'x'){ attrs[AttrType.AUTOEXPLORE] = 0; } }
public static async Task TutorialTip(TutorialTopic topic){ if(Global.Option(OptionType.NEVER_DISPLAY_TIPS) || displayed[topic]){ return; } Color box_edge_color = Color.Blue; Color box_corner_color = Color.Yellow; Color first_line_color = Color.Yellow; Color text_color = Color.Gray; string[] text = TutorialText(topic); int stringwidth = 27; // length of "[Press any key to continue]" foreach(string s in text){ if(s.Length > stringwidth){ stringwidth = s.Length; } } stringwidth += 4; //2 blanks on each side int boxwidth = stringwidth + 2; int boxheight = text.Length + 5; //for(bool done=false;!done;){ colorstring[] box = new colorstring[boxheight]; //maybe i should make this a list to match the others box[0] = new colorstring("+",box_corner_color,"".PadRight(stringwidth,'-'),box_edge_color,"+",box_corner_color); box[text.Length + 1] = new colorstring("|",box_edge_color,"".PadRight(stringwidth),Color.Gray,"|",box_edge_color); box[text.Length + 2] = new colorstring("|", box_edge_color) + ("[Press any key to continue]".PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here box[text.Length + 3] = new colorstring("|", box_edge_color) + ("[=] Stop showing tips".PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here box[text.Length + 4] = new colorstring("+",box_corner_color,"".PadRight(stringwidth,'-'),box_edge_color,"+",box_corner_color); int pos = 1; foreach(string s in text){ box[pos] = new colorstring("|", box_edge_color) + (s.PadOuter(stringwidth).GetColorString(text_color)) + new colorstring("|", box_edge_color); //PadOuter originally here if(pos == 1){ box[pos] = new colorstring(); box[pos].strings.Add(new cstr("|",box_edge_color)); box[pos].strings.Add(new cstr(s.PadOuter(stringwidth), first_line_color)); //PadOuter originally here box[pos].strings.Add(new cstr("|",box_edge_color)); } ++pos; } int y = (Global.SCREEN_H - boxheight) / 2; int x = (Global.SCREEN_W - boxwidth) / 2; colorchar[,] memory = Screen.GetCurrentRect(y,x,boxheight,boxwidth); List<List<colorstring>> frames = new List<List<colorstring>>(); frames.Add(BoxAnimationFrame(boxheight-2,FrameWidth(boxheight,boxwidth))); for(int i=boxheight-4;i>0;i-=2){ frames.Add(BoxAnimationFrame(i,FrameWidth(frames.Last().Count,frames.Last()[0].Length()))); } for(int i=frames.Count-1;i>=0;--i){ //since the frames are in reverse order int y_offset = i + 1; int x_offset = (boxwidth - frames[i][0].Length()) / 2; Screen.WriteList(y+y_offset,x+x_offset,frames[i]); await Task.Delay(20); } foreach(colorstring s in box){ Screen.WriteString(y,x,s); ++y; } Actor.player.DisplayStats(false); if(topic != TutorialTopic.Feats){ //hacky exception - don't get rid of the line that's already there. Actor.B.DisplayNow(); } Game.Console.CursorVisible = false; await Task.Delay(500); Global.FlushInput(); /* switch(Game.Console.ReadKey(true).KeyChar){ case 'q': box_edge_color = NextColor(box_edge_color); break; case 'w': box_corner_color = NextColor(box_corner_color); break; case 'e': first_line_color = NextColor(first_line_color); break; case 'r': text_color = NextColor(text_color); break; default: done=true; break; } }*/ if((await Game.Console.ReadKey(true)).KeyChar == '='){ Global.Options[OptionType.NEVER_DISPLAY_TIPS] = true; } Screen.WriteArray((Global.SCREEN_H - boxheight) / 2,x,memory); if(topic != TutorialTopic.Feats){ //another exception Actor.player.DisplayStats(true); } displayed[topic] = true; Game.Console.CursorVisible = true; }
public static void WriteString(int r,int c,colorstring cs) { if(cs.Length() > 0){ int pos = c; int start_col = -1; int end_col = -1; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(s.s.Length + pos > Global.SCREEN_W){ s.s = s.s.Substring(0,Global.SCREEN_W - pos); } s.color = Colors.ResolveColor(s.color); s.bgcolor = Colors.ResolveColor(s.bgcolor); colorchar cch; cch.color = s.color; cch.bgcolor = s.bgcolor; if(!GLMode){ ConsoleColor co = Colors.GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = Colors.GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } } int i = 0; bool changed = false; foreach(char ch in s.s){ cch.c = ch; if(!memory[r,pos+i].Equals(cch)){ memory[r,pos+i] = cch; if(start_col == -1){ start_col = pos+i; } end_col = pos+i; changed = true; } ++i; } if(changed && !GLMode){ Console.SetCursorPosition(pos,r); Console.Write(s.s); } pos += s.s.Length; } if(GLMode && !NoGLUpdate && start_col != -1){ UpdateGLBuffer(r,start_col,r,end_col); } if(MouseUI.AutomaticButtonsFromStrings && GLMode){ int idx = 0; int brace = -1; int start = -1; int end = -1; bool last_char_was_separator = false; while(true){ char ch = cs[idx].c; if(brace == -1){ if(ch == '['){ brace = 0; start = idx; } } else{ if(brace == 0){ if(ch == ']'){ brace = 1; end = idx; } } else{ if(ch == ' ' || ch == '-' || ch == ','){ if(last_char_was_separator){ ConsoleKey key = ConsoleKey.A; bool shifted = false; switch(cs[start+1].c){ case 'E': key = ConsoleKey.Enter; break; case 'T': key = ConsoleKey.Tab; break; case 'P': //"Press any key" break; case '?': key = ConsoleKey.Oem2; shifted = true; break; case '=': key = ConsoleKey.OemPlus; break; default: //all others should be lowercase letters key = (ConsoleKey)(ConsoleKey.A + ((int)cs[start+1].c - (int)'a')); break; } MouseUI.CreateButton(key,shifted,r,c+start,1,end-start+1); brace = -1; start = -1; end = -1; } last_char_was_separator = !last_char_was_separator; } else{ last_char_was_separator = false; end = idx; } } } ++idx; if(idx == cs.Length()){ if(brace == 1){ ConsoleKey key = ConsoleKey.A; bool shifted = false; switch(cs[start+1].c){ case 'E': key = ConsoleKey.Enter; break; case 'T': key = ConsoleKey.Tab; break; case 'P': //"Press any key" break; case '?': key = ConsoleKey.Oem2; shifted = true; break; case '=': key = ConsoleKey.OemPlus; break; default: //all others should be lowercase letters key = (ConsoleKey)(ConsoleKey.A + ((int)cs[start+1].c - (int)'a')); break; } MouseUI.CreateButton(key,shifted,r,c+start,1,end-start+1); } break; } } } } }
public colorstring NameOnStatusBar() { if(IsEnchanted()){ colorstring cs = new colorstring("+",EnchantmentColor()); return new colorstring("-- ",cs,NameWithoutEnchantment().Capitalize(),cs," --").PadOuter(Global.STATUS_WIDTH); } else{ return new colorstring(("-- " + NameWithoutEnchantment().Capitalize() + " --").PadOuter(Global.STATUS_WIDTH),Color.Gray); } }
public static colorstring operator +(cstr one,colorstring two) { //todo: whoops, forgot colorchar in this section. colorstring result = new colorstring(); result.strings.Add(one); foreach(cstr s in two.strings){ result.strings.Add(s); } return result; }
public static colorstring operator +(colorstring one,colorstring two){ colorstring result = new colorstring(); foreach(cstr s in one.strings){ result.strings.Add(s); } foreach(cstr s in two.strings){ result.strings.Add(s); } return result; }
public static colorstring operator +(colorstring one,string two) { colorstring result = new colorstring(); foreach(cstr s in one.strings){ result.strings.Add(s); } result.strings.Add(new cstr(two,Color.Gray)); return result; }
public static void WriteMapString(int r,int c,colorstring cs){ if(cs.Length() > 0){ r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; int cpos = c; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(cpos-Global.MAP_OFFSET_COLS + s.s.Length > Global.COLS){ s.s = s.s.Substring(0,Global.COLS-(cpos-Global.MAP_OFFSET_COLS)); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /* cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,cpos+i].Equals(cch)){ memory[r,cpos+i] = cch; changed = true; } ++i; } if(changed){ Game.Console.SetCursorPosition(cpos,r); Game.Console.Write(s.s); } cpos += s.s.Length; } /*if(cpos-Global.MAP_OFFSET_COLS < Global.COLS){ WriteString(r,cpos,"".PadRight(Global.COLS-(cpos-Global.MAP_OFFSET_COLS))); }*/ } }
public static void AddWithWrap(this List <colorstring> l, colorstring cs, int wrap_width, int indent = 0) { colorstring last = l.LastOrDefault(); colorstring remainder = null; if (last == null) { remainder = cs; } else { if (last.Length() + cs.Length() <= wrap_width) { foreach (cstr s in cs.strings) { last.strings.Add(s); } } else { int split_idx = cs.LastSpaceBeforeWrap(wrap_width - last.Length()); if (split_idx == -1) { remainder = cs; } else { var split = cs.SplitAt(split_idx, true); foreach (cstr s in split[0].strings) { last.strings.Add(s); } remainder = split[1]; } } } while (remainder?.Length() > 0) { if (indent + remainder.Length() <= wrap_width) { l.Add(new colorstring("".PadRight(indent)) + remainder); break; } else { colorstring next = new colorstring("".PadRight(indent)); l.Add(next); int split_idx = remainder.LastSpaceBeforeWrap(wrap_width - indent); bool remove_space = true; if (split_idx == -1) // if there's nowhere better, just cut it off at the end of the line. { split_idx = wrap_width - indent; remove_space = false; } var split = remainder.SplitAt(split_idx, remove_space); foreach (cstr s in split[0].strings) { next.strings.Add(s); } remainder = split[1]; } } }
public virtual List<colorstring> GetStatusBarInfo() { List<colorstring> result = new List<colorstring>(); Color text = UI.darken_status_bar? Colors.status_darken : Color.Gray; if(p.Equals(UI.MapCursor)){ text = UI.darken_status_bar? Colors.status_highlight_darken : Colors.status_highlight; } foreach(string s in name.GetWordWrappedList(17,true)){ colorstring cs = new colorstring(); result.Add(cs); if(result.Count == 1){ cs.strings.Add(new cstr(symbol.ToString(),color)); cs.strings.Add(new cstr(": " + s,text)); } else{ cs.strings.Add(new cstr(" " + s,text)); } } if(name == "troll corpse"){ //gotta do this here, since TerrainFeature isn't a class. result.Add(new colorstring("Regenerating".PadOuter(Global.STATUS_WIDTH),text,Color.StatusEffectBar)); } else{ if(name == "troll bloodwitch corpse"){ result.Add(new colorstring("Regenerating 3".PadOuter(Global.STATUS_WIDTH),text,Color.StatusEffectBar)); } } return result; }
public int Select(string message,colorstring top_border,colorstring bottom_border,List<colorstring> strings,bool no_ask,bool no_cancel,bool easy_cancel,bool never_redraw_map,bool help_key,HelpTopic help_topic) { if(!no_ask){ MouseUI.PushButtonMap(); } MouseUI.AutomaticButtonsFromStrings = true; int result = -2; while(result == -2){ Screen.WriteMapString(0,0,top_border); char letter = 'a'; int i=1; foreach(colorstring s in strings){ Screen.WriteMapString(i,0,new colorstring("[",Color.Gray,letter.ToString(),Color.Cyan,"] ",Color.Gray)); Screen.WriteMapString(i,4,s); if(s.Length() < COLS-4){ Screen.WriteMapString(i,s.Length()+4,"".PadRight(COLS - (s.Length()+4))); } letter++; i++; } Screen.WriteMapString(i,0,bottom_border); if(i < ROWS-1){ Screen.WriteMapString(i+1,0,"".PadRight(COLS)); } if(no_ask){ B.DisplayNow(message); if(!no_ask){ MouseUI.PopButtonMap(); } MouseUI.AutomaticButtonsFromStrings = false; return -1; } else{ result = GetSelection(message,strings.Count,no_cancel,easy_cancel,help_key); if(result == -2){ MouseUI.AutomaticButtonsFromStrings = false; Help.DisplayHelp(help_topic); MouseUI.AutomaticButtonsFromStrings = true; } else{ if(!never_redraw_map && result != -1){ M.Redraw(); } if(!no_ask){ MouseUI.PopButtonMap(); } MouseUI.AutomaticButtonsFromStrings = false; return result; } } } if(!no_ask){ MouseUI.PopButtonMap(); } MouseUI.AutomaticButtonsFromStrings = false; return -1; }
public static void StatusWriteString(ref int row,colorstring s) { if(row >= status_row_cutoff){ return; } Screen.WriteString(row,0,s); ++row; }
public int Select(string message,colorstring top_border,colorstring bottom_border,List<colorstring> strings,bool no_ask,bool no_cancel,bool easy_cancel,bool help_key,HelpTopic help_topic) { return Select(message,top_border,bottom_border,strings,no_ask,no_cancel,easy_cancel,false,help_key,help_topic); }
public colorstring[] SplitAt(int idx,bool remove_at_split_idx = false) { if(idx < 0){ throw new ArgumentOutOfRangeException("idx argument " + idx.ToString() + " can't be negative."); } if(idx >= Length()){ throw new ArgumentOutOfRangeException("idx argument " + idx.ToString() + " can't be outside the string."); } colorstring[] result = new colorstring[2]; result[0] = new colorstring(); result[1] = new colorstring(); foreach(cstr s in strings){ int len_0 = result[0].Length(); if(len_0 < idx){ if(len_0 + s.s.Length > idx){ result[0].strings.Add(new cstr(s.s.Substring(0,idx - len_0),s.color,s.bgcolor)); int second_start = idx - len_0; if(remove_at_split_idx){ ++second_start; } if(second_start < s.s.Length){ result[1].strings.Add(new cstr(s.s.Substring(idx - len_0),s.color,s.bgcolor)); } if(result[0].Length() != idx){ throw new Exception("whoops"); //todo, remove this after it works. } } else{ result[0].strings.Add(s); } } else{ result[1].strings.Add(s); } } return result; }
public override List<colorstring> GetStatusBarInfo() { string s_name = name; int s_curhp = curhp; int s_maxhp = maxhp; string s_aware = AwarenessStatus(); if(type == ActorType.DREAM_WARRIOR_CLONE){ if(group != null && group.Count > 0){ foreach(Actor a in group){ if(a.type == ActorType.DREAM_WARRIOR){ s_name = a.name; s_curhp = a.curhp; s_maxhp = a.maxhp; s_aware = a.AwarenessStatus(); } } } } if(type == ActorType.DREAM_SPRITE_CLONE){ if(group != null && group.Count > 0){ foreach(Actor a in group){ if(a.type == ActorType.DREAM_SPRITE){ s_name = a.name; s_curhp = a.curhp; s_maxhp = a.maxhp; s_aware = a.AwarenessStatus(); } } } } List<colorstring> result = new List<colorstring>(); Color text = UI.darken_status_bar? Colors.status_darken : Color.Gray; if(p.Equals(UI.MapCursor)){ text = UI.darken_status_bar? Colors.status_highlight_darken : Colors.status_highlight; } foreach(string s in s_name.Capitalize().GetWordWrappedList(Global.STATUS_WIDTH - 3,true)){ colorstring cs = new colorstring(); result.Add(cs); if(result.Count == 1){ cs.strings.Add(new cstr(symbol.ToString(),color)); cs.strings.Add(new cstr(": " + s,text)); } else{ cs.strings.Add(new cstr(" " + s,text)); } } string hp = ("HP: " + s_curhp.ToString() + " (" + s_aware + ")").PadOuter(Global.STATUS_WIDTH); int idx = UI.GetStatusBarIndex(s_curhp,s_maxhp); result.Add(new colorstring(new cstr(hp.SafeSubstring(0,idx),text,Color.HealthBar),new cstr(hp.SafeSubstring(idx),text))); Dictionary<AttrType,Event> events = Q.StatusEvents.ContainsKey(this)? Q.StatusEvents[this] : null; foreach(AttrType attr in UI.displayed_statuses){ if(HasAttr(attr) && !attr.StatusIsHidden(this)){ int value = 1; int max = 1; // If no other data is found, a full bar (1/1) will be shown. if(!attr.StatusByStrength(this,(events != null && events.ContainsKey(attr))? events[attr] : null,ref value,ref max)){ if(events != null && events.ContainsKey(attr)){ Event e = events[attr]; value = e.delay + e.time_created + 100 - Q.turn; max = e.delay; } } int attr_idx = UI.GetStatusBarIndex(value,max); string attr_name = attr.StatusName(this).PadOuter(Global.STATUS_WIDTH); result.Add(new colorstring(new cstr(attr_name.SafeSubstring(0,attr_idx),text,Color.StatusEffectBar),new cstr(attr_name.SafeSubstring(attr_idx),text))); } } if(p.BoundsCheck(M.tile)){ //in rare cases, the sidebar could be updated while a burrowing enemy is still present. this prevents a crash in that situation. if(tile().Is(FeatureType.WEB) && !HasAttr(AttrType.BURNING,AttrType.SLIMED,AttrType.OIL_COVERED)){ result.Add(new colorstring("Webbed".PadOuter(Global.STATUS_WIDTH),text,Color.StatusEffectBar)); } if(IsSilencedHere() && !HasAttr(AttrType.SILENCED,AttrType.SILENCE_AURA)){ result.Add(new colorstring(AttrType.SILENCED.StatusName(this).PadOuter(Global.STATUS_WIDTH),text,Color.StatusEffectBar)); } } return result; }