first commit, even though I've been "done" with the mod for like ever
This commit is contained in:
85
Buffs/Parasitism.cs
Normal file
85
Buffs/Parasitism.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using Siva.Projectiles;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Siva.Buffs
|
||||||
|
{
|
||||||
|
public class Parasitism : ModBuff
|
||||||
|
{
|
||||||
|
public static readonly int BuffType = ModContent.BuffType<Parasitism>();
|
||||||
|
|
||||||
|
public override void SetStaticDefaults()
|
||||||
|
{
|
||||||
|
Main.debuff[Type] = true; // Indicates this is a negative effect.
|
||||||
|
Main.buffNoSave[Type] = true; // Indicates that the buff won't save when exiting the game.
|
||||||
|
Main.buffNoTimeDisplay[Type] = false; // Shows the duration on the buff icon.
|
||||||
|
}
|
||||||
|
|
||||||
|
// What happens while the debuff is a applied
|
||||||
|
public override void Update(NPC npc, ref int buffIndex)
|
||||||
|
{
|
||||||
|
// Do I make them glow red or anything?
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int AttachedNaniteCount(NPC npc)
|
||||||
|
{
|
||||||
|
int attachedNanites = 0;
|
||||||
|
foreach (var p in Main.ActiveProjectiles)
|
||||||
|
{
|
||||||
|
if (p.type == SIVANanite.ProjectileType && p.ai[0] == 1f && p.ai[1] == npc.whoAmI) {
|
||||||
|
attachedNanites++;
|
||||||
|
// Main.NewText($"{attachedNanites}"); // Debug text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attachedNanites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetParasitismScaleFactor(int attachedNanites)
|
||||||
|
{
|
||||||
|
if(attachedNanites <= 5)
|
||||||
|
{
|
||||||
|
return attachedNanites*0.3f;
|
||||||
|
}
|
||||||
|
else if(attachedNanites > 5 && attachedNanites < 100)
|
||||||
|
{
|
||||||
|
return (attachedNanites-5)*0.021f+1.5f;
|
||||||
|
}
|
||||||
|
else if(attachedNanites >= 100)
|
||||||
|
{
|
||||||
|
return 3.5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ParasitismScaling : GlobalNPC
|
||||||
|
{
|
||||||
|
public override bool InstancePerEntity => true;
|
||||||
|
|
||||||
|
public override void ModifyHitByProjectile(NPC npc, Projectile projectile, ref NPC.HitModifiers modifiers)
|
||||||
|
{
|
||||||
|
if(LogicPerfected.ParasitismOnTarget(npc) && projectile.owner == Main.myPlayer) // Check to make sure the projectile is the local players rather than any other projectils from any other gun. Trying to prevent hypothetical exploits.
|
||||||
|
{
|
||||||
|
if(LogicPerfected.NormBullet(projectile))
|
||||||
|
{
|
||||||
|
float scaleFactor = GetParasitismScaleFactor(AttachedNaniteCount(npc));
|
||||||
|
AddableFloat addableScaleFactor = AddableFloat.Zero + scaleFactor;
|
||||||
|
modifiers.ScalingBonusDamage = addableScaleFactor;
|
||||||
|
Main.NewText($"norm {scaleFactor}"); // debug text
|
||||||
|
}
|
||||||
|
else if(LogicPerfected.MasterBulletOrNanite(projectile))
|
||||||
|
{
|
||||||
|
float scaleFactor = GetParasitismScaleFactor(AttachedNaniteCount(npc));
|
||||||
|
AddableFloat addableScaleFactor = AddableFloat.Zero + scaleFactor;
|
||||||
|
modifiers.ScalingBonusDamage = addableScaleFactor;
|
||||||
|
Main.NewText($"master {scaleFactor}"); // debug text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BIN
Buffs/Parasitism.png
Normal file
BIN
Buffs/Parasitism.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
19
Items/OutbreakCatalyst.cs
Normal file
19
Items/OutbreakCatalyst.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Terraria;
|
||||||
|
using Terraria.ID;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
|
||||||
|
namespace Siva.Items
|
||||||
|
{
|
||||||
|
public class OutbreakCatalyst : ModItem
|
||||||
|
{
|
||||||
|
public override void SetDefaults()
|
||||||
|
{
|
||||||
|
Item.height = 24;
|
||||||
|
Item.width = 24;
|
||||||
|
Item.buyPrice(platinum: 5);
|
||||||
|
Item.sellPrice(0);
|
||||||
|
Item.maxStack = 1;
|
||||||
|
Item.rare = ItemRarityID.Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Items/OutbreakCatalyst.png
Normal file
BIN
Items/OutbreakCatalyst.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
46
Localization/en-US_Mods.Siva.hjson
Normal file
46
Localization/en-US_Mods.Siva.hjson
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
Buffs: {
|
||||||
|
Parasitism: {
|
||||||
|
DisplayName: Parasitism
|
||||||
|
Description: SIVA Nanites are attached to you!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Items: {
|
||||||
|
Outbreak: {
|
||||||
|
DisplayName: Outbreak Perfected
|
||||||
|
Tooltip:
|
||||||
|
'''
|
||||||
|
Critical kills with this weapon have a chance to drop it's Catalyst.
|
||||||
|
Combine this weapon with it's Catalyst at a Mythril/Orichalcum anvil in order to Masterwork it which will unlock new perks and slight stat bonuses.
|
||||||
|
Rapid hits and critical kills with this weapon will create SIVA nanites swarms.
|
||||||
|
SIVA nanites seek out and damage targets.
|
||||||
|
This weapon's damage increases against targets based on the number of SIVA nanites that are attached to them.
|
||||||
|
[c/FF0000:~directive = KILL while enemies = PRESENT: execute(directive)~]
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
|
||||||
|
OutbreakCatalyst: {
|
||||||
|
DisplayName: Outbreak Catalyst
|
||||||
|
Tooltip:
|
||||||
|
'''
|
||||||
|
Combine with Outbreak Perfected at an anvil to Masterwork it.
|
||||||
|
*Be glad I didn't make you get another 700 kills on top of what it already took*
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
|
||||||
|
MasterworkedOutbreak: {
|
||||||
|
DisplayName: Outbreak Perfected
|
||||||
|
Tooltip:
|
||||||
|
'''
|
||||||
|
[c/FFF014:Masterworked]
|
||||||
|
[c/FFF014:Increased nanite damage.]
|
||||||
|
[c/FFF014:Enemies that die with nanites attached to them generate additional nanites.]
|
||||||
|
Rapid hits and critical kills with this weapon will create SIVA nanites swarms.
|
||||||
|
SIVA nanites seek out and damage targets.
|
||||||
|
This weapon's damage increases against targets based on the number of SIVA nanites that are attached to them.
|
||||||
|
[c/FF0000:~directive = KILL while enemies = PRESENT: execute(directive)~]
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Projectiles.SIVANanite.DisplayName: SIVA Nanite
|
||||||
212
Projectiles/SIVANanite.cs
Normal file
212
Projectiles/SIVANanite.cs
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Siva.Buffs;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.DataStructures;
|
||||||
|
using Terraria.ID;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Siva.Projectiles
|
||||||
|
{
|
||||||
|
// This Example show how to implement simple homing projectile
|
||||||
|
public class SIVANanite : ModProjectile
|
||||||
|
{
|
||||||
|
public static Texture2D glowMaskTexture;
|
||||||
|
public static readonly int ProjectileType = ModContent.ProjectileType<SIVANanite>();
|
||||||
|
|
||||||
|
// These properties wrap the usual ai arrays for cleaner and easier to understand code.
|
||||||
|
// Are we sticking to a target?
|
||||||
|
public bool IsStickingToTarget {
|
||||||
|
get => Projectile.ai[0] == 1f;
|
||||||
|
set => Projectile.ai[0] = value ? 1f : 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index of the current target
|
||||||
|
public int TargetWhoAmI {
|
||||||
|
get => (int)Projectile.ai[1];
|
||||||
|
set => Projectile.ai[1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float TimeAttached {
|
||||||
|
get => Projectile.localAI[0];
|
||||||
|
set => Projectile.localAI[0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Damage
|
||||||
|
{
|
||||||
|
get => Projectile.localAI[1];
|
||||||
|
set => Projectile.localAI[1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetStaticDefaults() {
|
||||||
|
ProjectileID.Sets.CultistIsResistantTo[Projectile.type] = true; // Make the cultist resistant to this projectile, as it's resistant to all homing projectiles.
|
||||||
|
Main.projFrames[Projectile.type] = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting the default parameters of the projectile
|
||||||
|
// You can check most of Fields and Properties here https://github.com/tModLoader/tModLoader/wiki/Projectile-Class-Documentation
|
||||||
|
public override void SetDefaults() {
|
||||||
|
|
||||||
|
Projectile.width = 16; // The width of projectile hitbox
|
||||||
|
Projectile.height = 16; // The height of projectile hitbox
|
||||||
|
Projectile.scale = .8f;
|
||||||
|
Projectile.aiStyle = 0; // The ai style of the projectile (0 means custom AI). For more please reference the source code of Terraria
|
||||||
|
Projectile.DamageType = DamageClass.Ranged; // What type of damage does this projectile affect?
|
||||||
|
Projectile.friendly = true; // Can the projectile deal damage to enemies?
|
||||||
|
Projectile.hostile = false; // Can the projectile deal damage to the player?
|
||||||
|
Projectile.ignoreWater = true; // Does the projectile's speed be influenced by water?
|
||||||
|
Projectile.tileCollide = false; // Can the projectile collide with tiles?
|
||||||
|
Projectile.timeLeft = 180; // The live time for the projectile (60 = 1 second, so 420 is 7 seconds)
|
||||||
|
Projectile.penetrate = -1;
|
||||||
|
Projectile.CritChance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostDraw(Color lightColor)
|
||||||
|
{
|
||||||
|
Texture2D NaniteGlow = new Texture2D()
|
||||||
|
Main.EntitySpriteDraw()
|
||||||
|
base.PostDraw(lightColor);
|
||||||
|
}
|
||||||
|
public override void AI()
|
||||||
|
{
|
||||||
|
Projectile.ai[2] += 1f;
|
||||||
|
if (++Projectile.frameCounter >= 5) {
|
||||||
|
Projectile.frameCounter = 0;
|
||||||
|
// Or more compactly Projectile.frame = ++Projectile.frame % Main.projFrames[Projectile.type];
|
||||||
|
if (++Projectile.frame >= Main.projFrames[Projectile.type])
|
||||||
|
Projectile.frame = 0;
|
||||||
|
}
|
||||||
|
Lighting.AddLight(Projectile.position, Color.Red.ToVector3() * 0.7f);
|
||||||
|
// Run either the Sticky AI or Normal AI
|
||||||
|
// Separating into different methods helps keeps your AI clean
|
||||||
|
// Main.NewText($"IsStickingToTarget = {IsStickingToTarget}"); //
|
||||||
|
if (IsStickingToTarget)
|
||||||
|
{
|
||||||
|
// Main.NewText("Calling StickyAI()"); // debug text
|
||||||
|
StickyAI();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NormalAI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NormalAI()
|
||||||
|
{
|
||||||
|
float maxDetectRadius = 400f; // The maximum radius at which a projectile can detect a target
|
||||||
|
float projSpeed = 7f; // The speed at which the projectile moves towards the target
|
||||||
|
Projectile.damage = (int)Damage; // Sets the damage of the projectile to the damage it was created with.
|
||||||
|
// Trying to find NPC closest to the projectile
|
||||||
|
NPC closestNPC = FindClosestNPC(maxDetectRadius);
|
||||||
|
if (closestNPC != null)
|
||||||
|
{
|
||||||
|
// If a target is found, change the velocity of the projectile and rotate it in the direction of the target
|
||||||
|
Projectile.velocity = (closestNPC.Center - Projectile.Center).SafeNormalize(Vector2.Zero) * projSpeed;
|
||||||
|
Projectile.rotation = Projectile.velocity.ToRotation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Projectile.velocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int MaxTimeAttached = 540;
|
||||||
|
public void StickyAI()
|
||||||
|
{
|
||||||
|
TimeAttached += 1f;
|
||||||
|
// Main.NewText($"TimeAttached: {TimeAttached}"); // debug text
|
||||||
|
int npcTarget = TargetWhoAmI;
|
||||||
|
if (TimeAttached >= MaxTimeAttached) { // If the nanite has stuck for 9 seconds (or more)
|
||||||
|
Projectile.Kill();
|
||||||
|
}
|
||||||
|
else if (Main.npc[npcTarget].active && !Main.npc[npcTarget].dontTakeDamage) {
|
||||||
|
// If the target is active and can take damage
|
||||||
|
// Set the projectile's position relative to the target's center
|
||||||
|
Projectile.Center = Main.npc[npcTarget].Center - Projectile.velocity * 2f;
|
||||||
|
Projectile.gfxOffY = Main.npc[npcTarget].gfxOffY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Projectile.Kill();
|
||||||
|
}
|
||||||
|
/* Very fun but a bit OP
|
||||||
|
else { // Otherwise, reset the timer to 3 seconds and unstick it
|
||||||
|
Projectile.timeLeft = 180;
|
||||||
|
IsStickingToTarget = false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public NPC FindClosestNPC(float maxDetectDistance)
|
||||||
|
{
|
||||||
|
NPC closestNPC = null;
|
||||||
|
float sqrMaxDetectDistance = maxDetectDistance * maxDetectDistance;
|
||||||
|
|
||||||
|
foreach (NPC target in Main.npc)
|
||||||
|
{
|
||||||
|
if (target.CanBeChasedBy())
|
||||||
|
{
|
||||||
|
float sqrDistanceToTarget = Vector2.DistanceSquared(target.Center, Projectile.Center);
|
||||||
|
if (sqrDistanceToTarget < sqrMaxDetectDistance)
|
||||||
|
{
|
||||||
|
sqrMaxDetectDistance = sqrDistanceToTarget;
|
||||||
|
closestNPC = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closestNPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnSpawn(IEntitySource source)
|
||||||
|
{
|
||||||
|
Damage = Projectile.damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int maxNanites = 100;
|
||||||
|
private readonly Point[] attachedNanites = new Point[maxNanites];
|
||||||
|
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
|
||||||
|
{
|
||||||
|
// Main.NewText($"{damageDone}"); // debug text
|
||||||
|
IsStickingToTarget = true; // we are sticking to a target
|
||||||
|
Projectile.damage = 0; // Makes sure it can't deal damage, this is reset when NormalAI() is called again.
|
||||||
|
TargetWhoAmI = target.whoAmI; // Set the target whoAmI
|
||||||
|
Projectile.velocity = (target.Center - Projectile.Center) * 0.75f; // Change velocity based on delta center of targets (difference between entity centers)
|
||||||
|
Projectile.netUpdate = true; // netUpdate this javelin
|
||||||
|
int na = 0;
|
||||||
|
foreach (var p in Main.ActiveProjectiles) // Refreses the duration of all of the nanites on the npc.
|
||||||
|
{
|
||||||
|
if (p.type == ProjectileType && p.ai[0] == 1f && p.ai[1] == TargetWhoAmI)
|
||||||
|
{
|
||||||
|
// Main.NewText("Refreshing duration of nanite"); // debug text
|
||||||
|
p.timeLeft = 540;
|
||||||
|
na++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Main.NewText(na); // debug text
|
||||||
|
// ExampleJavelinBuff handles the damage over time (DoT)
|
||||||
|
target.AddBuff(Parasitism.BuffType, 540);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Create(int naniteCount, NPC target, int projDamage)
|
||||||
|
{
|
||||||
|
// Main.NewText($"naniteCount = {naniteCount}"); //debug text
|
||||||
|
int i = 0;
|
||||||
|
while(i < naniteCount) // I'm proud of this basic function, draws the amount of nanites in a parabola above the target
|
||||||
|
{
|
||||||
|
float k = naniteCount/2;
|
||||||
|
// Main.NewText($"k = {k}"); //debug text
|
||||||
|
int x = (i - ((int)Math.Floor(k)))*4;
|
||||||
|
float y = 1.0f / 6.0f * x * x;
|
||||||
|
y -= target.height;
|
||||||
|
x *= 4;
|
||||||
|
y *= 2;
|
||||||
|
Projectile.NewProjectile(target.GetSource_FromThis(), Vector2.Add(target.Center, new Vector2(x, y)), Vector2.Zero, ProjectileType, projDamage, 0f, Main.myPlayer); // Might want to use Target.Top and make it not as high above them, big bosses have nanites spawn on them I think
|
||||||
|
// Main.NewText($"({x},{y})"); //debug text
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
// Main.NewText($"made {i} nanites off of {naniteCount}"); //debug text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Projectiles/SIVANanite.png
Normal file
BIN
Projectiles/SIVANanite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Projectiles/SIVANanite_Glow.png
Normal file
BIN
Projectiles/SIVANanite_Glow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 921 B |
16
Properties/launchSettings.json
Normal file
16
Properties/launchSettings.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Terraria": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(DotNetName)",
|
||||||
|
"commandLineArgs": "$(tMLPath)",
|
||||||
|
"workingDirectory": "$(tMLSteamPath)"
|
||||||
|
},
|
||||||
|
"TerrariaServer": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "$(DotNetName)",
|
||||||
|
"commandLineArgs": "$(tMLServerPath)",
|
||||||
|
"workingDirectory": "$(tMLSteamPath)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Siva.csproj
Normal file
10
Siva.csproj
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\tModLoader.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>Siva</AssemblyName>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
25
Siva.sln
Normal file
25
Siva.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.002.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Siva", "Siva.csproj", "{94357A29-B3C2-4A40-A301-4C495F984AA8}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{94357A29-B3C2-4A40-A301-4C495F984AA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{94357A29-B3C2-4A40-A301-4C495F984AA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{94357A29-B3C2-4A40-A301-4C495F984AA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{94357A29-B3C2-4A40-A301-4C495F984AA8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {13B26FFE-7FBA-4AD1-8598-C8797B82D8C1}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
BIN
Sounds/Pew.wav
Normal file
BIN
Sounds/Pew.wav
Normal file
Binary file not shown.
69
Weapons/MasterworkedOutbreak.cs
Normal file
69
Weapons/MasterworkedOutbreak.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Siva.Items;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.Audio;
|
||||||
|
using Terraria.ID;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
|
||||||
|
namespace Siva.Weapons
|
||||||
|
{
|
||||||
|
public class MasterworkedOutbreak : ModItem
|
||||||
|
{
|
||||||
|
public static readonly int ItemType = ModContent.ItemType<MasterworkedOutbreak>();
|
||||||
|
|
||||||
|
public override void SetDefaults()
|
||||||
|
{
|
||||||
|
// Modders can use Item.DefaultToRangedWeapon to quickly set many common properties, such as: useTime, useAnimation, useStyle, autoReuse, DamageType, shoot, shootSpeed, useAmmo, and noMelee. These are all shown individually here for teaching purposes.
|
||||||
|
|
||||||
|
// Common Properties
|
||||||
|
Item.width = 22; // Hitbox width of the item.
|
||||||
|
Item.height = 10; // Hitbox height of the item.
|
||||||
|
Item.scale = 0.75f;
|
||||||
|
Item.rare = ItemRarityID.Yellow; // The color that the item's name will be in-game.
|
||||||
|
|
||||||
|
|
||||||
|
// Use Properties
|
||||||
|
Item.useTime = 4; // one third of useAnimation for three burst effect I think
|
||||||
|
Item.useAnimation = 12; // The length of the item's use animation in ticks
|
||||||
|
Item.reuseDelay = 12; // The delay before you can shoot again, crazy I know
|
||||||
|
Item.useStyle = ItemUseStyleID.Shoot; // How you use the item (swinging, holding out, etc.)
|
||||||
|
Item.autoReuse = true; // Whether or not you can hold click to automatically use it again
|
||||||
|
|
||||||
|
// Weapon Properties
|
||||||
|
Item.consumeAmmoOnLastShotOnly = true;
|
||||||
|
Item.DamageType = DamageClass.Ranged; // Sets the damage type to ranged.
|
||||||
|
Item.damage = 22; // Sets the item's damage. Note that projectiles shot by this weapon will use its and the used ammunition's damage added together.
|
||||||
|
Item.knockBack = 5f; // Sets the item's knockback. Note that projectiles shot by this weapon will use its and the used ammunition's knockback added together.
|
||||||
|
Item.noMelee = true; // So the item's animation doesn't do damage.
|
||||||
|
Item.crit = 34; // Sets the item's crit chance. Note that the player's base crit chance is 4% and will be added to the item's crit chance.
|
||||||
|
|
||||||
|
// Gun Properties
|
||||||
|
Item.shoot = ProjectileID.PurificationPowder; // For some reason, all the guns in the vanilla source have this.
|
||||||
|
Item.shootSpeed = 20f; // The speed of the projectile (measured in pixels per frame.)
|
||||||
|
Item.useAmmo = AmmoID.Bullet; // The "ammo Id" of the ammo item that this weapon uses. Ammo IDs are magic numbers that usually correspond to the item id of one item that most commonly represent the ammo type.
|
||||||
|
|
||||||
|
// The sound that this item plays when used.
|
||||||
|
Item.UseSound = new SoundStyle($"{nameof(Siva)}/Sounds/Pew") {
|
||||||
|
Volume = 1f,
|
||||||
|
PitchVariance = 0,
|
||||||
|
MaxInstances = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method lets you adjust position of the gun in the player's hands. Play with these values until it looks good with your graphics.
|
||||||
|
public override Vector2? HoldoutOffset() {
|
||||||
|
return new Vector2(2f, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddRecipes()
|
||||||
|
{
|
||||||
|
CreateRecipe()
|
||||||
|
.AddIngredient<Outbreak>()
|
||||||
|
.AddIngredient<OutbreakCatalyst>()
|
||||||
|
.AddTile(TileID.MythrilAnvil)
|
||||||
|
.Register();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Weapons/MasterworkedOutbreak.png
Normal file
BIN
Weapons/MasterworkedOutbreak.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
115
Weapons/Outbreak.cs
Normal file
115
Weapons/Outbreak.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Terraria;
|
||||||
|
using Terraria.Audio;
|
||||||
|
using Terraria.ID;
|
||||||
|
using Terraria.ModLoader;
|
||||||
|
using Siva.Items;
|
||||||
|
|
||||||
|
namespace Siva.Weapons
|
||||||
|
{
|
||||||
|
public class Outbreak : ModItem
|
||||||
|
{
|
||||||
|
public static readonly int ItemType = ModContent.ItemType<Outbreak>();
|
||||||
|
|
||||||
|
public override void SetDefaults()
|
||||||
|
{
|
||||||
|
// Modders can use Item.DefaultToRangedWeapon to quickly set many common properties, such as: useTime, useAnimation, useStyle, autoReuse, DamageType, shoot, shootSpeed, useAmmo, and noMelee. These are all shown individually here for teaching purposes.
|
||||||
|
|
||||||
|
// Common Properties
|
||||||
|
Item.width = 22; // Hitbox width of the item.
|
||||||
|
Item.height = 10; // Hitbox height of the item.
|
||||||
|
Item.scale = 0.75f;
|
||||||
|
Item.rare = ItemRarityID.Red; // The color that the item's name will be in-game.
|
||||||
|
|
||||||
|
|
||||||
|
// Use Properties
|
||||||
|
Item.useTime = 4; // one third of useAnimation for three burst effect I think
|
||||||
|
Item.useAnimation = 12; // The length of the item's use animation in ticks
|
||||||
|
Item.reuseDelay = 12; // The delay before you can shoot again, crazy I know
|
||||||
|
Item.useStyle = ItemUseStyleID.Shoot; // How you use the item (swinging, holding out, etc.)
|
||||||
|
Item.autoReuse = true; // Whether or not you can hold click to automatically use it again
|
||||||
|
|
||||||
|
// Weapon Properties
|
||||||
|
Item.consumeAmmoOnLastShotOnly = true;
|
||||||
|
Item.DamageType = DamageClass.Ranged; // Sets the damage type to ranged.
|
||||||
|
Item.damage = 22; // Sets the item's damage. Note that projectiles shot by this weapon will use its and the used ammunition's damage added together.
|
||||||
|
Item.knockBack = 3f; // Sets the item's knockback. Note that projectiles shot by this weapon will use its and the used ammunition's knockback added together.
|
||||||
|
Item.noMelee = true; // So the item's animation doesn't do damage.
|
||||||
|
Item.crit = 29; // Sets the item's crit chance. Note that the player's base crit chance is 4% and will be added to the item's crit chance.
|
||||||
|
|
||||||
|
// Gun Properties
|
||||||
|
Item.shoot = ProjectileID.PurificationPowder; // For some reason, all the guns in the vanilla source have this.
|
||||||
|
Item.shootSpeed = 20f; // The speed of the projectile (measured in pixels per frame.)
|
||||||
|
Item.useAmmo = AmmoID.Bullet; // The "ammo Id" of the ammo item that this weapon uses. Ammo IDs are magic numbers that usually correspond to the item id of one item that most commonly represent the ammo type.
|
||||||
|
|
||||||
|
// The sound that this item plays when used.
|
||||||
|
Item.UseSound = new SoundStyle($"{nameof(Siva)}/Sounds/Pew") {
|
||||||
|
Volume = 1f,
|
||||||
|
PitchVariance = 0,
|
||||||
|
MaxInstances = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method lets you adjust position of the gun in the player's hands. Play with these values until it looks good with your graphics.
|
||||||
|
public override Vector2? HoldoutOffset() {
|
||||||
|
return new Vector2(2f, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CatalystDropChance : GlobalNPC
|
||||||
|
{
|
||||||
|
private static readonly Random Random = new Random();
|
||||||
|
public override void OnHitByProjectile(NPC npc, Projectile projectile, NPC.HitInfo hit, int damageDone)
|
||||||
|
{
|
||||||
|
Player player = Main.player[projectile.owner];
|
||||||
|
if(!player.HasItemInAnyInventory(ModContent.ItemType<OutbreakCatalyst>()) && player.HeldItem.type == Outbreak.ItemType && projectile.aiStyle == 1 && hit.Crit && npc.life <= 0 && !npc.SpawnedFromStatue && npc.lifeMax > 5)
|
||||||
|
{
|
||||||
|
int randomNumber = Random.Next(350);
|
||||||
|
|
||||||
|
// Main.NewText($"Rolled Catty drop chance, randint is {randomNumber}"); // debug text
|
||||||
|
if(randomNumber == 77)
|
||||||
|
{
|
||||||
|
player.QuickSpawnItem(player.GetSource_FromThis(), ModContent.ItemType<OutbreakCatalyst>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Old nanite creation method.
|
||||||
|
/*
|
||||||
|
public class NaniteCreation : GlobalProjectile // Creates 1-3 Nanites on critical hits
|
||||||
|
{
|
||||||
|
// Alters the base behavior of what happens when a projectile hits an NPC
|
||||||
|
public override void OnHitNPC(Projectile projectile, NPC target, NPC.HitInfo hit, int damage)
|
||||||
|
{
|
||||||
|
// Accessing the player who shot the projectile
|
||||||
|
Player player = Main.player[projectile.owner];
|
||||||
|
// Checks to make sure the player is holding MasterworkedOutbreak and the projectile was not a SIVA Nanite so they don't spawn more nanites.
|
||||||
|
if (player.HeldItem.type == ModContent.ItemType<MasterworkedOutbreak>() & projectile.type != ModContent.ProjectileType<SIVANanite>())
|
||||||
|
{
|
||||||
|
if(hit.Crit) // On critical hits
|
||||||
|
{
|
||||||
|
int randomNumber = new Random().Next(101); // Random number 0-10
|
||||||
|
if (randomNumber <= 60) // 60% chance to make a nanite
|
||||||
|
{
|
||||||
|
SIVANanite.Create(1, projectile, target, damage/2);
|
||||||
|
}
|
||||||
|
else if (60 < randomNumber & randomNumber <= 90) // 30% chance to make a nanite twice
|
||||||
|
{
|
||||||
|
SIVANanite.Create(2, projectile, target, damage/2);
|
||||||
|
}
|
||||||
|
else if (90 < randomNumber & randomNumber <= 100) // 10% chance to make a nanite thrice
|
||||||
|
{
|
||||||
|
SIVANanite.Create(3, projectile, target, damage/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
BIN
Weapons/Outbreak.png
Normal file
BIN
Weapons/Outbreak.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
3
build.txt
Normal file
3
build.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
displayName = Outbreak Perfected
|
||||||
|
author = ForeverPyrite
|
||||||
|
version = 0.9.8
|
||||||
7
description.txt
Normal file
7
description.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
This mod introduces Outbreak Perfected, the iconic pulse rifle from the Destiny francise, into Terraria.
|
||||||
|
|
||||||
|
This mod includes:
|
||||||
|
- Outbreak Perfected (Obtainable by defeating Moss Hornets in the Jungle, might change this, but I was inspired by the Uzi or something...)
|
||||||
|
- Outbreak Perfected Catalyst (Rarely found from getting Critical Kills. Since it's already rare I didn't add an extra 700 kills to match Destiny lol)
|
||||||
|
|
||||||
|
This one is very accurate to the game, yeah. Not much to say. Just adds the one weapon.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||||
22
obj/Debug/net8.0/Siva.AssemblyInfo.cs
Normal file
22
obj/Debug/net8.0/Siva.AssemblyInfo.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("Siva")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("Siva")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("Siva")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
1
obj/Debug/net8.0/Siva.AssemblyInfoInputs.cache
Normal file
1
obj/Debug/net8.0/Siva.AssemblyInfoInputs.cache
Normal file
@@ -0,0 +1 @@
|
|||||||
|
47b2cfa54c9c9d42493b9726e8ede67436d64078f36f1068b1efa251fb950172
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.TargetFramework = net8.0
|
||||||
|
build_property.TargetPlatformMinVersion =
|
||||||
|
build_property.UsingMicrosoftNETSdkWeb =
|
||||||
|
build_property.ProjectTypeGuids =
|
||||||
|
build_property.InvariantGlobalization =
|
||||||
|
build_property.PlatformNeutralAssembly =
|
||||||
|
build_property.EnforceExtendedAnalyzerRules =
|
||||||
|
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||||
|
build_property.RootNamespace = Siva
|
||||||
|
build_property.ProjectDir = C:\Users\ForeverPyrite\Documents\My Games\Terraria\tModLoader\ModSources\Siva\
|
||||||
|
build_property.EnableComHosting =
|
||||||
|
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||||
|
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||||
|
build_property.EnableCodeStyleSeverity =
|
||||||
BIN
obj/Debug/net8.0/Siva.assets.cache
Normal file
BIN
obj/Debug/net8.0/Siva.assets.cache
Normal file
Binary file not shown.
BIN
obj/Debug/net8.0/Siva.csproj.AssemblyReference.cache
Normal file
BIN
obj/Debug/net8.0/Siva.csproj.AssemblyReference.cache
Normal file
Binary file not shown.
87
obj/Siva.csproj.nuget.dgspec.json
Normal file
87
obj/Siva.csproj.nuget.dgspec.json
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj",
|
||||||
|
"projectName": "Siva",
|
||||||
|
"projectPath": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\ForeverPyrite\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\ForeverPyrite\\AppData\\Roaming\\NuGet\\NuGet.Config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"https://api.nuget.org/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "9.0.200"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"tModLoader.CodeAssist": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[0.1.*, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"downloadDependencies": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
obj/Siva.csproj.nuget.g.props
Normal file
18
obj/Siva.csproj.nuget.g.props
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\ForeverPyrite\.nuget\packages\</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="C:\Users\ForeverPyrite\.nuget\packages\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<PkgtModLoader_CodeAssist Condition=" '$(PkgtModLoader_CodeAssist)' == '' ">C:\Users\ForeverPyrite\.nuget\packages\tmodloader.codeassist\0.1.5</PkgtModLoader_CodeAssist>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
2
obj/Siva.csproj.nuget.g.targets
Normal file
2
obj/Siva.csproj.nuget.g.targets
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||||
115
obj/project.assets.json
Normal file
115
obj/project.assets.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
"net8.0": {
|
||||||
|
"tModLoader.CodeAssist/0.1.5": {
|
||||||
|
"type": "package"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"tModLoader.CodeAssist/0.1.5": {
|
||||||
|
"sha512": "Sg/jKEg/z5eN+Cdi3/9CU4JfJwvXHVH+UDJf4Lipo26uTa+guLLJXH1XDJNPShTFwKK8jMUYbthINP4QhsgHSA==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "tmodloader.codeassist/0.1.5",
|
||||||
|
"hasTools": true,
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"NugetIcon.png",
|
||||||
|
"analyzers/dotnet/cs/tModLoader.CodeAssist.dll",
|
||||||
|
"tmodloader.codeassist.0.1.5.nupkg.sha512",
|
||||||
|
"tmodloader.codeassist.nuspec",
|
||||||
|
"tools/install.ps1",
|
||||||
|
"tools/uninstall.ps1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectFileDependencyGroups": {
|
||||||
|
"net8.0": [
|
||||||
|
"tModLoader.CodeAssist >= 0.1.*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"packageFolders": {
|
||||||
|
"C:\\Users\\ForeverPyrite\\.nuget\\packages\\": {}
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj",
|
||||||
|
"projectName": "Siva",
|
||||||
|
"projectPath": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj",
|
||||||
|
"packagesPath": "C:\\Users\\ForeverPyrite\\.nuget\\packages\\",
|
||||||
|
"outputPath": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\obj\\",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"configFilePaths": [
|
||||||
|
"C:\\Users\\ForeverPyrite\\AppData\\Roaming\\NuGet\\NuGet.Config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net8.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"https://api.nuget.org/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"restoreAuditProperties": {
|
||||||
|
"enableAudit": "true",
|
||||||
|
"auditLevel": "low",
|
||||||
|
"auditMode": "direct"
|
||||||
|
},
|
||||||
|
"SdkAnalysisLevel": "9.0.200"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net8.0": {
|
||||||
|
"targetAlias": "net8.0",
|
||||||
|
"dependencies": {
|
||||||
|
"tModLoader.CodeAssist": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[0.1.*, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48",
|
||||||
|
"net481"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"downloadDependencies": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||||
|
"version": "[8.0.13, 8.0.13]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.200/PortableRuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
obj/project.nuget.cache
Normal file
13
obj/project.nuget.cache
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "xoCv9EvyOl0=",
|
||||||
|
"success": true,
|
||||||
|
"projectFilePath": "C:\\Users\\ForeverPyrite\\Documents\\My Games\\Terraria\\tModLoader\\ModSources\\Siva\\Siva.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"C:\\Users\\ForeverPyrite\\.nuget\\packages\\tmodloader.codeassist\\0.1.5\\tmodloader.codeassist.0.1.5.nupkg.sha512",
|
||||||
|
"C:\\Users\\ForeverPyrite\\.nuget\\packages\\microsoft.netcore.app.ref\\8.0.13\\microsoft.netcore.app.ref.8.0.13.nupkg.sha512",
|
||||||
|
"C:\\Users\\ForeverPyrite\\.nuget\\packages\\microsoft.windowsdesktop.app.ref\\8.0.13\\microsoft.windowsdesktop.app.ref.8.0.13.nupkg.sha512",
|
||||||
|
"C:\\Users\\ForeverPyrite\\.nuget\\packages\\microsoft.aspnetcore.app.ref\\8.0.13\\microsoft.aspnetcore.app.ref.8.0.13.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": []
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user