public static void SetWeaponImprovedCriticalFeat(BaseItemType baseItem, FeatType feat) { Internal.NativeFunctions.nwnxSetFunction(PLUGIN_NAME, "SetWeaponImprovedCriticalFeat"); Internal.NativeFunctions.nwnxPushInt(feat.InternalValue); Internal.NativeFunctions.nwnxPushInt(baseItem.InternalValue); Internal.NativeFunctions.nwnxCallFunction(); }
public static int GetSkillFeatCountForSkill(FeatType feat) { Internal.NativeFunctions.nwnxSetFunction(PLUGIN_NAME, "GetSkillFeatCountForSkill"); Internal.NativeFunctions.nwnxPushInt(feat.InternalValue); Internal.NativeFunctions.nwnxCallFunction(); return(Internal.NativeFunctions.nwnxPopInt()); }
public static void SetEpicWeaponSpecializationFeat(BaseItemType baseItem, FeatType feat) { Internal.NativeFunctions.nwnxSetFunction(PLUGIN_NAME, "SetEpicWeaponSpecializationFeat"); Internal.NativeFunctions.nwnxPushInt(feat.InternalValue); Internal.NativeFunctions.nwnxPushInt(baseItem.InternalValue); Internal.NativeFunctions.nwnxCallFunction(); }
public static void SetFavoredEnemyFeat(RacialType iRace, FeatType iFeat) { Internal.NativeFunctions.nwnxSetFunction(PLUGIN_NAME, "SetFavoredEnemyFeat"); Internal.NativeFunctions.nwnxPushInt(iFeat.InternalValue); Internal.NativeFunctions.nwnxPushInt(iRace.InternalValue); Internal.NativeFunctions.nwnxCallFunction(); }
public Feat(string name, string prereqs, string description, FeatType featType) { Name = name; PrerequisitesString = prereqs; Description = description; FeatType = featType; Link = "https://aonprd.com/FeatDisplay.aspx?ItemName=" + Name; }
public Feat(string name, FeatType type, int eventFrame, Color color, string description) { this.name = name; featType = type; this.eventFrame = eventFrame; this.color = color; this.description = description; }
/// <summary> /// Create a QBS for using a feat /// </summary> /// <param name="nFeat"></param> /// <returns></returns> public static QuickBarSlot UseFeat(FeatType nFeat) { var qbs = Empty(QuickBarSlotType.Feat); qbs.INTParam1 = nFeat.InternalValue; return(qbs); }
public FeatImpl(string id, FeatType type) { ArgumentValidationHelper.AssertNotNullOrWhiteSpace(id, "id"); Id = id; ArgumentValidationHelper.AssertNotNull(type, "type"); Type = type; }
public IEnumerable <Feat> GetFeats(Uri uri, FeatType featType = FeatType.General) { ScrapingBrowser browser = new ScrapingBrowser { AllowAutoRedirect = true, AllowMetaRedirect = true }; WebPage page = browser.NavigateToPage(uri); HtmlNode node = page.Html.CssSelect("#ctl00_MainContent_GridView6").First(); var feats = new List <Feat>(); foreach (var c in node.SelectNodes("tr")) { var values = new List <string>(); foreach (var cn in c.ChildNodes) { if (cn.Name == "td") { values.Add(cn.InnerText); } } if (values.Count == 0) { continue; } var name = values[0].Trim().Replace("???", ""); if (name.Contains("*")) { name = name.Replace("*", ""); if (featType == FeatType.General) { featType = FeatType.Combat; } } var prereqs = values[1].Trim().Replace("???", "'"); prereqs = Regex.Replace(prereqs, @"(\&.*)", "-"); var description = values[2].Trim().Replace("???", "'"); description = Regex.Replace(description, @"(?<=)(\')(?=\d)", "-"); description = Regex.Replace(description, @"(?<=\/)(\')(?=)", "-"); feats.Add(new Feat(name, prereqs, description, featType)); } return(feats); }
// GET: FeatTypes/Edit/5 public ActionResult Edit(int?id) { if (id == null) { return(NotFound()); } FeatType featType = DAL.GetFeatType((int)id); if (featType == null) { return(NotFound()); } return(View(featType)); }
public ActionResult Create([Bind("Name,ID")] FeatType featType) { if (ModelState.IsValid) { if (DAL.CreateFeatType(featType) > 0) { //success } else { //error } return(RedirectToAction(nameof(Index))); } return(View(featType)); }
public Feat(int id, string name, int level, FeatType featType, FeatAction featAction, string featSubType, List <string> traits, List <int> pre, string preText, string fre, string cost, string trigger, string req, string desc, string spec) { Id = id; Name = name; Level = level; FeatType = featType; FeatAction = featAction; FeatSubType = featSubType; Traits = traits; Prerequisites = pre; PrerequisitesText = preText; Frequency = fre; Cost = cost; Trigger = trigger; Requirements = req; Description = desc; Special = spec; }
public ActionResult Edit(int id, [Bind("Name,ID")] FeatType featType) { if (id != featType.ID) { return(NotFound()); } if (ModelState.IsValid) { if (DAL.UpdateFeatType(featType, id) > 0) { //success } else { //error } return(RedirectToAction(nameof(Index))); } return(View(featType)); }
public static SkillFeat GetSkillFeat(FeatType feat, SkillType skill) { Internal.NativeFunctions.nwnxSetFunction(PLUGIN_NAME, "GetSkillFeat"); Internal.NativeFunctions.nwnxPushInt(feat.InternalValue); Internal.NativeFunctions.nwnxPushInt(skill.InternalValue); Internal.NativeFunctions.nwnxCallFunction(); return(new SkillFeat { skill = skill.InternalValue, feat = feat.InternalValue, modifier = Internal.NativeFunctions.nwnxPopInt(), focusFeat = Internal.NativeFunctions.nwnxPopInt(), classes = Internal.NativeFunctions.nwnxPopString(), classLevelMod = Internal.NativeFunctions.nwnxPopFloat(), areaFlagsRequired = Internal.NativeFunctions.nwnxPopInt(), areaFlagsForbidden = Internal.NativeFunctions.nwnxPopInt(), dayOrNight = Internal.NativeFunctions.nwnxPopInt(), bypassArmorCheckPenalty = Internal.NativeFunctions.nwnxPopInt(), keyAbilityMask = Internal.NativeFunctions.nwnxPopInt() }); }
public static bool IsActivated(FeatType type) { switch(type){ case FeatType.LUNGE: case FeatType.TUMBLE: case FeatType.DISARM_TRAP: return true; case FeatType.QUICK_DRAW: case FeatType.WHIRLWIND_STYLE: case FeatType.DRIVE_BACK: case FeatType.CUNNING_DODGE: case FeatType.ARMOR_MASTERY: case FeatType.DEFLECT_ATTACK: case FeatType.MASTERS_EDGE: case FeatType.ARCANE_INTERFERENCE: case FeatType.CHAIN_CASTING: case FeatType.FORCE_OF_WILL: case FeatType.CONVICTION: case FeatType.ENDURING_SOUL: case FeatType.FEEL_NO_PAIN: case FeatType.BOILING_BLOOD: case FeatType.NECK_SNAP: case FeatType.CORNER_CLIMB: case FeatType.DANGER_SENSE: default: return false; } }
public static string Name(FeatType type) { switch(type){ case FeatType.CORNER_CLIMB: return "Corner climb"; case FeatType.QUICK_DRAW: return "Quick draw"; case FeatType.CUNNING_DODGE: return "Cunning dodge"; case FeatType.DANGER_SENSE: return "Danger sense"; case FeatType.DEFLECT_ATTACK: return "Deflect attack"; case FeatType.ENDURING_SOUL: return "Enduring soul"; case FeatType.NECK_SNAP: return "Neck snap"; case FeatType.BOILING_BLOOD: return "Boiling blood"; case FeatType.WHIRLWIND_STYLE: return "Whirlwind style"; case FeatType.LUNGE: return "Lunge"; case FeatType.DRIVE_BACK: return "Drive back"; case FeatType.ARMOR_MASTERY: return "Armor mastery"; case FeatType.TUMBLE: return "Tumble"; case FeatType.MASTERS_EDGE: return "Master's edge"; case FeatType.ARCANE_INTERFERENCE: return "Arcane interference"; case FeatType.CHAIN_CASTING: return "Chain casting"; case FeatType.FORCE_OF_WILL: return "Force of will"; case FeatType.CONVICTION: return "Conviction"; case FeatType.FEEL_NO_PAIN: return "Feel no pain"; case FeatType.DISARM_TRAP: return "Disarm trap"; default: return "no feat"; } }
public static SkillType Skill(FeatType type) { switch(type){ case FeatType.QUICK_DRAW: case FeatType.WHIRLWIND_STYLE: case FeatType.LUNGE: case FeatType.DRIVE_BACK: return SkillType.COMBAT; case FeatType.ARMOR_MASTERY: case FeatType.DEFLECT_ATTACK: case FeatType.TUMBLE: case FeatType.CUNNING_DODGE: return SkillType.DEFENSE; case FeatType.MASTERS_EDGE: case FeatType.ARCANE_INTERFERENCE: case FeatType.CHAIN_CASTING: case FeatType.FORCE_OF_WILL: return SkillType.MAGIC; case FeatType.ENDURING_SOUL: case FeatType.BOILING_BLOOD: case FeatType.CONVICTION: case FeatType.FEEL_NO_PAIN: return SkillType.SPIRIT; case FeatType.CORNER_CLIMB: case FeatType.DANGER_SENSE: case FeatType.NECK_SNAP: case FeatType.DISARM_TRAP: return SkillType.STEALTH; default: return SkillType.NO_SKILL; } }
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 static bool IsActivated(FeatType type) { switch (type) { case FeatType.LUNGE: case FeatType.TUMBLE: case FeatType.ARCANE_SHIELD: case FeatType.FORCE_OF_WILL: case FeatType.DISARM_TRAP: case FeatType.DISTRACT: return true; case FeatType.QUICK_DRAW: case FeatType.LETHALITY: case FeatType.DRIVE_BACK: case FeatType.SILENT_CHAINMAIL: case FeatType.ARMORED_MAGE: case FeatType.FULL_DEFENSE: case FeatType.MASTERS_EDGE: case FeatType.STUDENTS_LUCK: case FeatType.CONVICTION: case FeatType.ENDURING_SOUL: case FeatType.FEEL_NO_PAIN: case FeatType.BOILING_BLOOD: case FeatType.NECK_SNAP: case FeatType.DANGER_SENSE: default: return false; } }
public static string Name(FeatType type) { switch (type) { case FeatType.DISTRACT: return "Distract"; case FeatType.QUICK_DRAW: return "Quick draw"; case FeatType.SILENT_CHAINMAIL: return "Silent chainmail"; case FeatType.DANGER_SENSE: return "Danger sense"; case FeatType.FULL_DEFENSE: return "Full defense"; case FeatType.ENDURING_SOUL: return "Enduring soul"; case FeatType.NECK_SNAP: return "Neck snap"; case FeatType.BOILING_BLOOD: return "Boiling blood"; case FeatType.LETHALITY: return "Lethality"; case FeatType.LUNGE: return "Lunge"; case FeatType.DRIVE_BACK: return "Drive back"; case FeatType.ARMORED_MAGE: return "Armored mage"; case FeatType.TUMBLE: return "Tumble"; case FeatType.MASTERS_EDGE: return "Master's edge"; case FeatType.STUDENTS_LUCK: return "Student's luck"; case FeatType.ARCANE_SHIELD: return "Arcane shield"; case FeatType.FORCE_OF_WILL: return "Force of will"; case FeatType.CONVICTION: return "Conviction"; case FeatType.FEEL_NO_PAIN: return "Feel no pain"; case FeatType.DISARM_TRAP: return "Disarm trap"; default: return "no feat"; } }
public static List<string> Description(FeatType type) { switch (type) { case FeatType.QUICK_DRAW: return new List<string>{ "Wielding a different weapon takes no time.", "(This also enables you to fire arrows without first switching", "to your bow.)"}; case FeatType.LETHALITY: return new List<string>{ "Your chance to score a critical hit increases by 10%. This", "bonus also increases by 5% for each 20% health that the target", "is missing."}; case FeatType.LUNGE: return new List<string>{ "Leap from one space away and attack your target (with a +4", "bonus to Combat). The intervening space must be unoccupied."}; case FeatType.DRIVE_BACK: return new List<string>{ "Enemies must yield ground in order to avoid your attacks.", "(If your target has nowhere to run, your attacks will", "automatically hit.)"}; case FeatType.SILENT_CHAINMAIL: return new List<string>{ "You can wear chainmail with no penalty to stealth."}; case FeatType.ARMORED_MAGE: return new List<string>{ "You can cast spells with no penalty from your armor."}; case FeatType.FULL_DEFENSE: return new List<string>{ "Stand still to ready yourself for attack. You gain an extra", "50% chance to avoid attacks while readied. Enemies that try to", "hit you might hit other adjacent enemies instead."}; case FeatType.TUMBLE: return new List<string>{ "Move up to 2 spaces while avoiding arrows. (Also useful for", "slipping behind enemies and putting out fires.)"}; case FeatType.MASTERS_EDGE: /*return new List<string>{ "Spells you've mastered deal 1d6 extra damage. (You've mastered", "a spell if its natural chance of failure is 0%.)"};*/ return new List<string>{ "The first offensive spell you've learned will deal 1d6 extra", "damage. (Affects the first spell in the list that deals damage", "directly.)"}; case FeatType.STUDENTS_LUCK: return new List<string>{ "Casting a spell of higher level than your Magic skill will now", "only drain your magic reserves 50% of the time."}; case FeatType.ARCANE_SHIELD: /*return new List<string>{ "Drain your magic reserves to heal some of your wounds. Heals", "at least 25% of your HP, with a bonus for Magic skill. (Each", "drain on your magic reserves gives an extra 25% failure rate", "to your spells, and lasts until you rest.)"};*/ return new List<string>{ "Drain your magic reserves to shield yourself. The shield lasts", "for 20 turns and can block 25 damage, plus a bonus for Magic", "skill. (Each drain on your magic reserves gives an extra 25%", "failure rate to your spells, and lasts until you rest.)"}; case FeatType.FORCE_OF_WILL: /*return new List<string>{ "Drain your magic reserves to flawlessly cast a spell. (Having", "drained magic reserves still decreases your chance of success,", "but nothing else does.)", "If you have skill in Spirit, your chances are increased."};*/ return new List<string>{ "Drain your magic reserves to flawlessly cast a spell. (The", "spell's level and any penalty from your armor are ignored. Any", "drain on your magic reserves still decreases your chances.)", "If you have skill in Spirit, your chances are increased."}; case FeatType.CONVICTION: return new List<string>{ "Each turn you're engaged in combat (attacking/being attacked),", "you gain 1 bonus Spirit, and bonus Combat skill equal to half", "that."}; case FeatType.ENDURING_SOUL: return new List<string>{ "Improves the amount by which your natural recovery can heal", "you. (You can recover to a multiple of 20HP instead of 10.)"}; case FeatType.FEEL_NO_PAIN: return new List<string>{ "When your health becomes very low (less than 20%), you", "briefly enter a state of invulnerability. (For about 5 turns,", "you'll be immune to damage, but not other effects.)"}; case FeatType.BOILING_BLOOD: return new List<string>{ "Taking damage briefly increases your movement speed. (This", "effect can stack up to 5 times. At 5 stacks, your speed is", "doubled.)"}; case FeatType.DISTRACT: return new List<string>{ "Attempt to misdirect an unaware enemy, causing it to", "investigate the source of the sound."}; case FeatType.DISARM_TRAP: return new List<string>{ "Attempt to disable a trap without setting it off. If you have", "skill in Defense, you might avoid damage if you do trigger it."}; case FeatType.NECK_SNAP: return new List<string>{ "Automatically perform a stealth kill when attacking an unaware", "medium humanoid. (Living enemies of approximately human size.)"}; case FeatType.DANGER_SENSE: return new List<string>{ "You can sense where it's safe and where enemies might detect", "you. Your torch must be extinguished while you're sneaking."}; default: return null; } }
public static List<string> Description(FeatType type) { switch(type){ case FeatType.QUICK_DRAW: return new List<string>{ "Switch from a melee weapon to another weapon instantly. (You", "can fire arrows without first switching to your bow. However,", "putting your bow away still takes time.)"}; case FeatType.WHIRLWIND_STYLE: return new List<string>{ "When you take a step, you automatically attack every enemy", "still adjacent to you."}; case FeatType.LUNGE: return new List<string>{ "Leap from one space away and attack your target with perfect", "accuracy. The intervening space must be unoccupied."}; case FeatType.DRIVE_BACK: return new List<string>{ "Enemies must yield ground in order to avoid your attacks, and", "cornered enemies are more vulnerable to critical hits. (When", "your target has nowhere to run, your attacks won't miss.)"}; /*return new List<string>{ "Enemies must yield ground in order to avoid your attacks.", "(If your target has nowhere to run, your attacks will", "automatically hit.)"};*/ case FeatType.ARMOR_MASTERY: return new List<string>{ "When your armor blocks an enemy's attack, you're twice as", "likely to score a critical hit on it next turn. The exhaustion", "total at which armor becomes too heavy is increased by 25%."}; case FeatType.CUNNING_DODGE: return new List<string>{ "Relying on mobility and tricks, you can entirely avoid the", "first attack of each foe you face."}; case FeatType.DEFLECT_ATTACK: return new List<string>{ "When an enemy attacks you, you might deflect the attack to", "any other enemy next to you. (The two enemies don't need to", "be adjacent to one another.)"}; /*return new List<string>{ "When an enemy attacks you, you might deflect the attack to", "another enemy (one that is adjacent to both you and your", "attacker)."};*/ case FeatType.TUMBLE: return new List<string>{ "Move up to two spaces while avoiding arrows. Takes two turns", "to perform."}; case FeatType.MASTERS_EDGE: return new List<string>{ "The first offensive spell you've learned is empowered - it'll", "deal 1d6 extra damage. (Affects the first spell in the list", "that deals damage directly.)"}; /*return new List<string>{ "The first offensive spell you've learned will deal 1d6 extra", "damage. (Affects the first spell in the list that deals damage", "directly.)"};*/ case FeatType.ARCANE_INTERFERENCE: return new List<string>{ "When you cast a spell, nearby enemy spellcasters are stunned", "for a short time. Additionally, they permanently lose their", "ability to cast the spell you just cast."}; /*return new List<string>{ "When you cast a spell, nearby enemies lose their ability to", "cast that spell. If this happens, your spells will be", "empowered for several turns."};*/ case FeatType.CHAIN_CASTING: return new List<string>{ "The mana cost of your spells is reduced by one if you cast", "a spell last turn. (This doesn't ever reduce mana costs", "to zero.)"}; case FeatType.FORCE_OF_WILL: return new List<string>{ "Exhaustion will never make you fail an attempt at casting.", "(Casting without mana still increases your exhaustion, and", "you can't cast if your exhaustion would exceed 100%.)"}; /*return new List<string>{ "Exhaustion will never make you fail an attempt at casting.", "(Casting without mana still increases your exhaustion.)"};*/ case FeatType.CONVICTION: return new List<string>{ "Each turn you're engaged in combat (attacking or being", "attacked) you gain 1 bonus Spirit, and bonus Combat skill", "equal to half that, rounded up."}; case FeatType.ENDURING_SOUL: return new List<string>{ "Your health recovers over time. You'll regain one HP every", "five turns until your total health is a multiple of 10."}; case FeatType.FEEL_NO_PAIN: return new List<string>{ "When your health becomes very low (less than 20%), you", "briefly enter a state of invulnerability. (For about 5 turns,", "you'll be immune to damage, but not other effects.)"}; case FeatType.BOILING_BLOOD: return new List<string>{ "Taking damage briefly increases your movement speed. (This", "effect can stack up to 5 times. At 5 stacks, your speed is", "doubled and you are immune to fire damage.)"}; case FeatType.NECK_SNAP: return new List<string>{ "Automatically perform a stealth kill when attacking an unaware", "medium humanoid. (Living enemies of approximately human size.)"}; case FeatType.DISARM_TRAP: return new List<string>{ "Alter a trap so that you can walk past it safely (but enemies", "still trigger it). You can use this feat again to disable it", "entirely."}; case FeatType.CORNER_CLIMB: return new List<string>{ "If you're in a corner (and in the dark), enemies can't see you", "unless they're adjacent to you."}; case FeatType.DANGER_SENSE: return new List<string>{ "Once you've seen or detected an enemy, you can sense where", "it's safe and where that enemy might detect you. Your torch", "must be extinguished while you're sneaking."}; default: return null; } }
public bool HasFeat(FeatType feat) { return feats[feat] > 0; }
public IEnumerable<Feat> GetByType(FeatType type) { return Enumerable.Empty<Feat>(); }
/// <summary> /// Increment the remaining uses per day for this creature by one. /// Total number of feats per day can not exceed the maximum. /// - oCreature: creature to modify /// - nFeat: constant FEAT_* /// </summary> public static void IncrementRemainingFeatUses(uint oCreature, FeatType nFeat) { Internal.NativeFunctions.StackPushInteger(nFeat.InternalValue); Internal.NativeFunctions.StackPushObject(oCreature); Internal.NativeFunctions.CallBuiltIn(718); }
public bool UseFeat(FeatType feat) { switch(feat){ case FeatType.LUNGE: { List<Tile> line = GetTargetTile(2,0,false,true); Tile t = null; if(line != null && line.LastOrDefault() != tile()){ t = line.LastOrDefault(); } if(t != null && t.actor() != null){ bool moved = false; if(DistanceFrom(t) == 2 && line[1].passable && line[1].actor() == null && !MovementPrevented(line[1])){ moved = true; B.Add("You lunge! "); Move(line[1].row,line[1].col); attrs[AttrType.LUNGING_AUTO_HIT] = 1; Attack(0,t.actor()); attrs[AttrType.LUNGING_AUTO_HIT] = 0; } if(!moved){ if(MovementPrevented(line[1])){ B.Add("You can't currently reach that spot. "); return false; } else{ B.Add("The way is blocked! "); return false; } } else{ return true; } } else{ return false; } //break; } case FeatType.TUMBLE: { target = null; //don't try to automatically pick previous targets while tumbling. this solution isn't ideal. List<Tile> line = GetTargetTile(2,0,false,false); target = null; //then, don't remember an actor picked as the target of tumble Tile t = null; if(line != null && line.LastOrDefault() != tile()){ t = line.LastOrDefault(); } if(t != null && t.passable && t.actor() == null && !MovementPrevented(t)){ if(!t.seen){ B.Add("You don't know what's over there! "); return false; } bool moved = false; foreach(Tile neighbor in t.PassableNeighborsBetween(row,col)){ if(neighbor.passable && !moved){ B.Add("You tumble. "); Move(t.row,t.col); moved = true; attrs[AttrType.TUMBLING]++; } } if(moved){ Q.Add(new Event(this,Speed() + 100,EventType.MOVE)); return true; } else{ B.Add("The way is blocked! "); return false; } } else{ if(MovementPrevented(t)){ B.Add("You can't currently reach that spot. "); } return false; } } case FeatType.DISARM_TRAP: { int dir = GetDirection("Disarm which trap? "); Tile t = TileInDirection(dir); if(dir != -1 && t.IsKnownTrap()){ if(ActorInDirection(dir) != null){ B.Add("There is " + ActorInDirection(dir).AName(true) + " in the way. "); Q0(); return true; } 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{ Q0(); } return true; } default: return false; } }