/*/// <summary> * /// was missilefirecontrol in battlespace. * /// </summary> * /// <param name="battletick"></param> * /// <param name="comSek"></param> * * public override void firecontrol(int battletick) * { * Fix16 locdistance = Trig.distance(comSek.cmbt_loc, comSek.weaponTarget[0].cmbt_loc); * if (locdistance <= comSek.cmbt_vel.Length)//erm, I think? (if we're as close as we're going to get in one tick) could screw up at high velocities. * { * if (!IsReplay) * { * CombatTakeFireEvent evnt = comSek.seekertargethit; * evnt.IsHit = true; * evnt.Tick = battletick; * } * Component launcher = comSek.launcher.weapon; * CombatObject target = comSek.weaponTarget[0]; * if (target is ControlledCombatObject) * { * ControlledCombatObject ccTarget = (ControlledCombatObject)target; * var target_icomobj = ccTarget.WorkingObject; * var shot = new Combat.Shot(launcher, target_icomobj, 0); * //defender.TakeDamage(weapon.Template.ComponentTemplate.WeaponInfo.DamageType, shot.Damage, battle); * int damage = shot.Damage; * combatDamage(battletick, target, comSek.launcher, damage, comSek.getDice()); * if (target_icomobj.MaxNormalShields < target_icomobj.NormalShields) * target_icomobj.NormalShields = target_icomobj.MaxNormalShields; * if (target_icomobj.MaxPhasedShields < target_icomobj.PhasedShields) * target_icomobj.PhasedShields = target_icomobj.MaxPhasedShields; * } * * DeadNodes.Add(comSek); * CombatNodes.Remove(comSek); * } * else if (battletick > comSek.deathTick) * { * DeadNodes.Add(comSek); * CombatNodes.Remove(comSek); * } * } */ public override void TakeSpecialDamage(Battle_Space battle, Hit hit, PRNG dice) { // find out who hit us var atkr = battle.FindCombatObject(hit.Shot.Attacker); // find out how too var dmgType = hit.Shot.DamageType; // push/pull effects if (atkr.CanPushOrPull(this)) { var deltaV = dmgType.TargetPush.Value * hit.Shot.DamageLeft / 100; var vector = atkr.cmbt_loc - this.cmbt_loc; if (vector.Length == 0) { // pick a random direction to push/pull vector = new Compass(dice.Next(360), false).Point(1); } vector /= vector.Length; // normalize to unit vector vector *= Battle_Space.KilometersPerSquare / Battle_Space.TicksPerSecond; // scale to combat map vector *= deltaV; // scale to push/pull acceleration factor this.cmbt_vel += deltaV; // apply force } // teleport effects { var deltaPos = dmgType.TargetTeleport.Value * hit.Shot.DamageLeft / 100; var vector = new Compass(dice.Next(360), false).Point(deltaPos); this.cmbt_loc += deltaPos; // apply teleport } }
public void Combat_CheckCopies() { Galaxy gal = new Galaxy(); testships testships = new testships(); StarSystem sys = new StarSystem(1); Sector location = new Sector(sys, new System.Drawing.Point()); List <SpaceVehicle> ships = testships.ships; foreach (SpaceVehicle ship in ships) { location.Place(ship); } Battle_Space battle = new Battle_Space(location); var id0 = testships.ships[0].ID; var id1 = testships.ships[1].ID; battle.Resolve(); Assert.AreNotEqual(battle.StartCombatants[id0], battle.ActualCombatants[id0]); Assert.AreNotEqual(battle.StartCombatants[id1], battle.ActualCombatants[id1]); //MogreFreeMain replay = new MogreFreeMain(battle); doing this crashes VS on compile. }
public void Combat_setupbattle() { Sector location = new Sector(sys, new System.Drawing.Point()); Empire emp = new Empire(); MockCombatant combatant = new MockCombatant(emp); testComObj = new MockCombatObject(combatant, new PointXd(), new PointXd(), 42, "SHP"); spinrate = new Compass(5, false); testComObj.maxRotate = spinrate; testComObj.cmbt_accel = new PointXd(0, 0, 0); testComObj.maxfowardThrust = 100; testComObj.maxStrafeThrust = (Fix16)0; testComObj.cmbt_mass = 100; ICombatant[] combatants = new ICombatant[] { combatant }; foreach (ISpaceObject ispobj in (combatants)) { location.Place(ispobj); } battle = new Battle_Space(location); battle.StartNodes.Add(testComObj); }
/*/// <summary> * /// attempt at adding this to the combatObject. it's not working too well though. * /// </summary> * /// <param name="battletick"></param> * /// <param name="attacker"></param> * /// <param name="weapon"></param> * /// <param name="Sector"></param> * /// <param name="IsReplay"></param> * /// <returns></returns> * * public CombatTakeFireEvent FireWeapon(int battletick, CombatObject attacker, CombatWeapon weapon, Space.Sector Sector, bool IsReplay) * { * var wpninfo = weapon.weapon.Template.ComponentTemplate.WeaponInfo; * Fix16 rangeForDamageCalcs = (Fix16)0; * Fix16 rangetotarget = Trig.distance(attacker.cmbt_loc, this.cmbt_loc); * int targettic = battletick; * * //reset the weapon nextReload. * weapon.nextReload = battletick + (int)(weapon.reloadRate * Battle_Space.TicksPerSecond); // TODO - round up, so weapons that fire more than 10 times per second don't fire at infinite rate * * var target_icomobj = this.WorkingObject; * //Vehicle defenderV = (Vehicle)target_icomobj; * * if (!weapon.CanTarget(target_icomobj)) * return null; * * // TODO - check range too * var tohit = * Mod.Current.Settings.WeaponAccuracyPointBlank // default weapon accuracy at point blank range + weapon.weapon.Template.WeaponAccuracy // weapon's intrinsic accuracy modifier + weapon.weapon.Container.Accuracy // firing ship's accuracy modifier + - target_icomobj.Evasion // target's evasion modifier + - Sector.GetAbilityValue(this.WorkingObject.Owner, "Sector - Sensor Interference").ToInt() // sector evasion modifier + Sector.GetAbilityValue(attacker.WorkingObject.Owner, "Combat Modifier - Sector").ToInt() // generic combat bonuses + - Sector.GetAbilityValue(this.WorkingObject.Owner, "Combat Modifier - Sector").ToInt() + Sector.StarSystem.GetAbilityValue(attacker.WorkingObject.Owner, "Combat Modifier - System").ToInt() + - Sector.StarSystem.GetAbilityValue(this.WorkingObject.Owner, "Combat Modifier - System").ToInt() + attacker.WorkingObject.Owner.GetAbilityValue("Combat Modifier - Empire").ToInt() + - this.WorkingObject.Owner.GetAbilityValue("Combat Modifier - Empire").ToInt(); + // TODO - moddable min/max hit chances with per-weapon overrides + if (tohit > 99) + tohit = 99; + if (tohit < 1) + tohit = 1; + if (weapon.weapon.Container.HasAbility("Weapons Always Hit")) + tohit = 100; + + //bool hit = RandomHelper.Range(0, 99) < tohit; + PRNG dice = attacker.getDice(); + bool hit = dice.Range(0, 99) < tohit; + + CombatTakeFireEvent target_event = null; + + if (weapon.weaponType == "Seeker") + { + + //create seeker and node. + CombatSeeker seeker = new CombatSeeker(attacker, weapon, -tempObjCounter); + seeker.waypointTarget = new combatWaypoint(this); + seeker.weaponTarget = new List<CombatObject>() { this }; + seeker.deathTick = battletick + weapon.maxRange_time; + seeker.cmbt_head = attacker.cmbt_head; + seeker.cmbt_att = attacker.cmbt_att; + FreshNodes.Add(seeker); + + foreach (var emp in Empires.Values) + { + if (emp.ownships.Contains(attacker)) + emp.ownships.Add(seeker); + if (emp.friendly.Contains(attacker)) + emp.friendly.Add(seeker); + if (emp.neutral.Contains(attacker)) + emp.neutral.Add(seeker); + if (emp.hostile.Contains(attacker)) + emp.hostile.Add(seeker); + } + + if (IsReplay) + { + //read the event + target_event = ReplayLog.EventsForObjectAtTick(this, targettic).OfType<CombatTakeFireEvent>().ToList<CombatTakeFireEvent>()[0]; + target_event.BulletNode = seeker; + } + else + { + //*write* the event + target_event = new CombatTakeFireEvent(battletick, this, this.cmbt_loc, false); + target_event.BulletNode = seeker; + seeker.seekertargethit = target_event; + } + } + //for bolt calc, need again for adding to list. + else if (weapon.weaponType == "Bolt") + { + + rangeForDamageCalcs = rangeForDamageCalcs_bolt(attacker, weapon, this); + Fix16 boltTTT = weapon.boltTimeToTarget(attacker, target); + //set target tick for the future. + targettic += (int)boltTTT; + + + + if (IsReplay) + { + //read the event + target_event = ReplayLog.EventsForObjectAtTick(this, targettic).OfType<CombatTakeFireEvent>().ToList<CombatTakeFireEvent>()[0]; + + //because bullets don't need to be created during processing + Fix16 rThis_distance = (target_event.Location - target_event.fireOnEvent.Location).Length; + PointXd bulletVector = Trig.intermediatePoint(attacker.cmbt_loc, target_event.Location, rThis_distance); + if (!target_event.IsHit) //jitter it! + { + // TODO - take into account firing ship's accuracy and target's evasion + int accuracy = target_event.fireOnEvent.Weapon.weapon.Template.WeaponAccuracy; + int jitterAmount = 0; + if (accuracy < 50) + jitterAmount = (int)System.Math.Pow(50 - accuracy, 2) / 50; + if (jitterAmount < 5) + jitterAmount = 5; + if (jitterAmount > 30) + jitterAmount = 30; + //do *NOT* use ship prng here!!!! (since this is not done during normal processing, it'll cause differences, use any rand) + Compass jitter = new Compass(RandomHelper.Range(-jitterAmount, jitterAmount), false); + Compass bulletCompass = bulletVector.Compass; + Compass offsetCompass = bulletCompass + jitter; + bulletVector = offsetCompass.Point(bulletVector.Length); + } + CombatNode bullet = new CombatNode(attacker.cmbt_loc, bulletVector, -tempObjCounter, "BLT"); + target_event.BulletNode = bullet; + FreshNodes.Add(bullet); + if (target_event.IsHit) + { + bullet.deathTick = target_event.Tick; + } + else + { + bullet.deathTick = battletick + target_event.fireOnEvent.Weapon.maxRange; + } + } + else + { + //*write* the event + target_event = new CombatTakeFireEvent(targettic, this, this.cmbt_loc, hit); + int nothing = tempObjCounter; //increase it just so processing has the same number of tempObjects created as replay will. + } + + } + else //not bolt + { + if (IsReplay) + { //read the replay... nothing to do if a beam. + } + else + { //write the event. + rangeForDamageCalcs = rangetotarget / (Fix16)1000; + target_event = new CombatTakeFireEvent(targettic, this, this.cmbt_loc, hit); + } + } + + rangeForDamageCalcs = Fix16.Max((Fix16)1, rangeForDamageCalcs); //don't be less than 1. + + if (hit && !target_icomobj.IsDestroyed) + { + var shot = new Combat.Shot(weapon.weapon, target_icomobj, (int)rangeForDamageCalcs); + //defender.TakeDamage(weapon.Template.ComponentTemplate.WeaponInfo.DamageType, shot.Damage, battle); + int damage = shot.Damage; + combatDamage(battletick, this, weapon, damage, attacker.getDice()); + if (target_icomobj.MaxNormalShields < target_icomobj.NormalShields) + target_icomobj.NormalShields = target_icomobj.MaxNormalShields; + if (target_icomobj.MaxPhasedShields < target_icomobj.PhasedShields) + target_icomobj.PhasedShields = target_icomobj.MaxPhasedShields; + //if (defender.IsDestroyed) + //battle.LogTargetDeath(defender); + } + return target_event; + } */ public void TakeDamage(Battle_Space battle, Hit hit, PRNG dice) { // special combat damage effects TakeSpecialDamage(battle, hit, dice); // basic damage effects WorkingObject.TakeDamage(hit, dice); }
public void setupEnvironment0() { location = new Sector(sys, new System.Drawing.Point()); SimulatedEmpire simemp = new SimulatedEmpire(testships2.empire("TestEmpOne", new Culture(), new Race())); Design <Ship> design = testships2.EscortDUC(gal, simemp.Empire, testships2.Components(gal)); SpaceVehicle sv = testships2.testShip(simemp, design, 100); location.Place(sv); battle = new Battle_Space(location); }
public override void TakeSpecialDamage(Battle_Space battle, Hit hit, PRNG dice) { // find out who hit us var atkr = battle.FindCombatObject(hit.Shot.Attacker); // find out how too var dmgType = hit.Shot.DamageType; // conditions damage { var cdmg = dmgType.ConditionsDamage.Value * hit.Shot.DamageLeft / 100; // TODO - conditions damage, once we have conditions } // plagues { var plague = dmgType.PlagueLevel; // TODO - plaguing planets, once we have plagues } // population damage { var popdmg = dmgType.PopulationDamage.Value * hit.Shot.DamageLeft / 100; WorkingPlanet.TakePopulationDamage(popdmg, dice); } // disrupt reload { var disrupt = dmgType.DisruptReload.Value * hit.Shot.DamageLeft / 100; foreach (var w in Weapons) { w.nextReload += disrupt; if (w.nextReload - battle.CurrentTick > w.reloadRate) { w.nextReload = battle.CurrentTick + w.reloadRate; // this damage type can't increase past normal reload time } } } // increase reload (doesn't work againts master computers, even disabled ones) if (WorkingPlanet.Colony != null) { if (!WorkingPlanet.Colony.Facilities.Cast <IAbilityObject>().Union(WorkingPlanet.Cargo.Units.SelectMany(u => u.Components).Cast <IAbilityObject>()).Any(c => c.HasAbility("Master Computer"))) { var inc = dmgType.IncreaseReload.Value * hit.Shot.DamageLeft / 100; foreach (var w in Weapons) { w.nextReload += inc; // this damage type can increase past normal reload time } } } }
public void setupEnvironment1() { location = new Sector(sys, new System.Drawing.Point()); SimulatedEmpire simemp0 = new SimulatedEmpire(testships2.empire("TestEmpOne", new Culture(), new Race())); SimulatedEmpire simemp1 = new SimulatedEmpire(testships2.empire("TestEmpTwo", new Culture(), new Race())); Design <Ship> design0 = testships2.EscortCSM(gal, simemp0.Empire, testships2.Components(gal)); Design <Ship> design1 = testships2.EscortDUC(gal, simemp1.Empire, testships2.Components(gal)); SpaceVehicle sv0 = testships2.testShip(simemp0, design0, 100); SpaceVehicle sv1 = testships2.testShip(simemp1, design1, 200); location.Place(sv0); location.Place(sv1); battle = new Battle_Space(location); }
public MogreCombatForm(Battle_Space battle) { InitializeComponent(); Battle = battle; Text = battle.Name; }
public virtual void TakeSpecialDamage(Battle_Space battle, Hit hit, PRNG dice) { }
public override void TakeSpecialDamage(Battle_Space battle, Hit hit, PRNG dice) { // find out who hit us var atkr = battle.FindCombatObject(hit.Shot.Attacker); // find out how too var dmgType = hit.Shot.DamageType; // disrupt reload { var disrupt = dmgType.DisruptReload.Value * hit.Shot.DamageLeft / 100; foreach (var w in Weapons) { w.nextReload += disrupt; if (w.nextReload - battle.CurrentTick > w.reloadRate) { w.nextReload = battle.CurrentTick + w.reloadRate; // this damage type can't increase past normal reload time } } } // increase reload (doesn't work againts master computers, even disabled ones) if (!WorkingVehicle.Components.Any(c => c.HasAbility("Master Computer"))) { var inc = dmgType.IncreaseReload.Value * hit.Shot.DamageLeft / 100; foreach (var w in Weapons) { w.nextReload += inc; // this damage type can increase past normal reload time } } // ship capture { var cap = dmgType.ShipCapture.Value * hit.Shot.DamageLeft; if (cap > WorkingVehicle.GetAbilityValue("Boarding Attack").ToInt() + WorkingVehicle.GetAbilityValue("Boarding Defense").ToInt()) { // destroy all boarding parties and security stations on the target foreach (var c in WorkingVehicle.Components.Where(c => c.HasAbility("Boarding Attack") || c.HasAbility("Boarding Defense"))) { c.Hitpoints = 0; } // see if that killed the target if (battle.CheckForDeath(battle.CurrentTick, this)) { return; } // transfer ownership this.WorkingCombatant.Owner = atkr.WorkingObject.Owner; } } // push/pull effects if (atkr.CanPushOrPull(this)) { var deltaV = dmgType.TargetPush.Value * hit.Shot.DamageLeft / 100; var vector = atkr.cmbt_loc - this.cmbt_loc; if (vector.Length == 0) { // pick a random direction to push/pull vector = new Compass(dice.Next(360), false).Point(1); } vector /= vector.Length; // normalize to unit vector vector *= Battle_Space.KilometersPerSquare / Battle_Space.TicksPerSecond; // scale to combat map vector *= deltaV; // scale to push/pull acceleration factor this.cmbt_vel += deltaV; // apply force } // teleport effects { var deltaPos = dmgType.TargetTeleport.Value * hit.Shot.DamageLeft / 100; var vector = new Compass(dice.Next(360), false).Point(deltaPos); this.cmbt_loc += deltaPos; // apply teleport } }
public override void TakeSpecialDamage(Battle_Space battle, FrEee.Game.Objects.Combat.Hit hit, PRNG dice) { }