void Update() { if (!gameObject.activeInHierarchy || !HighLogic.LoadedSceneIsFlight || BDArmorySetup.GameIsPaused) { return; } transform.rotation = Quaternion.FromToRotation(Vector3.up, -FlightGlobals.getGeeForceAtPosition(transform.position)); PartResource fuel = parentPart.Resources.Where(pr => pr.resourceName == "LiquidFuel").FirstOrDefault(); var engine = parentPart.FindModuleImplementing <ModuleEngines>(); if (engine != null) { if (engine.enabled) { if (parentPart.RequestResource("LiquidFuel", (double)(burnRate * TimeWarp.deltaTime)) <= 0) { hasFuel = false; } } } else { if (fuel != null) { if (fuel.amount > (fuel.maxAmount * 0.15f) || (fuel.amount > 0 && fuel.amount < (fuel.maxAmount * 0.10f))) { fuel.amount -= (burnRate * TimeWarp.deltaTime); } else if (fuel.amount < (fuel.maxAmount * 0.15f) && fuel.amount > (fuel.maxAmount * 0.10f)) { Detonate(); } else { hasFuel = false; } } PartResource ox = parentPart.Resources.Where(pr => pr.resourceName == "Oxidizer").FirstOrDefault(); if (ox != null) { if (ox.amount > 0) { ox.amount -= (burnRate * TimeWarp.deltaTime); } else { hasFuel = false; } } PartResource mp = parentPart.Resources.Where(pr => pr.resourceName == "MonoPropellant").FirstOrDefault(); if (mp != null) { if (mp.amount > (mp.maxAmount * 0.15f) || (mp.amount > 0 && mp.amount < (mp.maxAmount * 0.10f))) { mp.amount -= (burnRate * TimeWarp.deltaTime); } else if (mp.amount < (mp.maxAmount * 0.15f) && mp.amount > (mp.maxAmount * 0.10f)) { Detonate(); } else { hasFuel = false; } } PartResource ec = parentPart.Resources.Where(pr => pr.resourceName == "ElectricCharge").FirstOrDefault(); if (ec != null) { if (ec.amount > 0) { ec.amount -= (burnRate * TimeWarp.deltaTime); Mathf.Clamp((float)ec.amount, 0, Mathf.Infinity); } if ((Time.time - startTime > 30) && engine == null) { Detonate(); } } } if ((!hasFuel && disableTime < 0 && burnTime < 0) || (burnTime > 0 && disableTime < 0 && Time.time - startTime > burnTime)) { disableTime = Time.time; //grab time when emission stops foreach (var pe in pEmitters) { if (pe != null) { pe.emit = false; } } } if (disableTime > 0 && Time.time - disableTime > _highestEnergy) //wait until last emitted particle has finished { gameObject.SetActive(false); } if (BDArmorySettings.BATTLEDAMAGE && BDArmorySettings.BD_FIRE_DOT) { parentPart.AddDamage(BDArmorySettings.BD_FIRE_DAMAGE * Time.deltaTime); //////////////////////////////////////////////// if (ScoreAccumulator >= 1) { ScoreAccumulator = 0; var aName = SourceVessel; var tName = parentPart.vessel.GetName(); if (aName != null && tName != null && aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(aName) && BDACompetitionMode.Instance.Scores.ContainsKey(tName)) { if (BDArmorySettings.REMOTE_LOGGING_ENABLED) { BDAScoreService.Instance.TrackDamage(aName, tName, BDArmorySettings.BD_FIRE_DAMAGE); } var aData = BDACompetitionMode.Instance.Scores[aName]; aData.Score += 1; if (parentPart.vessel.GetName() == "Pinata") { aData.PinataHits++; } var tData = BDACompetitionMode.Instance.Scores[tName]; tData.lastPersonWhoHitMe = aName; tData.lastHitTime = Planetarium.GetUniversalTime(); tData.everyoneWhoHitMe.Add(aName); // Track hits if (tData.hitCounts.ContainsKey(aName)) { ++tData.hitCounts[aName]; } else { tData.hitCounts.Add(aName, 1); } // Track damage if (tData.damageFromBullets.ContainsKey(aName)) { tData.damageFromBullets[aName] += BDArmorySettings.BD_FIRE_DAMAGE; } else { tData.damageFromBullets.Add(aName, BDArmorySettings.BD_FIRE_DAMAGE); } } } else { ScoreAccumulator += 1 * Time.deltaTime; } } //////////////////////////////////////////// }
private void ApplyDamage(Part hitPart, RaycastHit hit) { //hitting a vessel Part //No struts, they cause weird bugs :) -BahamutoD if (hitPart == null) { return; } if (hitPart.partInfo.name.Contains("Strut")) { return; } float explDamage = 0; if (BDArmorySettings.BULLET_HITS) { BulletHitFX.CreateBulletHit(hitPart, hit.point, hit, hit.normal, false, 200, 3); } if (CASELevel == 2) { explDamage = 100; hitPart.AddDamage(explDamage); float armorToReduce = hitPart.GetArmorThickness() * 0.25f; hitPart.ReduceArmor(armorToReduce); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BD DEBUG]" + hitPart.name + "damaged, armor reduced by " + armorToReduce); } } else //CASE I { explDamage = (hitPart.Modules.GetModule <HitpointTracker>().GetMaxHitpoints() * 0.9f); explDamage = Mathf.Clamp(explDamage, 0, 600); hitPart.AddDamage(explDamage); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BD DEBUG]" + hitPart.name + "damaged for " + (hitPart.MaxDamage() * 0.9f)); } if (BDArmorySettings.BATTLEDAMAGE) { Misc.BattleDamageHandler.CheckDamageFX(hitPart, 200, 3, true, SourceVessel, hit); } } { var aName = SourceVessel; var tName = part.vessel.GetName(); if (aName != null && tName != null && aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(aName) && BDACompetitionMode.Instance.Scores.ContainsKey(tName)) { if (BDArmorySettings.REMOTE_LOGGING_ENABLED) { BDAScoreService.Instance.TrackDamage(aName, tName, explDamage); } var aData = BDACompetitionMode.Instance.Scores[aName]; aData.Score += 1; if (part.vessel.GetName() == "Pinata") { aData.PinataHits++; } var tData = BDACompetitionMode.Instance.Scores[tName]; tData.lastPersonWhoHitMe = aName; tData.lastHitTime = Planetarium.GetUniversalTime(); tData.everyoneWhoHitMe.Add(aName); // Track hits if (tData.hitCounts.ContainsKey(aName)) { ++tData.hitCounts[aName]; } else { tData.hitCounts.Add(aName, 1); } // Track damage if (tData.damageFromBullets.ContainsKey(aName)) { tData.damageFromBullets[aName] += explDamage; } else { tData.damageFromBullets.Add(aName, explDamage); } } } }
public static void DoExplosionRay(Ray ray, float power, float heat, float maxDistance, ref List <Part> ignoreParts, ref List <DestructibleBuilding> ignoreBldgs, Vessel sourceVessel = null) { RaycastHit rayHit; //KerbalEVA hitEVA = null; //if (Physics.Raycast(ray, out rayHit, maxDistance, 2228224)) //{ // float sqrDist = (rayHit.point - ray.origin).sqrMagnitude; // float sqrMaxDist = maxDistance * maxDistance; // float distanceFactor = Mathf.Clamp01((sqrMaxDist - sqrDist) / sqrMaxDist); // try // { // hitEVA = rayHit.collider.gameObject.GetComponentUpwards<KerbalEVA>(); // if (hitEVA != null) // Debug.Log("[BDArmory]:Hit on kerbal confirmed!"); // } // catch (System.NullReferenceException) // { // Debug.Log("[BDArmory]:Whoops ran amok of the exception handler"); // } // Part part = hitEVA.part; // Vessel missileSource = null; // if (sourceVessel != null) // { // MissileBase ml = part.FindModuleImplementing<MissileBase>(); // if (ml) // { // missileSource = ml.SourceVessel; // } // } // if (!ignoreParts.Contains(part) && part.physicalSignificance == Part.PhysicalSignificance.FULL && // (!sourceVessel || sourceVessel != missileSource)) // { // ignoreParts.Add(part); // Rigidbody rb = part.GetComponent<Rigidbody>(); // if (rb) // { // rb.AddForceAtPosition(ray.direction * power * distanceFactor * ExplosionImpulseMultiplier, // rayHit.point, ForceMode.Impulse); // } // if (heat < 0) // { // heat = power; // } // float heatDamage = (BDArmorySettings.DMG_MULTIPLIER / 100) * ExplosionHeatMultiplier * heat * // distanceFactor / part.crashTolerance; // float excessHeat = Mathf.Max(0, (float)(part.temperature + heatDamage - part.maxTemp)); // part.AddDamage(heatDamage); // if (BDArmorySettings.DRAW_DEBUG_LABELS) // Debug.Log("[BDArmory]:====== Explosion ray hit part! Damage: " + heatDamage); // if (excessHeat > 0 && part.parent) // { // part.parent.AddDamage(excessHeat); // } // return; // } //} if (Physics.Raycast(ray, out rayHit, maxDistance, 688129)) { float sqrDist = (rayHit.point - ray.origin).sqrMagnitude; float sqrMaxDist = maxDistance * maxDistance; float distanceFactor = Mathf.Clamp01((sqrMaxDist - sqrDist) / sqrMaxDist); //parts KerbalEVA eva = rayHit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); Part part = eva ? eva.part : rayHit.collider.GetComponentInParent <Part>(); if (part) { Vessel missileSource = null; if (sourceVessel != null) { MissileBase ml = part.FindModuleImplementing <MissileBase>(); if (ml) { missileSource = ml.SourceVessel; } } if (!ignoreParts.Contains(part) && part.physicalSignificance == Part.PhysicalSignificance.FULL && (!sourceVessel || sourceVessel != missileSource)) { ignoreParts.Add(part); Rigidbody rb = part.GetComponent <Rigidbody>(); if (rb) { rb.AddForceAtPosition(ray.direction * power * distanceFactor * ExplosionImpulseMultiplier, rayHit.point, ForceMode.Impulse); } if (heat < 0) { heat = power; } float heatDamage = (BDArmorySettings.DMG_MULTIPLIER / 100) * ExplosionHeatMultiplier * heat * distanceFactor / part.crashTolerance; float excessHeat = Mathf.Max(0, (float)(part.temperature + heatDamage - part.maxTemp)); part.AddDamage(heatDamage); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]:====== Explosion ray hit part! Damage: " + heatDamage); } if (excessHeat > 0 && part.parent) { part.parent.AddDamage(excessHeat); } return; } } //buildings DestructibleBuilding building = rayHit.collider.GetComponentInParent <DestructibleBuilding>(); if (building && !ignoreBldgs.Contains(building)) { ignoreBldgs.Add(building); float damageToBuilding = (BDArmorySettings.DMG_MULTIPLIER / 100) * ExplosionHeatMultiplier * 0.00645f * power * distanceFactor; if (damageToBuilding > building.impactMomentumThreshold / 10) { building.AddDamage(damageToBuilding); } if (building.Damage > building.impactMomentumThreshold) { building.Demolish(); } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]:== Explosion hit destructible building! Damage: " + (damageToBuilding).ToString("0.00") + ", total Damage: " + building.Damage); } } } }
void FixedUpdate() { float distanceFromStartSqr = (transform.position - startPosition).sqrMagnitude; if (!gameObject.activeInHierarchy) { return; } flightTimeElapsed += TimeWarp.fixedDeltaTime; //calculate flight time for drag purposes if (bulletDrop && FlightGlobals.RefFrameIsRotating) { currentVelocity += FlightGlobals.getGeeForceAtPosition(transform.position) * TimeWarp.fixedDeltaTime; } if (dragType == BulletDragTypes.NumericalIntegration) { Vector3 dragAcc = currentVelocity * currentVelocity.magnitude * (float) FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position), FlightGlobals.getExternalTemperature(transform.position)); dragAcc *= 0.5f; dragAcc /= ballisticCoefficient; currentVelocity -= dragAcc * TimeWarp.fixedDeltaTime; //numerical integration; using Euler is silly, but let's go with it anyway } if (tracerLength == 0) { bulletTrail.SetPosition(0, transform.position + (currentVelocity * tracerDeltaFactor * TimeWarp.fixedDeltaTime / TimeWarp.CurrentRate) - (FlightGlobals.ActiveVessel.Velocity() * TimeWarp.fixedDeltaTime)); } else { bulletTrail.SetPosition(0, transform.position + ((currentVelocity - sourceOriginalV).normalized * tracerLength)); } if (fadeColor) { FadeColor(); bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance); } bulletTrail.SetPosition(1, transform.position); currPosition = gameObject.transform.position; if (distanceFromStartSqr > maxDistance * maxDistance) { //GameObject.Destroy(gameObject); KillBullet(); return; } if (collisionEnabled) { float dist = initialSpeed * TimeWarp.fixedDeltaTime; Ray ray = new Ray(prevPosition, currPosition - prevPosition); RaycastHit hit; try { if (Physics.Raycast(ray, out hit, dist, 688129)) { bool penetrated = true; bool hitEva = false; Part hitPart = null; //determine when bullet collides with a target try { // Look for any Kerbal first. The part, KerbalEVA, is functionally similar to regular parts. KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); hitPart = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>(); hitEva = eva; } catch (NullReferenceException) { } // Need to make sure Kerbals don't get armor. BDArmor armor = hitEva ? null : BDArmor.GetArmor(hit.collider, hitPart); ArmorPenetration.BulletPenetrationData armorData = new ArmorPenetration.BulletPenetrationData(ray, hit); ArmorPenetration.DoPenetrationRay(armorData, bullet.positiveCoefficient); float penetration = bullet.penetration.Evaluate(Mathf.Sqrt(distanceFromStartSqr)) / 1000; bool fulllyPenetrated = penetration * leftPenetration > ((armor == null) ? 1f : armor.EquivalentThickness) * armorData.armorThickness; Vector3 finalDirect = Vector3.Lerp(ray.direction, -hit.normal, bullet.positiveCoefficient); if (fulllyPenetrated) { currentVelocity = finalDirect * currentVelocity.magnitude * leftPenetration; } else { currPosition = hit.point; bulletTrail.SetPosition(1, currPosition); } float hitAngle = Vector3.Angle(currentVelocity, -hit.normal); if (bulletType != PooledBulletTypes.Explosive) //dont do bullet damage if it is explosive { float impactVelocity = currentVelocity.magnitude; if (dragType == BulletDragTypes.AnalyticEstimate) { float analyticDragVelAdjustment = (float) FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(currPosition), FlightGlobals.getExternalTemperature(currPosition)); analyticDragVelAdjustment *= flightTimeElapsed * initialSpeed; analyticDragVelAdjustment += 2 * ballisticCoefficient; analyticDragVelAdjustment = 2 * ballisticCoefficient * initialSpeed / analyticDragVelAdjustment; //velocity as a function of time under the assumption of a projectile only acted upon by drag with a constant drag area analyticDragVelAdjustment = analyticDragVelAdjustment - initialSpeed; //since the above was velocity as a function of time, but we need a difference in drag, subtract the initial velocity //the above number should be negative... impactVelocity += analyticDragVelAdjustment; //so add it to the impact velocity if (impactVelocity < 0) { impactVelocity = 0; //clamp the velocity to > 0, since it could drop below 0 if the bullet is fired upwards } //Debug.Log("flight time: " + flightTimeElapsed + " BC: " + ballisticCoefficient + "\ninit speed: " + initialSpeed + " vel diff: " + analyticDragVelAdjustment); } //hitting a vessel Part ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////[panzer1b] HEAT BASED DAMAGE CODE START////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (hitPart != null) //see if it will ricochet of the part { penetrated = !RicochetOnPart(hitPart, hitAngle, impactVelocity); } else //see if it will ricochet off scenery { float reflectRandom = UnityEngine.Random.Range(-75f, 90f); if (reflectRandom > 90 - hitAngle) { penetrated = false; } } if (hitPart != null && !hitPart.partInfo.name.Contains("Strut")) //when a part is hit, execute damage code (ignores struts to keep those from being abused as armor)(no, because they caused weird bugs :) -BahamutoD) { float heatDamage = (mass / (hitPart.crashTolerance * hitPart.mass)) * impactVelocity * impactVelocity * BDArmorySettings.DMG_MULTIPLIER * bulletDmgMult ; //how much heat damage will be applied based on bullet mass, velocity, and part's impact tolerance and mass if (!penetrated) { heatDamage = heatDamage / 8; } if (fulllyPenetrated) { heatDamage /= 8; } if (BDArmorySettings.INSTAKILL) //instakill support, will be removed once mod becomes officially MP { heatDamage = (float)hitPart.maxTemp + 100; //make heat damage equal to the part's max temperture, effectively instakilling any part it hits } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Hit! damage applied: " + heatDamage); //debugging stuff } if (hitPart.vessel != sourceVessel) { hitPart.AddDamage(heatDamage); } float overKillHeatDamage = (float)(hitPart.temperature - hitPart.maxTemp); if (overKillHeatDamage > 0) //if the part is destroyed by overheating, we want to add the remaining heat to attached parts. This prevents using tiny parts as armor { overKillHeatDamage *= hitPart.crashTolerance; //reset to raw damage float numConnectedParts = hitPart.children.Count; if (hitPart.parent != null) { numConnectedParts++; overKillHeatDamage /= numConnectedParts; hitPart.parent.AddDamage(overKillHeatDamage / (hitPart.parent.crashTolerance * hitPart.parent.mass)); for (int i = 0; i < hitPart.children.Count; i++) { hitPart.children[i].AddDamage(overKillHeatDamage / hitPart.children[i].crashTolerance); } } else { overKillHeatDamage /= numConnectedParts; for (int i = 0; i < hitPart.children.Count; i++) { hitPart.children[i].AddDamage(overKillHeatDamage / hitPart.children[i].crashTolerance); } } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////[panzer1b] HEAT BASED DAMAGE CODE END//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //hitting a Building DestructibleBuilding hitBuilding = null; try { hitBuilding = hit.collider.gameObject.GetComponentUpwards <DestructibleBuilding>(); } catch (NullReferenceException) { } if (hitBuilding != null && hitBuilding.IsIntact) { float damageToBuilding = mass * initialSpeed * initialSpeed * BDArmorySettings.DMG_MULTIPLIER / 12000; if (!penetrated) { damageToBuilding = damageToBuilding / 8; } hitBuilding.AddDamage(damageToBuilding); if (hitBuilding.Damage > hitBuilding.impactMomentumThreshold) { hitBuilding.Demolish(); } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: bullet hit destructible building! Damage: " + (damageToBuilding).ToString("0.00") + ", total Damage: " + hitBuilding.Damage); } } } if (hitPart == null || (hitPart != null && hitPart.vessel != sourceVessel)) { if (!penetrated && !hasBounced && !fulllyPenetrated) { //ricochet hasBounced = true; if (BDArmorySettings.BULLET_HITS) { BulletHitFX.CreateBulletHit(hit.point, hit.normal, true); } tracerStartWidth /= 2; tracerEndWidth /= 2; transform.position = hit.point; currentVelocity = Vector3.Reflect(currentVelocity, hit.normal); currentVelocity = (hitAngle / 150) * currentVelocity * 0.65f; Vector3 randomDirection = UnityEngine.Random.rotation * Vector3.one; currentVelocity = Vector3.RotateTowards(currentVelocity, randomDirection, UnityEngine.Random.Range(0f, 5f) * Mathf.Deg2Rad, 0); } else { if (bulletType == PooledBulletTypes.Explosive) { ExplosionFX.CreateExplosion(hit.point - (ray.direction * 0.1f), radius, blastPower, blastHeat, sourceVessel, currentVelocity.normalized, explModelPath, explSoundPath); } else if (BDArmorySettings.BULLET_HITS) { BulletHitFX.CreateBulletHit(hit.point, hit.normal, false); } if (armor != null && (penetration * leftPenetration > armor.outerArmorThickness / 1000 * armor.EquivalentThickness || fulllyPenetrated)) { switch (armor.explodeMode) { case BDArmor.ExplodeMode.Always: armor.CreateExplosion(hitPart); break; case BDArmor.ExplodeMode.Dynamic: float probability = CalculateExplosionProbability(hitPart); if (probability > 0.1f) { armor.CreateExplosion(hitPart); } break; case BDArmor.ExplodeMode.Never: break; } } if (fulllyPenetrated) { leftPenetration -= armorData.armorThickness / penetration; transform.position = armorData.hitResultOut.point; flightTimeElapsed -= Time.fixedDeltaTime; prevPosition = transform.position; FixedUpdate(); return; } else { KillBullet(); return; } } } } } catch (NullReferenceException e) // Exception handling { Debug.Log("[BDArmory]: Ran afoul of exception filter\n" + e.StackTrace); } } if (bulletType == PooledBulletTypes.Explosive && airDetonation && distanceFromStartSqr > detonationRange * detonationRange) { //detonate ExplosionFX.CreateExplosion(transform.position, radius, blastPower, blastHeat, sourceVessel, currentVelocity.normalized, explModelPath, explSoundPath); //GameObject.Destroy(gameObject); //destroy bullet on collision KillBullet(); return; } prevPosition = currPosition; //move bullet transform.position += currentVelocity * Time.fixedDeltaTime; }
void Update() { if (!gameObject.activeInHierarchy || !HighLogic.LoadedSceneIsFlight || BDArmorySetup.GameIsPaused) { return; } transform.rotation = Quaternion.FromToRotation(Vector3.up, -FlightGlobals.getGeeForceAtPosition(transform.position)); fuel = parentPart.Resources.Where(pr => pr.resourceName == "LiquidFuel").FirstOrDefault(); if (disableTime < 0) //only have fire do it's stuff while burning and not during FX timeout { if (!surfaceFire) //is fire inside tank, or an incendiary substance on the part's surface? { if (!lookedForEngine) { engine = parentPart.FindModuleImplementing <ModuleEngines>(); lookedForEngine = true; //have this only called once, not once per update tick } if (engine != null) { if (engine.throttleLocked && !engine.allowShutdown) //likely a SRB { if (parentPart.RequestResource("SolidFuel", (double)(burnRate * TimeWarp.deltaTime)) <= 0) { hasFuel = false; } solid = parentPart.Resources.Where(pr => pr.resourceName == "SolidFuel").FirstOrDefault(); if (solid != null) { if (solid.amount < solid.maxAmount * 0.66f) { engine.Activate(); //SRB lights from unintended ignition source } if (solid.amount < solid.maxAmount * 0.15f) { tntMassEquivilent += Mathf.Clamp((float)solid.amount, ((float)solid.maxAmount * 0.05f), ((float)solid.maxAmount * 0.2f)); Detonate(); //casing's full of holes and SRB fuel's burnt to the point it can easily start venting through those holes } } } else { if (engine.EngineIgnited) { if (parentPart.RequestResource("LiquidFuel", (double)(burnRate * TimeWarp.deltaTime)) <= 0) { hasFuel = false; } } else { hasFuel = false; } } } else { if (fuel != null) { if (fuel.amount > (fuel.maxAmount * 0.15f) || (fuel.amount > 0 && fuel.amount < (fuel.maxAmount * 0.10f))) { fuel.amount -= (burnRate * Mathf.Clamp((float)((1 - (fuel.amount / fuel.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 4 * BDArmorySettings.BD_TANK_LEAK_RATE) * TimeWarp.deltaTime); burnScale = Mathf.Clamp((float)((1 - (fuel.amount / fuel.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 2 * BDArmorySettings.BD_TANK_LEAK_RATE); } else if (fuel.amount < (fuel.maxAmount * 0.15f) && fuel.amount > (fuel.maxAmount * 0.10f)) { Detonate(); } else { hasFuel = false; } } ox = parentPart.Resources.Where(pr => pr.resourceName == "Oxidizer").FirstOrDefault(); if (ox != null) { if (ox.amount > 0) { ox.amount -= (burnRate * Mathf.Clamp((float)((1 - (ox.amount / ox.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 4 * BDArmorySettings.BD_TANK_LEAK_RATE) * TimeWarp.deltaTime); } else { hasFuel = false; } } mp = parentPart.Resources.Where(pr => pr.resourceName == "MonoPropellant").FirstOrDefault(); if (mp != null) { if (mp.amount > (mp.maxAmount * 0.15f) || (mp.amount > 0 && mp.amount < (mp.maxAmount * 0.10f))) { mp.amount -= (burnRate * Mathf.Clamp((float)((1 - (mp.amount / mp.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 4 * BDArmorySettings.BD_TANK_LEAK_RATE) * TimeWarp.deltaTime); if (burnScale < 0) { burnScale = Mathf.Clamp((float)((1 - (mp.amount / mp.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 2 * BDArmorySettings.BD_TANK_LEAK_RATE); } } else if (mp.amount < (mp.maxAmount * 0.15f) && mp.amount > (mp.maxAmount * 0.10f)) { Detonate(); } else { hasFuel = false; } } ec = parentPart.Resources.Where(pr => pr.resourceName == "ElectricCharge").FirstOrDefault(); if (ec != null) { if (ec.amount > 0) { ec.amount -= (burnRate * TimeWarp.deltaTime); Mathf.Clamp((float)ec.amount, 0, Mathf.Infinity); if (burnScale < 0) { burnScale = 1; } } if ((Time.time - startTime > 30) && engine == null) { Detonate(); } } } } if (BDArmorySettings.BD_FIRE_HEATDMG) { if (parentPart.temperature < 1300) { if (fuel != null) { parentPart.temperature += burnRate * Mathf.Clamp((float)((1 - (fuel.amount / fuel.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 4 * BDArmorySettings.BD_TANK_LEAK_RATE) * Time.deltaTime; } else if (mp != null) { parentPart.temperature += burnRate * Mathf.Clamp((float)((1 - (mp.amount / mp.maxAmount)) * 4), 0.1f * BDArmorySettings.BD_TANK_LEAK_RATE, 4 * BDArmorySettings.BD_TANK_LEAK_RATE) * Time.deltaTime; } else if (ec != null || ox != null) { parentPart.temperature += burnRate * BDArmorySettings.BD_FIRE_DAMAGE * Time.deltaTime; } } } if (BDArmorySettings.BATTLEDAMAGE && BDArmorySettings.BD_FIRE_DOT) { if (BDArmorySettings.BD_FIRE_HEATDMG) { if (parentPart.temperature > 1000) { parentPart.AddDamage(BDArmorySettings.BD_FIRE_DAMAGE * Time.deltaTime); } } else { parentPart.AddDamage(BDArmorySettings.BD_FIRE_DAMAGE * Time.deltaTime); } //////////////////////////////////////////////// ScoreAccumulator = 0; var aName = SourceVessel; var tName = parentPart.vessel.GetName(); if (aName != null && tName != null && aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(aName) && BDACompetitionMode.Instance.Scores.ContainsKey(tName)) { if (BDArmorySettings.REMOTE_LOGGING_ENABLED) { BDAScoreService.Instance.TrackDamage(aName, tName, BDArmorySettings.BD_FIRE_DAMAGE); } // Track damage. Moving this here to properly track damage per tick var tData = BDACompetitionMode.Instance.Scores[tName]; if (tData.damageFromBullets.ContainsKey(aName)) { tData.damageFromBullets[aName] += BDArmorySettings.BD_FIRE_DAMAGE; } else { tData.damageFromBullets.Add(aName, BDArmorySettings.BD_FIRE_DAMAGE); } if (ScoreAccumulator >= 1) //could be reduced, gaining +1 hit per sec, per fire seems high { var aData = BDACompetitionMode.Instance.Scores[aName]; aData.Score += 1; if (parentPart.vessel.GetName() == "Pinata") { aData.PinataHits++; } tData.lastPersonWhoHitMe = aName; tData.lastHitTime = Planetarium.GetUniversalTime(); tData.everyoneWhoHitMe.Add(aName); // Track hits if (tData.hitCounts.ContainsKey(aName)) { ++tData.hitCounts[aName]; } else { tData.hitCounts.Add(aName, 1); } } } else { ScoreAccumulator += 1 * Time.deltaTime; } } } if ((!hasFuel && disableTime < 0 && burnTime < 0) || (burnTime > 0 && disableTime < 0 && Time.time - startTime > burnTime)) { disableTime = Time.time; //grab time when emission stops foreach (var pe in pEmitters) { if (pe != null) { pe.emit = false; } } } else { foreach (var pe in pEmitters) { pe.maxSize = burnScale; pe.minSize = burnScale * 1.2f; } } if (disableTime > 0 && Time.time - disableTime > _highestEnergy) //wait until last emitted particle has finished { gameObject.SetActive(false); } if (engine != null && enginerestartTime > 0 && Time.time - 10 > enginerestartTime) { engine.Activate(); enginerestartTime = -1; } //////////////////////////////////////////// }