first commit, even though I've been "done" with the mod for like ever
This commit is contained in:
261
Siva.cs
Normal file
261
Siva.cs
Normal file
@@ -0,0 +1,261 @@
|
||||
using System;
|
||||
using System.Timers;
|
||||
using System.Collections.Generic;
|
||||
using MonoMod.RuntimeDetour;
|
||||
using Terraria;
|
||||
using Terraria.ModLoader;
|
||||
using Terraria.GameContent.ItemDropRules;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader.Default;
|
||||
using Terraria.ModLoader.UI;
|
||||
using Terraria.DataStructures;
|
||||
using Siva;
|
||||
using Siva.Weapons;
|
||||
using Siva.Buffs;
|
||||
using Siva.Projectiles;
|
||||
|
||||
|
||||
|
||||
|
||||
// only thing that really needs to be active mod wide is the drop chance and reduced crit, so here it is
|
||||
namespace Siva
|
||||
{
|
||||
public class Siva : Mod
|
||||
{
|
||||
public class ReducedCritMulti : GlobalNPC // Modifies the crit multiplier on NPCs so it doesn't do insane damage with it's high crit chance
|
||||
{
|
||||
|
||||
// Alters the base behavior of what happens when an NPC is hit by a projectile.
|
||||
public override void ModifyHitByProjectile(NPC npc, Projectile projectile, ref NPC.HitModifiers modifiers)
|
||||
{
|
||||
if(LogicPerfected.HeldIsNorm() && LogicPerfected.Bullet(projectile))
|
||||
{
|
||||
modifiers.CritDamage = new(1.6f, 1f); // Modifies Outbreak's bullets crit damage to 60% to match in game
|
||||
}
|
||||
else if(LogicPerfected.HeldIsMaster() && LogicPerfected.Bullet(projectile))
|
||||
{
|
||||
modifiers.CritDamage = new(1.55f, 1f); // Modifies Outbreak's bullets crit damage to 55% as a little terraria bonus
|
||||
}
|
||||
}
|
||||
}
|
||||
public class OutbreakDrop : GlobalNPC
|
||||
{
|
||||
public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot)
|
||||
{
|
||||
if (npc.type == NPCID.MossHornet)
|
||||
{
|
||||
|
||||
npcLoot.Add(new ConditionalNormalvsExpertDropRule(Outbreak.ItemType, 350, 250, new Conditions.DownedAllMechBosses()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public class LogicPerfected // I got so fed up with typing the same long ass hard to read conditionals, so I made this class.
|
||||
{
|
||||
public static bool HeldIsNorm()
|
||||
{
|
||||
return Main.LocalPlayer.HeldItem.type == Outbreak.ItemType;
|
||||
}
|
||||
public static bool HeldIsMaster()
|
||||
{
|
||||
return Main.LocalPlayer.HeldItem.type == MasterworkedOutbreak.ItemType;
|
||||
}
|
||||
public static bool Bullet(Projectile projectile) // Really it just checks that it's a projectile that acts like a bullet while you are holding Outbreak, best way I could find to do it :/. This means hypothetically someone can shoot bullets from any other gun then quickswap. Probably not useful but I'll see..
|
||||
{
|
||||
return projectile.aiStyle == 1;
|
||||
}
|
||||
public static bool Nanite(Projectile projectile)
|
||||
{
|
||||
return projectile.type == SIVANanite.ProjectileType;
|
||||
}
|
||||
public static bool NormBullet(Projectile projectile)
|
||||
{
|
||||
return HeldIsNorm() && Bullet(projectile);
|
||||
}
|
||||
public static bool MasterBulletOrNanite(Projectile projectile)
|
||||
{
|
||||
return HeldIsMaster() && (Bullet(projectile) || Nanite(projectile));
|
||||
}
|
||||
public static bool ParasitismOnTarget(NPC npc)
|
||||
{
|
||||
return npc.FindBuffIndex(Parasitism.BuffType) != -1; // FindBuffIndex returns -1 if the buff isn't found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// none of the base game drops have a condition for the state of the game you are in and also have different chances based on expert vs master
|
||||
public class ConditionalNormalvsExpertDropRule : IItemDropRule
|
||||
{
|
||||
private int itemId;
|
||||
private int normalModeChance;
|
||||
private int expertModeChance;
|
||||
private IItemDropRuleCondition condition;
|
||||
|
||||
public ConditionalNormalvsExpertDropRule(int itemId, int normalModeChance, int expertModeChance, IItemDropRuleCondition condition)
|
||||
{
|
||||
this.itemId = itemId;
|
||||
this.normalModeChance = normalModeChance;
|
||||
this.expertModeChance = expertModeChance;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public bool CanDrop(DropAttemptInfo info)
|
||||
{
|
||||
return condition.CanDrop(info);
|
||||
}
|
||||
|
||||
public ItemDropAttemptResult TryDroppingItem(DropAttemptInfo info)
|
||||
{
|
||||
ItemDropAttemptResult result = new ItemDropAttemptResult();
|
||||
if (CanDrop(info))
|
||||
{
|
||||
int chance = info.IsExpertMode ? expertModeChance : normalModeChance;
|
||||
if (info.player.RollLuck(chance) == 0)
|
||||
{
|
||||
CommonCode.DropItem(info, itemId, 1, true);
|
||||
result.State = ItemDropAttemptResultState.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.State = ItemDropAttemptResultState.FailedRandomRoll;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.State = ItemDropAttemptResultState.DoesntFillConditions;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ReportDroprates(List<DropRateInfo> drops, DropRateInfoChainFeed ratesInfo)
|
||||
{
|
||||
DropRateInfoChainFeed ratesInfo2 = ratesInfo.With(1f);
|
||||
ratesInfo2.AddCondition(condition);
|
||||
float chance = ratesInfo2.parentDroprateChance != 0 && ratesInfo2.parentDroprateChance != 1f ? ratesInfo2.parentDroprateChance : (ratesInfo2.parentDroprateChance == 1f ? expertModeChance : normalModeChance);
|
||||
float dropRate = 1f / chance * ratesInfo2.parentDroprateChance;
|
||||
drops.Add(new DropRateInfo(itemId, 1, 1, dropRate, ratesInfo2.conditions));
|
||||
}
|
||||
|
||||
public List<IItemDropRuleChainAttempt> ChainedRules => new List<IItemDropRuleChainAttempt>();
|
||||
}
|
||||
|
||||
|
||||
// A timer to make sure the nanite hits are consecutive
|
||||
public class RapidHitTimer
|
||||
{
|
||||
private Timer hitTimer;
|
||||
|
||||
public RapidHitTimer()
|
||||
{
|
||||
hitTimer = new Timer
|
||||
{
|
||||
AutoReset = false,
|
||||
};
|
||||
hitTimer.Elapsed += NaniteCreation.ResetHits;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
hitTimer.Interval = 2000;
|
||||
hitTimer.Enabled = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
hitTimer.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Nanite creation about to go crazy
|
||||
I used to have one class in each of them that was copied and pasted, and I think it might still make more sense to put them in there
|
||||
Deriving them off of each other isn't too important, I just wanted to try more programming things.
|
||||
I also just wanted it to be a lot more readable, hence all the extra functions like OutbreakBullet and OutbreakNanite, as well as overriding OutbreakBullet instead of making a new class just to try it.
|
||||
*/
|
||||
|
||||
public class NaniteCreation : GlobalProjectile // Creates Nanites on sustained fire and critical kills.
|
||||
{
|
||||
|
||||
// Alters the base behavior of what happens when a projectile hits an NPC
|
||||
protected static int outbreakHits = 0;
|
||||
|
||||
protected static RapidHitTimer hitTimer = new RapidHitTimer();
|
||||
protected static void ResetHits()
|
||||
{
|
||||
outbreakHits = 0;
|
||||
hitTimer.Stop();
|
||||
}
|
||||
public static void ResetHits(Object ph, ElapsedEventArgs ph2) // Have to cater to Timer.Elapsed so I made an overload for it
|
||||
{
|
||||
outbreakHits = 0;
|
||||
hitTimer.Stop();
|
||||
}
|
||||
|
||||
|
||||
public override void OnHitNPC(Projectile projectile, NPC target, NPC.HitInfo hit, int damage)
|
||||
{
|
||||
// Checks to make sure the player is holding Outbreak and the projectile was a bullet, as well as making sure that the life of the target is more than 5 (ie not magic or a critter).
|
||||
if (LogicPerfected.NormBullet(projectile) && target.lifeMax > 5)
|
||||
{
|
||||
outbreakHits++;
|
||||
hitTimer.Start();
|
||||
// Main.NewText($"{outbreakHits}"); //debug text
|
||||
if(outbreakHits >= 12)
|
||||
{
|
||||
int naniteCount = new Random().Next(2, 5); // It's just how ranges work in this function, I didn't make it, go yell at Microsoft
|
||||
SIVANanite.Create(naniteCount, target, (int)(hit.SourceDamage*2.21));
|
||||
ResetHits();
|
||||
}
|
||||
if(hit.Crit & target.life <= 0) // On critical kills make 9 nanites
|
||||
{
|
||||
// Main.NewText("Critical Kill!"); // debug text
|
||||
SIVANanite.Create(9, target, (int)(hit.SourceDamage*1.38));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class MasterworkedNaniteCreation : NaniteCreation
|
||||
{
|
||||
private new static int outbreakHits = 0;
|
||||
|
||||
public override void OnHitNPC(Projectile projectile, NPC target, NPC.HitInfo hit, int damage)
|
||||
{
|
||||
|
||||
|
||||
|
||||
// Checks to make sure the player is holding MasterworkedOutbreak, and that the targets max life is more than 5 (ie. not magic/critters), as well as making sure the projectile is either a bullet or a siva nanite.
|
||||
if (LogicPerfected.MasterBulletOrNanite(projectile) && target.lifeMax > 5)
|
||||
{
|
||||
// Checks to make sure that it was a bullet and not a nanite or anything
|
||||
if(LogicPerfected.Bullet(projectile))
|
||||
{
|
||||
outbreakHits++;
|
||||
hitTimer.Start();
|
||||
if(outbreakHits >= 12)
|
||||
{
|
||||
int naniteCount = new Random().Next(2, 5); // It's just how ranges work in this function, I didn't make it, go yell at Microsoft
|
||||
SIVANanite.Create(naniteCount, target, (int)(hit.SourceDamage*2.21));
|
||||
outbreakHits = 0;
|
||||
ResetHits();
|
||||
}
|
||||
|
||||
}
|
||||
if(target.life <= 0) // On kill
|
||||
{
|
||||
if(target.FindBuffIndex(Parasitism.BuffType) != -1) // If parasitism is in the buff list of the target
|
||||
{
|
||||
SIVANanite.Create(4, target, (int)(damage*0.6)); // It's actually 15% (46.8 vs 7) of the normal ones in game according to the Destiny Data Compendium spreedsheets and I forgot to check it myself. Maybe it was pvp or something. Idk. But they also scale damage so that might be why.
|
||||
}
|
||||
|
||||
if(hit.Crit) // If the final blow was a crit
|
||||
{
|
||||
SIVANanite.Create(9, target, (int)(hit.SourceDamage*1.38));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user