public static GameEntity CreateEnemy(Contexts contexts, Vector2 pos) { var enemy = contexts.game.CreateEntity(); enemy.AddPrefab("Prefabs/Enemies/spider"); enemy.AddPosition(pos); enemy.isEnemy = true; enemy.isRemovedWhenDead = true; MovementHelpers.AddMovementComponents(enemy, 2f, .25f, .5f, .8f, 1f); SightHelpers.AddSightComponents(enemy, 50); CombatHelpers.AddCombatComponents(enemy, 5f, 3f, .5f); var agent = new EntityGoapAgent(contexts, enemy); agent.AddAction(new CloseRangeAttackAction()); agent.AddAction(new GetCloseToTargetAction()); agent.AddAction(new TargetMinersAction()); agent.AddGoal(new DestroyMineGoal()); enemy.AddGoapAgent(agent); var animDirector = new AnimationDirector(enemy); enemy.AddAnimationDirector(animDirector); var combatDirector = new CombatDirector(enemy); combatDirector.AddAttack(new MeleeAttack(enemy, "spider_walk", new [] { 24 })); enemy.AddCombatDirector(combatDirector); return(enemy); }
public static void GetDodgeChance_Postfix( ref float __result ) { if (__result.IsTrivial() || CurrentStrike.GlowDiff.IsTrivial()) { return; } __result = CombatHelpers.DodgeChanceFunction(__result, CurrentStrike.GlowDiff); }
public static void Postfix( //ref ShotReport __instance, ref float __result ) { if (!CurrentShot.NoShot && CurrentShot.GlowFactor.FactorIsNonTrivial()) { CurrentShot.OriginalHitOnStandardTarget = __result; CurrentShot.ModifiedHitOnStandardTarget = CombatHelpers.HitChanceGlowTransform(__result, CurrentShot.GlowFactor); __result = CurrentShot.ModifiedHitOnStandardTarget; } }
protected virtual bool DoConsider(string rawParameters, params CommandParameter[] parameters) { if (parameters.Length == 0) { Send("Consider killing whom?"); return(true); } ICharacter whom = FindHelpers.FindByName(Room.People, parameters[0]); if (whom == null) { Send(StringHelpers.CharacterNotFound); return(true); } CombatHelpers.CombatDifficulties difficulty = CombatHelpers.GetConColor(Level, whom.Level); switch (difficulty) { case CombatHelpers.CombatDifficulties.Grey: Act(ActOptions.ToCharacter, "You can kill {0} naked and weaponless.", whom); break; case CombatHelpers.CombatDifficulties.Green: Act(ActOptions.ToCharacter, "{0:N} looks like an easy kill.", whom); break; case CombatHelpers.CombatDifficulties.Yellow: Send("The perfect match!"); break; case CombatHelpers.CombatDifficulties.Orange: Act(ActOptions.ToCharacter, "{0:N} says 'Do you fell lucky punk?'.", whom); break; case CombatHelpers.CombatDifficulties.Red: Act(ActOptions.ToCharacter, "{0:N} laughs at you mercilessly.", whom); break; case CombatHelpers.CombatDifficulties.Skull: Send("Death will thank you for your gift."); break; default: Act(ActOptions.ToCharacter, "You failed to consider killing {0}.", whom); Log.Default.WriteLine(LogLevels.Error, "DoConsider: unhandled CombatDifficulties: {0}", difficulty); break; } return(true); }
public static void HitReportFor_Postfix( ref ShotReport __result, Thing caster, Verb verb, LocalTargetInfo target ) { if (caster is Pawn pawn && pawn.TryGetComp <Comp_NightVision>() is Comp_NightVision comp) { CurrentShot.Caster = caster; CurrentShot.Verb = verb; CurrentShot.GlowFactor = CombatHelpers.GlowFactorForPawnAtTarget(pawn, target, comp); }
// TODO: Some way to get all actors around... // Add actor to list // remove actor from list // ================================================================================================= // // COMBAT // // ================================================================================================= #region HANDLING COMBAT public void HandleCombat(DynamicActor _AttackingActor, DynamicActor _BeingAttackedActor, Weapon.EWeaponRoll AttackerRoll) { _AttackingActor.DealtDamage(); int ExtraStr = 0; if (_AttackingActor.ActorType == EActorType.EAT_Player) { ExtraStr = ResourceLocator.instance.PlayerExtraStr; } int AttackerModifier = CombatHelpers.CalculateModifier(_AttackingActor.ActorStats.Strength + ExtraStr); int Damage = CombatHelpers.CalculateDamage(AttackerModifier, AttackerRoll); Damage = Mathf.Max(Damage, 0); _BeingAttackedActor.SufferedDamage(Damage); Debug.Log($"{_AttackingActor.ActorName} dealt {Damage} damage to {_BeingAttackedActor.ActorName}"); }
public static void GetNonMissChance_Postfix(ref Verb __instance, ref float __result, LocalTargetInfo target) { if (__result > 0.999f || !(__instance.CasterPawn is Pawn pawn) || !(pawn.TryGetComp <Comp_NightVision>() is Comp_NightVision comp)) { CurrentStrike.GlowFactor = Constants.TRIVIAL_FACTOR; CurrentStrike.GlowDiff = 0f; return; } float glow = pawn.Map != null?GlowFor.GlowAt(pawn.Map, target.Cell) : Constants.TRIVIAL_GLOW; if (!glow.GlowIsDarkOrBright()) { CurrentStrike.GlowFactor = Constants.TRIVIAL_FACTOR; CurrentStrike.GlowDiff = 0f; return; } CurrentStrike.GlowFactor = comp.FactorFromGlow(glow); if (target.Thing is Pawn t_pawn) { CurrentStrike.GlowDiff = CurrentStrike.GlowFactor - GlowFor.FactorOrFallBack(t_pawn, glow); if (CurrentStrike.GlowDiff.IsNonTrivial() && CurrentStrike.SurpAtkSuccess) { AccessTools.FieldRefAccess <Verb, bool>(__instance, "surpriseAttack") = true; __result = 1f; MoteMaker.ThrowText(pawn.Position.ToVector3Shifted(), pawn.Map, "NightVisionSneakAtkMote".Translate(), 5f); return; } } else { CurrentStrike.GlowDiff = 0; } __result = CombatHelpers.HitChanceGlowTransform(__result, CurrentStrike.GlowFactor); }
public static GameEntity CreateMiner(Contexts contexts, Vector2 pos) { var e = contexts.game.CreateEntity(); e.AddPrefab("Prefabs/Miners/miner_grunt"); e.AddPosition(pos); MovementHelpers.AddMovementComponents(e, 3f, .25f, .5f, .5f, .8f); SightHelpers.AddSightComponents(e, 10f); e.isMiner = true; var health = StatCalculator.Calculate(BaseHealth, 1); var damage = StatCalculator.Calculate(BaseMiningDamage, 1); var cooldown = StatCalculator.Calculate(BaseMiningSpeed, 1); CombatHelpers.AddCombatComponents(e, health, damage, cooldown); var animDirector = new AnimationDirector(e); e.AddAnimationDirector(animDirector); e.isKillable = true; var agent = new EntityGoapAgent(contexts, e); agent.AddAction(new CloseRangeAttackAction()); agent.AddAction(new GetCloseToTargetAction()); agent.AddAction(new TargetOreBranchAction()); agent.AddAction(new MineAction()); agent.AddGoal(new AcquireOreGoal()); e.AddGoapAgent(agent); var combatDirector = new CombatDirector(e); combatDirector.AddAttack(new MeleeAttack(e, "miner_grunt_mine_regular", new[] { 24 })); e.AddCombatDirector(combatDirector); e.AddBag(new List <int>()); return(e); }
public virtual int Resolve(string ThisFighterId) { int ret = 0; //string opponentFighterId = otherFighterId(ThisFighterId); string opponentFighterId = CombatHelpers.otherFighterId(ThisFighterId, _combatSession); if (_combatSession.CombatRounds.Where(x => x.Result != null).Count() == 0) { return(0); } for (int i = _combatSession.CombatRounds.Count - 1; i > -1; i--) { CombatRound combatRound = _combatSession.CombatRounds[i]; if (combatRound.Result != null) { //if (combatRound.Moves.Where(x => x.FighterId == ThisFighterId).FirstOrDefault().Action == CombatEnums.SWING && // combatRound.Moves.Where(x => x.FighterId == opponentFighterId).FirstOrDefault().Action == CombatEnums.REST //) if (truthCondition ( combatRound.Moves.Where(x => x.FighterId == ThisFighterId).FirstOrDefault().Action, combatRound.Moves.Where(x => x.FighterId == opponentFighterId).FirstOrDefault().Action ) ) { ret++; } else { return(ret); } } } return(ret); }
public static GameEntity CreateTurret(Contexts contexts, Vector2 pos) { var turret = contexts.game.CreateEntity(); turret.AddPosition(pos); turret.AddPrefab("Prefabs/Towers/tower_rifle"); var muzzle = contexts.game.CreateEntity(); muzzle.AddPrefab("Prefabs/Towers/tower_rifle_gun"); muzzle.isLookingAtTarget = true; muzzle.AddParent(turret.id.value); muzzle.AddPositionOffset(new Vector2(-0.056f, -0.118f)); CombatHelpers.AddCombatComponents(muzzle, 5f, .5f, .1f); SightHelpers.AddSightComponents(muzzle, 10f); var turretAgent = new EntityGoapAgent(contexts, muzzle); turretAgent.AddGoal(new DefendMineGoal()); turretAgent.AddAction(new TargetMineIntruderAction()); turretAgent.AddAction(new RangeAttackAction()); muzzle.AddGoapAgent(turretAgent); var turretAnim = new AnimationDirector(muzzle); muzzle.AddAnimationDirector(turretAnim); var turretCombat = new CombatDirector(muzzle); turretCombat.AddAttack(new MeleeAttack(muzzle, "tower_rifle_gun_fire", new[] { 3 })); muzzle.AddCombatDirector(turretCombat); return(turret); }
private static void ProcessOnOneTarget(ICharacter source, ICharacter victim, IAbility ability, bool cannotMiss, bool cannotBeDodgedParriedBlocked) { if (ability?.Effects == null || ability.Effects.Count == 0 || !source.IsValid || !victim.IsValid) { return; } // Miss/Dodge/Parray/Block check (only for harmful ability) CombatHelpers.AttackResults attackResult = CombatHelpers.AttackResults.Hit; if (ability.Behavior == AbilityBehaviors.Harmful) { // Starts fight if needed (if A attacks B, A fights B and B fights A) if (source != victim) { if (source.Fighting == null) { source.StartFighting(victim); } if (victim.Fighting == null) { victim.StartFighting(source); } // TODO: Cannot attack slave without breaking slavery } if (ability.Kind == AbilityKinds.Skill) { // TODO: refactor same code in Character.OneHit // Miss, dodge, parry, ... attackResult = CombatHelpers.YellowMeleeAttack(source, victim, cannotMiss, cannotBeDodgedParriedBlocked); Log.Default.WriteLine(LogLevels.Debug, $"{source.DebugName} -> {victim.DebugName} : attack result = {attackResult}"); switch (attackResult) { case CombatHelpers.AttackResults.Miss: victim.Act(ActOptions.ToCharacter, "{0} misses you.", source); source.Act(ActOptions.ToCharacter, "You miss {0}.", victim); return; // no effect applied case CombatHelpers.AttackResults.Dodge: victim.Act(ActOptions.ToCharacter, "You dodge {0}'s {1}.", source, ability.Name); source.Act(ActOptions.ToCharacter, "{0} dodges your {1}.", victim, ability.Name); return; // no effect applied case CombatHelpers.AttackResults.Parry: victim.Act(ActOptions.ToCharacter, "You parry {0}'s {1}.", source, ability.Name); source.Act(ActOptions.ToCharacter, "{0} parries your {1}.", victim, ability.Name); return; // no effect applied case CombatHelpers.AttackResults.Block: EquipedItem victimShield = victim.Equipments.FirstOrDefault(x => x.Item != null && x.Slot == EquipmentSlots.Shield); if (victimShield != null) // will never be null because MeleeAttack will not return Block if no shield { victim.Act(ActOptions.ToCharacter, "You block {0}'s {1} with {2}.", source, ability.Name, victimShield.Item); source.Act(ActOptions.ToCharacter, "{0} blocks your {1} with {2}.", victim, ability.Name, victimShield.Item); } // effect applied break; case CombatHelpers.AttackResults.Critical: case CombatHelpers.AttackResults.CrushingBlow: case CombatHelpers.AttackResults.Hit: // effect applied break; default: Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name}[{ability.Kind}] returned an invalid attack result: {attackResult}"); break; } } else if (ability.Kind == AbilityKinds.Spell && ability.Behavior == AbilityBehaviors.Harmful) { // Miss/Hit/Critical attackResult = CombatHelpers.SpellAttack(source, victim, cannotMiss); switch (attackResult) { case CombatHelpers.AttackResults.Miss: victim.Act(ActOptions.ToCharacter, "{0} misses you.", source); source.Act(ActOptions.ToCharacter, "You miss {0}.", victim); return; // no effect applied case CombatHelpers.AttackResults.Hit: case CombatHelpers.AttackResults.Critical: // effect applied break; default: Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name}[{ability.Kind}] returned an invalid attack result: {attackResult}"); break; } } else { Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name} has an invalid kind: {ability.Kind}"); } } // Apply effects foreach (AbilityEffect effect in ability.Effects) { effect.Process(source, victim, ability, attackResult); } }